Google Ads

Zero Impression and Structure Reports  |  AdWords API

In addition to retrieving performance statistics, AdWords API developers often
use the reporting system to get structural information about accounts.

This guide goes over how to interpret and manage
zero impression stats in reports
as well as how to use them in
constructing an account structure.

Zero impression stats in reports

In your reports, you may encounter zero impression stats for
entities that have not been viewed. This could be for various reasons:
the entities are ineligible to display, or they could
have been paused during the report’s date range.

These zero impressions are of little use when calculating performance,
but are needed to download the full contents of the account.

Zero impression reports are used to discover entity structures in an
account or to quickly synchronize a local database without having to make
a series of expensive get() calls to
the API. By including zero impressions in results, you can discover the
structure of any account entity in a single call.

Including and excluding zero impressions

Zero impression data can be returned in all of the normal performance reports,
so you should always explicitly include or exclude
zero impressions according to your use case. This removes any ambiguity
from your requests and allows the API to provide a meaningful error if
your request contains an invalid combination of report fields and zero
impressions behavior.

When to include zero impressions

Zero impressions are useful in exposing entity structures in an account in
a single call.
The alternative is making numerous API requests which may trigger
rate limits.

For example, querying the Keyword Performance
Id and Criteria while excluding zero impressions may only retrieve
minimal results; but by including zero
impressions and adding fields such as CampaignId and AdGroupId,
it’s possible to process and build a structure of the
currently known keywords.

When to exclude zero impressions

Zero impressions are useful for discovering entity structures but should
typically be excluded from performance reporting. You may want to exclude
zero impressions to reduce response size or to focus
only on meaningful performance statistics for a given date range.
This is especially beneficial if there are many paused campaigns in a
given report, as zero impressions can unnecessarily inflate the result set.

Including zero impressions

To include zero impressions in your report output, set the
includeZeroImpressions HTTP header to true.

When set to true, reports will not exclude any rows based on metric
values, and will include those with zero impressions.

Excluding zero impressions

There are two ways to explicity exclude zero impressions from reports:

  • Set the includeZeroImpressions HTTP header to false.
  • Use a predicate.

The simplest way to exclude zero impressions is to set the
includeZeroImpressions HTTP header to false.

When set to false, reports will return only rows where at least one of
the requested Metric fields has a non-zero value.

Excluding zero impressions with a predicate

You can exclude zero impressions by adding a predicate for the
Impressions field with an operator of GREATER_THAN and a value of 0.

The XML for this predicate looks like this


and the AWQL statement like this

WHERE Impressions > 0

Implicitly excluding zero impressions

Zero impression rows are implicitly excluded when a report request
contains any field that doesn’t support zero impressions. You can see the zero impressions
behavior for each field in the
Supports Zero Impressions attribute of the
Report Types pages.

However, it’s best not to rely on implicit exclusions,
since adding or removing one field from your request could change your
report’s behavior.

Structure reports

Using the API services to collect comprehensive data on your account can
require a large number of requests, especially as your account grows.

Google Ads reporting provides an easier way to get
basic structural information for your account and its related entities:
you can use reports to quickly return data—including
object IDs, names, and values—to reproduce the basic skeleton of your
account. From there, you can identify elements you want to know more about,
and use their object IDs to retrieve details from the API.

The Report Types documentation indicates
which column entries can be retrieved for each account object. These column
titles can also be obtained programmatically using the
method of the ReportDefinitionService.
By carefully selecting report columns, you can obtain enough information
to build the structure of your account.

Retrieving ad group criteria

Since Google Ads accounts can have a large number of ad group criteria, issuing
get or query requests against
is inefficient compared to retrieving the same criteria via the

To use the CRITERIA_PERFORMANCE_REPORT as a structure report, make sure your
request meets the following restrictions:

  1. All selected fields in the report request have
  2. All fields used in the predicates of the report request have
  3. The includeZeroImpressions HTTP header is set to true.
  4. The request does not include a date range or DURING clause.

For example, the following AWQL will retrieve the ad group ID, criterion ID,
criterion type, criterion description, and targeting type for each ad group
criterion in your account:

SELECT AdGroupId, Id, CriteriaType, Criteria, IsNegative FROM CRITERIA_PERFORMANCE_REPORT

Retrieving campaign criteria

You can use the
to retrieve all campaign-level criteria in your account. Unlike the
the CAMPAIGN_CRITERIA_REPORT can only be used as a structure report.

For example, the following AWQL will retrieve the campaign ID, criterion ID,
criterion type, criterion description, and targeting type for each campaign
criterion in your account:

SELECT CampaignId, Id, CriteriaType, Criteria, IsNegative FROM CAMPAIGN_CRITERIA_REPORT

