Read the sections below to learn how to create search reports in the Search Ads
360 Reporting API.

## Search service

The Search Ads 360 Reporting API provides a special service for searching and
reporting.

[`SearchAds360Service`](https://developers.google.com/search-ads/reporting/api/reference/rpc/google.ads.searchads360.v0.services#searchads360service)
is a unified object retrieval and reporting service that provides two search
methods: *`SearchStream`* and *`Search`* . Searches are passed in a query string
written in the [Search Ads 360 Query Language](https://developers.google.com/search-ads/reporting/query/query-language). You can
define queries to:

- Retrieve specific attributes of objects.
- Retrieve performance metrics for objects based on a date range.
- Order objects based on their attributes.
- Filter your results using conditions that specify which objects to return
- Limit the number of objects returned.

Both search methods return all rows that match your query. For example, when you
retrieve `campaign.id`, `campaign.name`, and `metrics.clicks`, the API returns a
[`SearchAds360Row`](https://developers.google.com/search-ads/reporting/api/reference/rpc/google.ads.searchads360.v0.services#searchads360row)
containing a campaign object with its `id` and `name` fields set, and a
`metrics` object with its `clicks` field set.

## Search methods

`SearchStream`

:   Sends a single request and initiates a persistent connection with the Search
    Ads 360 Reporting API regardless of report size.

    - Data packets start downloading immediately with the entire result cached in a data buffer.
    - Your code can start reading the buffered data without having to wait for the entire stream to finish.

`Search`

:   Sends multiple paginated requests to download the entire report.

`SearchStream` typically offers better performance because it eliminates the
round-trip network time required to request individual pages. We recommend using
`SearchStream` for all reports of more than 10,000 rows. There is no significant
performance difference between the methods for smaller reports (\<10,000 rows).

The method you use does not affect your API
[quotas and limits](https://cloud.google.com/api-gateway/docs/quotas): a single
query or report is counted as one operation regardless of whether the results
are paged or streamed.

## Example search query

This example query returns performance data for an account for the last 30 days
by campaign, segmented by device:

    SELECT
      campaign.name,
      campaign.status,
      segments.device,
      metrics.impressions,
      metrics.clicks,
      metrics.ctr,
      metrics.average_cpc,
      metrics.cost_micros
    FROM campaign
    WHERE segments.date DURING LAST_30_DAYS

> [!NOTE]
> **Note:** [Search Ads 360 Query Language](https://developers.google.com/search-ads/reporting/query/query-language) provides detailed information about how to use each clause of the search query.

## Make a request

To issue a request, you need to pass a `customer_id` and a `query` string to the
[`SearchAds360Service.SearchStream`](https://developers.google.com/search-ads/reporting/api/reference/rpc/google.ads.searchads360.v0.services#searchads360service)
or
[`SearchAds360Service.Search`](https://developers.google.com/search-ads/reporting/api/reference/rpc/google.ads.searchads360.v0.services#searchads360service)
interface.

> [!NOTE]
> **Note:** The examples below shows the underlying HTTP/JSON request. This is used to demonstrate the concepts. We recommend that you use our [client libraries](https://developers.google.com/search-ads/reporting/client-libraries/client-libraries) that are based on [gRPC](https://grpc.io/) to submit requests in your own app.

The request consists of an HTTP `POST` to the Search Ads 360 Reporting API
server at either of the following URLs:

```
https://searchads360.googleapis.com/VERSION_NUMBER/customers/CUSTOMER_ID/searchads360:searchStream
```

```
https://searchads360.googleapis.com/VERSION_NUMBER/customers/CUSTOMER_ID/searchads360:search
```

Here's a complete example of the report definition to `searchStream` enclosed in
an HTTP `POST` request:

```
POST /VERSION_NUMBER/customers/CUSTOMER_ID/searchads360:searchStream HTTP/1.1
Host: searchads360.googleapis.com
User-Agent: curl
Content-Type: application/json
Accept: application/json
Authorization: Bearer [OAUTH_2.0_ACCESS_TOKEN]

Parameters:
{
  "query" : "SELECT campaign.name, campaign.status, segments.device,
                    metrics.impressions, metrics.clicks, metrics.ctr,
                    metrics.average_cpc, metrics.cost_micros
            FROM campaign
            WHERE segments.date DURING LAST_30_DAYS"
}
```

## Process a response

[`SearchAds360Service`](https://developers.google.com/search-ads/reporting/api/reference/rpc/google.ads.searchads360.v0.services#searchads360service)
returns a list of
[`SearchAds360Row`](https://developers.google.com/search-ads/reporting/api/reference/rpc/google.ads.searchads360.v0.services#searchads360row)
objects.

Each `SearchAds360Row` represents an object returned by the query. Each object
consists of a set of attributes that are populated based on the fields requested
in the `SELECT` clause of the query. Attributes not included in the `SELECT`
clause are not populated in the objects in the response.

For example, the query below populates each `SearchAds360Row` object with only
the `campaign.id`, `campaign.name`, and `campaign.status`. Other attributes,
like `campaign.engine_id` or `campaign.bidding_strategy_type`, are omitted.

    SELECT
      campaign.id,
      campaign.name,
      campaign.status
    FROM campaign

## Reference documentation

The [Reference](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/overview) section includes all the information you
need to correctly use each artifact. There is one page for each resource, for
example [`ad_group`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/ad_group) and [`campaign`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/campaign).
The [`segments`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/segments) and [`metrics`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/metrics) pages
list all available segments and metrics fields.

Some resources, segments, and metrics are incompatible and cannot be used
together, while others are fully compatible and compliment each other. Each
resource page includes the following information (if available and appropriate)
and more:

Attributed resources

:   For some resources, you may have the option to implicitly join related
    resources by selecting their fields together with the fields of the resource
    in your `FROM` clause. For example, the [`campaign`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/campaign)
    resource is an attributed resource of the [`ad_group`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/ad_group)
    resource. This means that you can include fields like `campaign.id` and
    `campaign.bidding_strategy_type` in your query when using `ad_group` in your
    `FROM` clause.

    The **Attributed resources** section lists available attributed resources.
    Not all resources have attributed resources.

Resource fields column

:   All fields of the resource are included in the **Resource fields** column.
    Each resource field links to more details about the field, including its
    description, category, data type, type URL, and filterable, selectable,
    sortable, and repeated setting.

Segments column

:   Not all segment fields are selectable with a given resource.

    The **Segments** column lists the `segments` fields that you can use in the
    same `SELECT` clause as the fields of the resource. Each field links to full
    details about the field, including its description, category, data type,
    type URL, and filterable, selectable, sortable, and repeated setting. If you
    are using the resource in your `FROM` clause, you can use the **Yes/No**
    dropdown to filter out segments that are not available.

Metrics column

:   Not all metrics fields are selectable with a given resource.

    The **Metrics** column lists the `metrics` fields that you can use in the
    same `SELECT` clause as the fields of the resource. Each field links to full
    details about the field, including its description, category, data type,
    type URL, and filterable, selectable, sortable, and repeated setting. If you
    are using the resource in your `FROM` clause, use the **Yes/No** dropdown to
    filter out metrics that are not available.

> [!NOTE]
> **Note:** When getting currency related metrics (e.g. cost_micros) for a specific date or a date range, be sure to include segments.date in the SELECT clause.

Segmenting resources

:   Some resources have segmenting resource fields that you can select when the
    resource is in your `FROM` clause. For example, if you select a
    [`campaign`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/campaign) resource field, like
    [`campaign.name`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/campaign#campaign.name), when using
    [`campaign_budget`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/campaign#campaign.campaign_budget) in your
    `FROM` clause,
    [`campaign.resource_name`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/campaign#campaign.resource_name) will
    automatically be returned and segmented on, because `campaign` is a
    segmenting resource of
    [`campaign_budget`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/campaign#campaign.campaign_budget).

    The **Segmenting resources** section lists available segmenting resources.
    Not all resources have segmenting resources.

Selectable with

:   Some `segments` fields are incompatible with other resources, segments, and
    metrics.

    The [`segments`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/segments) page includes a **Selectable with**
    expandable for each `segments` field that lists all compatible resource
    fields, `metrics` fields, and other `segments` fields that you can include
    in your `SELECT` clause.

> [!NOTE]
> **Note:** See [Search Ads 360 Query Language](https://developers.google.com/search-ads/reporting/concepts/query-language) to learn how to use each clause of a query.

## Segmentation

You can segment your search results by adding a
`segments.FIELD_NAME` field to the [`SELECT` clause](https://developers.google.com/search-ads/reporting/concepts/query-language#select_clause) of your query.

For example, [`segments.device`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/segments#segments.device) in the
query below, results in a report with a row for the `impressions` of each device
for the resource specified in the
[`FROM` clause](https://developers.google.com/search-ads/reporting/concepts/query-language#from_clause).

    SELECT
      campaign.name,
      campaign.status,
      segments.device,
      metrics.impressions
    FROM campaign

The results returned by
[`SearchAds360Service.SearchStream`](https://developers.google.com/search-ads/reporting/api/reference/rpc/google.ads.searchads360.v0.services#searchads360service)
look something like this JSON string:

    {
      "results":[
        {
          "campaign":{
            "resourceName":"customers/1234567890/campaigns/111111111",
            "name":"Test campaign",
            "status":"ENABLED"
          },
          "metrics":{
            "impressions":"10922"
          },
          "segments":{
            "device":"MOBILE"
          }
        },
        {
          "campaign":{
            "resourceName":"customers/1234567890/campaigns/111111111",
            "name":"Test campaign",
            "status":"ENABLED"
          },
          "metrics":{
            "impressions":"28297"
          },
          "segments":{
            "device":"DESKTOP"
          }
        },
        ...
      ]
    }

See [`segments`](https://developers.google.com/search-ads/reporting/api/reference/fields/v0/segments) for a list of available segment fields you
can use.

### Multiple segments

> [!CAUTION]
> **Caution:** The number of rows can increase exponentially for each additional `segments` field you add to your query.

You can specify multiple segments in the `SELECT` clause of your query. The
response contains one `SearchAds360Row` object for each **combination** of the
**instance** of the main resource specified in the `FROM` clause and the
**value** of each selected `segment` field.

For example, the following query will return one row for each combination of
`campaign`, `segments.ad_network_type`, and `segments.date`.

    SELECT
      segments.ad_network_type
      segments.date
    FROM campaign

Note that results are implicitly segmented by each **instance** of the main
resource, but not by the values of the individual selected fields.

The following example query results in one row per campaign, not one row per
distinct value of the `campaign.status` field.

    SELECT
      campaign.status,
      metrics.impressions
    FROM campaign
    WHERE segments.date DURING LAST_14_DAYS

### Implicit segmentation

Every report is initially segmented by the resource specified in the `FROM`
clause. Metrics are segmented by the `resource_name` field of this resource

> [!NOTE]
> **Note:** The `resource_name` field of the resource in the `FROM` clause is always returned, even when it is not specified in the `SELECT` clause. See [`resource_name` field](https://developers.google.com/search-ads/reporting/concepts/query-language#resource_name_field) for more information.

This example query automatically returns `ad_group.resource_name` and implicitly
uses it to segment metrics at the `ad_group` level.

    SELECT metrics.impressions
    FROM ad_group

The returned JSON string looks similar to this:

    {
      "results":[
        {
          "adGroup":{
            "resourceName":"customers/1234567890/adGroups/2222222222"
          },
          "metrics":{
            "impressions":"237"
          }
        },
        {
          "adGroup":{
            "resourceName":"customers/1234567890/adGroups/33333333333"
          },
          "metrics":{
            "impressions":"15"
          }
        },
        {
          "adGroup":{
            "resourceName":"customers/1234567890/adGroups/44444444444"
          },
          "metrics":{
            "impressions":"0"
          }
        }
      ]
    }

### Core date segments

You can use core date segments in your
[`WHERE` clause](https://developers.google.com/search-ads/reporting/concepts/query-language#where_clause) to specify a date or
time period.

The following segments fields are known as *core date segments* :
`segments.date`, `segments.week`, `segments.month`, `segments.quarter`, and
`segments.year`.

This example query returns campaign `clicks` metrics for the last 30 days.

    SELECT
      campaign.id,
      campaign.name,
      segments.date,
      metrics.clicks
    FROM campaign
    WHERE segments.date DURING LAST_30_DAYS

Core date segments fields are an **exception** to the general rule that you
cannot use a segments field in your `WHERE` clause, unless you also include the
field in your `SELECT` clause. See
[Prohibited filtering](https://developers.google.com/search-ads/reporting/concepts/query-language#prohibited_filtering) for more
information.

Core date segment rules:

- You may use a core date field in your `WHERE` clause without including it in
  your `SELECT` clause. *You may also include the field in both clauses if you
  like.*

  This example query returns `clicks` metrics by campaign name during the date
  range. Note that `segments.date` is not included in the `SELECT` clause.

      SELECT
          campaign.name,
          metrics.clicks
      FROM campaign
      WHERE segments.date > '2022-02-01'
        AND segments.date < '2022-03-01'

- If you include a core date field in your `SELECT` clause, you must specify a
  finite date or date range in your `WHERE` clause. *The fields specified in
  the `SELECT` and `WHERE` clauses do not need to match.*

  This example query returns `clicks` metrics by campaign name segmented by
  month for all days in the date range.

      SELECT
        campaign.name,
        metrics.clicks,
        segments.month
      FROM campaign
      WHERE segments.date > '2022-02-01'
        AND segments.date < '2022-03-01'

#### ISO 8601 dates

You can use the `YYYY-MM-DD` (ISO 8601) format to specify dates and date ranges,
for example:

    WHERE segments.date BETWEEN '2022-06-01' AND '2022-06-30'

    WHERE segments.date >= '2022-06-01' AND segments.date <= '2022-06-30'

For core date segments that require a time period (`segments.week`,
`segments.month`, `segments.quarter`) you can use the `=` operator with the
first day of the time period, for example:

    WHERE segments.month = '2022-06-01'

> [!NOTE]
> **Note:** If you specify a date that is not the first day of a period, you will receive a `MISALIGNED_DATE_FOR_FILTER` error.

#### Predefined dates

You can also use the following predefined dates and date ranges:

| Predefined dates ||
|---|---|
| `TODAY` | Today only. |
| `YESTERDAY` | Yesterday only. |
| `LAST_7_DAYS` | Previous 7 days not including today. |
| `LAST_BUSINESS_WEEK` | Previous 5-day business week (Monday to Friday). |
| `THIS_MONTH` | All days in the current month. |
| `LAST_MONTH` | All days in the previous month. |
| `LAST_14_DAYS` | Previous 14 days excluding today. |
| `LAST_30_DAYS` | Previous 30 days excluding today. |
| `THIS_WEEK_SUN_TODAY` | Period between the previous Sunday and the current day. |
| `THIS_WEEK_MON_TODAY` | Period between the previous Monday and the current day. |
| `LAST_WEEK_SUN_SAT` | 7-day period starting from the previous Sunday. |
| `LAST_WEEK_MON_SUN` | 7-day period starting from the previous Monday. |

Example:

    WHERE segments.date DURING LAST_30_DAYS

## Zero metrics

When you execute a query, you may encounter metrics with a value of zero for
some entities.
[Learn about how to handle zero metrics in your queries](https://developers.google.com/search-ads/reporting/query/zero-metrics).

## UNKNOWN enum types

If a resource is returned with the `UNKNOWN` enum data type, this means that the
type is not fully supported in the API version. These resources may have been
created through other interfaces. For example, a new campaign or ad is
introduced in the Search Ads 360 UI, but is not yet supported in the API version
you are querying.

You can still select metrics when a resource has the type `UNKNOWN`, but you
need to keep the following in mind:

- A resource with an `UNKNOWN` type may be supported later, but it could
  remain `UNKNOWN` indefinitely.

- New objects with type `UNKNOWN` may appear at any time. These objects are
  backwards compatible because the enum value is already available. We
  introduce resources with this change as they are available so that you have
  an accurate view of your account. The `UNKNOWN` resource may appear because
  of new activity in your account through other interfaces or because a
  resource becomes no longer formally supported.

- `UNKNOWN` resources may have detailed metrics attached to them that you can
  query.

- `UNKNOWN` resources are typically fully visible in the Search Ads 360 UI.