## Overview

The following instructions provide examples of how to query both valid
[viewability](https://developers.google.com/ads-data-hub/marketers/resources/glossary#viewability) traffic, and
[invalid traffic](https://developers.google.com/ads-data-hub/marketers/resources/glossary#invalid_traffic) by
using the API. These metrics are limited to inventory purchased using Google Ads
and Display \& Video 360.

Note that MRC-accredited
[TrueView view](https://developers.google.com/ads-data-hub/marketers/resources/glossary#trueview) metrics require
the use of the ADH API, as there is no associated templated query. Additionally,
TrueView view metrics shouldn't be confused with viewability metrics.

Select the buying door that you want to query viewability metrics for:
<button value="Google Ads" default="">Google Ads</button> <button value="Display & Video 360">Display \& Video 360</button>

## Query viewability metrics using the UI

The templated viewability query provides MRC-accredited metrics.

MRC accreditation is binary---your results can be accredited, or not---and applies
to your entire results table. You must run the query through the template,
without modifying it, and in difference check mode in order for your metrics to
be MRC-accredited. Ads Data Hub's MRC accreditation doesn't extend to queries
run in [noise mode](https://developers.google.com/ads-data-hub/marketers/guides/noise-injection).

To run the MRC-accredited query through the template:

1. Follow the instructions on [how to create a query](https://developers.google.com/ads-data-hub/marketers/guides/run-queries), ensuring that you select **Google Ads** as the buying door and **Video viewability by device type** as the query template.
2. Click the **Run** button next to **Use template**.

> [!NOTE]
> **Note:** The campaign IDs should all specify the same time zone as used in the UI, otherwise the data may not be accurate for campaigns outside the specified time zone.

## Query invalid traffic and viewability metrics using the API

Invalid traffic and viewability metrics can be retrieved from the ADH API using the `generateIvtReport` and `startAnalysis` endpoints. For invalid traffic, your metrics must be retrieved through the `generateIvtReport` in order for the `adh-mrc-accredited` [label](https://cloud.google.com/bigquery/docs/labels-intro) to be applied and your metrics to be MRC-accredited. Similarly, the global query specified below must be used for viewability metrics through the ADH API for MRC accreditation. This section covers how to send a request to this endpoint using the Python client library.

Follow the setup and authorization/authentication instructions in the [API quickstart](https://developers.google.com/ads-data-hub/marketers/guides/quickstart-api).

After replacing the following fields with information relevant to your account, you can run the query below to retrieve an invalid traffic report for your Google Ads campaigns:

- Client secrets file
- Customer ID
- API key
- Campaign IDs
- Timezone

### Sample code

### Invalid traffic

    import json
    import os.path
    from google.auth.transport.requests import Request
    from google.oauth2.credentials import Credentials
    from google_auth_oauthlib.flow import InstalledAppFlow
    from googleapiclient.discovery import build

    # If modifying these scopes, delete the file `token.json`.
    SCOPES = ['https://www.googleapis.com/auth/adsdatahub']
    TOKEN_FILE = 'token.json'

    creds = None

    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists(TOKEN_FILE):
        creds = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'YOUR_CLIENT_SECRETS.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run.
        with open(TOKEN_FILE, 'w') as token:
            token.write(creds.to_json())

    service = build('adsdatahub', 'v1', credentials=creds,
                    developerKey='YOUR_API_KEY', static_discovery=False)

    body = {
        'ads_data_customer_id': YOUR_CUSTOMER_ID,
        'start_date': {
            'year': 2019,
            'month': 12,
            'day': 15
        },
        'end_date': {
            'year': 2019,
            'month': 12,
            'day': 20
        },
        'time_zone': 'YOUR_TIMEZONE',
        # Optional. Defaults to 'DAY' (one set of rows per day). Use
        # 'ENTIRE_DATE_RANGE' for a single set of rows covering the whole range.
        'date_dimension_granularity': 'DAY',
        'google_ads_dimensions': {
            'campaign_ids': [YOUR_CAMPAIGN_IDS],
            'metric_type': 'METRIC_TYPE_IMPRESSION'
        },
        'dest_table': 'YOUR_DESTINATION_TABLE'
    }

    resp = service.customers().generateIvtReport(
        name='customers/YOUR_CUSTOMER_ID', body=body).execute()
    print(json.dumps(resp))

### Viewability metrics

    import json
    import os.path
    from google.auth.transport.requests import Request
    from google.oauth2.credentials import Credentials
    from google_auth_oauthlib.flow import InstalledAppFlow
    from googleapiclient.discovery import build

    # If modifying these scopes, delete the file `token.json`.
    SCOPES = ['https://www.googleapis.com/auth/adsdatahub']
    TOKEN_FILE = 'token.json'

    creds = None

    # The file token.json stores the user's access and refresh tokens, and is
    # created automatically when the authorization flow completes for the first
    # time.
    if os.path.exists(TOKEN_FILE):
        creds = Credentials.from_authorized_user_file(TOKEN_FILE, SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file(
                'YOUR_CLIENT_SECRETS.json', SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run.
        with open(TOKEN_FILE, 'w') as token:
            token.write(creds.to_json())

    service = build('adsdatahub', 'v1', credentials=creds,
                    developerKey='YOUR_API_KEY', static_discovery=False)

    name = 'customers/global/analysisQueries/f41320e7296d49158e572aba662f35b1'
    body = {
      'spec': {
        'ads_data_customer_id': YOUR_CUSTOMER_ID,
        'start_date': {
          'year': 2019,
          'month': 12,
          'day': 15
        },
        'end_date': {
          'year': 2019,
          'month': 12,
          'day': 20
        },
        'time_zone': 'YOUR_TIMEZONE',
        'parameter_values': {
          'campaign_ids': {
            'array_value': {
              'values': [
                {
                  'value': 'YOUR_CAMPAIGN_ID'
                },
              ]
            }
          }
        }
      },
      'dest_table': 'YOUR_DESTINATION_TABLE',
      'customer_id': YOUR_CUSTOMER_ID
    }

    resp = service.customers().analysisQueries().start(name=name,body=body).execute()
    print(json.dumps(resp))

## Calculate viewability metrics net of general invalid traffic

Use the following formulas to derive MRC-accredited viewability metrics net of
general invalid traffic (GIVT):

- Total Impressions (Net of GIVT): Total Impressions - General Invalid Impressions
- Viewable Impressions (Net of GIVT): Viewable Impressions + Invalid Viewable Impressions - GIVT Viewable Impressions
- Measurable Impressions (Net of GIVT): Measurable Impressions + Invalid Measurable Impressions - GIVT Measurable Impressions
- Eligible Impressions (Net of GIVT): Eligible Impressions + Invalid Eligible Impressions - GIVT Eligible Impressions
- Non-Viewable Impression (Net of GIVT) : Measurable Impressions (Net of GIVT) - Viewable Impressions (Net of GIVT)
- Unmeasurable Impressions (Net of GIVT): Eligible Impressions (Net of GIVT) - Measurable Impressions (Net of GIVT)
- % Measurable Impressions (Net of GIVT): Measurable Impressions (Net of GIVT) / Eligible Impressions (Net of GIVT)
- % Viewable Impressions (Net of GIVT): Viewable Impressions (Net of GIVT) / Measurable Impressions (Net of GIVT)