Campaigns example

This example demonstrates how to gather some relevant data about each campaign
in an account. Use an
AWQL request to gather
the data; then insert
the returned data into a local database. You can then make local SELECT
requests to build
the structural table in which you’re interested.

The following steps and code snippets show how to construct a campaigns table:

  1. Query campaign data from reports by building the AWQL request string,
    all the required column headings from the Campaign Performance
    You also must state the report type and a date range for the query. Then
    use the query to create the report,
    specifying CSV as the download format.

    SELECT CampaignStatus, CampaignId, CampaignName, ExternalCustomerId,
        CustomerDescriptiveName, Amount, BiddingStrategyId, Impressions
  2. Create a local campaigns table. This statement creates the table,
    spelling out the column
    titles and their type in our SQLite table:

    CREATE TABLE campaigns (Status STRING, id LONG, name STRING, extCID LONG,
        custName STRING, amount FLOAT, biddingStrategyId LONG, impressions INTEGER)
  3. Fill in campaigns table. The SQL statement below inserts entries into
    the campaigns table.
    Set a parameter value for each “?” using the values received in the
    report download.

    INSERT INTO campaigns (Status, id, name, extCID, custName, amount,
        biddingStrategyId, impressions) VALUES (?, ?, ?, ?, ?, ?, ?, ?)

Report formats

Reports are available in a number of formats (such as CSV or XML), but CSV
allows you to
simply feed the response stream through readily available libraries to
filter each entry into an object format of your choice. CSV output is also more
concise, so processing is often faster.

By default, CSV reports have a report header as the first line,
the column headers as the second line, followed by the results, and finally
a summary
Total line. Here’s a sample response from the
Campaign Performance Report
illustrating the default format:

"CAMPAIGN_PERFORMANCE_REPORT (Apr 1, 2015-Apr 6, 2015)"
Campaign state,Campaign ID,Campaign,Customer ID,Account,Cost,Bid Strategy Name,Impressions
paused,143072203,Search + DSAs,1234567890,My Google Ads Account,0, --,0
paused,168682400,Interplanetary Cruise 1396462861759,1234567890,My Google Ads Account,0, --,0
paused,168682099,Interplanetary Cruise 1396462699054,1234567890,My Google Ads Account,0, --,0
enabled,238539688,Campaign 1234,1234567890,My Google Ads Account,5970000, --,902
Total, --, --, --, --,5970000, --,902

The report header line in this default format is followed by the
column names requested in the second line. The returned columns are
in the same order specified in the request—unless you request duplicate
columns, in which case the second instance is omitted. The summary line
concludes the report.

When parsing and inserting the data into a database,
be sure to ignore the first two lines, then insert each of the
remaining lines until the Total line which should also be ignored.
Alternatively, you can set optional

on the request so that the report header, column headers, and summary are
omitted from the response, leaving only the data itself.

You can repeat these tasks for ad groups, ads, and criteria; then use SQL
to query the local database you just populated. You can modify
this example to utilize the collected data however you wish, for instance:

SELECT * FROM campaigns
LEFT OUTER JOIN ads ON ads.adAdGroupId=adGroups.adGroupId


SELECT * FROM criteria
JOIN keywords
WHERE criteria.critType='Keyword' AND keywords.keywordId=criteria.critId

Tips and tricks

When using this approach to retrieve account data, keep the following tips
in mind:

  • When requesting certain reports, the inclusion of columns that prevent
    rows with zero
    impressions from returning will generate no results. The KeywordId field
    in the
    Ad Performance Report is one
    such case;
    this is indicated in the Notes column for that field, and by the
    False value
    in its Support Zero Impressions column.
    Other columns can be mutually exclusive, for example, ConversionTypeName
    and Clicks.
    You should avoid these column headings when downloading structural data:
    use ones listed as Attributes in the Behavior column instead.

  • You should avoid requesting duplicate columns, since they’re removed from the
    response and will likely confuse the parsing of the data. Refer to the
    Notes column
    in the Report Types page for
    specifications on how columns are formatted.

  • If you choose not to use the optional

    to suppress the summary Total line, and instead signal the end of your
    parsing by the presence of the word Total, take care when selecting the first
    column in your AWQL query so you won’t see the word Total as one of the values
    for that column, or you’ll terminate your parsing prematurely.
    For example, you could safely use IDs as the first column, which will be
    Longs. In the example, we selected the Status column, which contains Strings
    with a limited set of values.

  • Ensure you get the right type for each column, as the parsing
    of those values into the correct values from strings will throw exceptions if you
    receive something unexpected and then call a type-specific string parser on it.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button