RTB Troubleshooting

This guide covers RTB troubleshooting resources, which allow you to programmatically access real-time bidding campaign metrics that are also exposed through the RTB Breakout tool found in the Authorized Buyers UI. These include bidders.filterSets, bidders.accounts.filterSets, and all resources under them hierarchically.

Using metrics from the RTB troubleshooting resources, you can gain insights on missed opportunities to win impressions that can help you optimize your real-time bidding campaign.

Adjustments to API structure and style

The RTB troubleshooting resources introduce a few changes to explicitly indicate ownership and access, provide more granular control over the data returned by the API, and better align with Google API design practices.

Bidder-level and account-level resources

Resources are structured under both bidders and bidders.accounts. These allow you to specify whether an API call is targeting a bidder (also known as a parent account) and all associated child accounts, or individual Authorized Buyers accounts. In the context of RTB Troubleshooting, resources structured under bidders.filterSets will return aggregated metrics for the given bidder and all associated child accounts. In contrast, those under bidders.accounts.filterSets will only return metrics for the specified account regardless of whether it is a bidder or child account.

Note: Accounts that delegate their bidding to another buyer are not bidder accounts, and consequently can't access bidder-level resources. Additionally, non-bidder accounts can't access account-level impressionMetrics, filteredBidResponses, bidResponseErrors, and bidResponsesWithoutBids resources.

Introducing resource names as unique identifiers

Resource names are used as unique identifiers rather than integer or string IDs. When creating a new instance of a given resource type, you must now specify a relative resource name using the resource's URI path followed by the preferred resource ID. The following are examples of names relevant for RTB Troubleshooting resources:

Resource Name example
bidders.filterSets bidders/12345678/filterSets/fset_1
bidders.accounts.filterSets bidders/12345678/accounts/87654321/filterSets/fset_2

Note: The resource ID specified for bidders in the name must be a bidder's Authorized Buyers account ID. For accounts, the resource ID must be an account ID of either the bidder or a child account managed by it. If you do not know which Authorized Buyers accounts are associated with your Google account, you can use the accounts.list method to find them.

Filter sets

A filter set is a representation of the filtering options that are available, and can be created at the bidder or account level. It is used to filter the list results of RTB Troubleshooting resources that retrieve metrics for your real-time bidding campaigns.

The filter applied when retrieving metrics is the intersection of each filter in the specified filter set. List filters, such as platforms, are interpreted as the union of each item in the list.

Bidder and account-level filter sets are distinct and only accessible from the level in which they were created—regardless of the account used to create them. A bidder and child account share filter sets created at the account level, whereas only a bidder can access resources at the bidder level. The following table summarizes how bidder and child accounts can access resources at either level:

  bidders.filterSets bidders.accounts.filterSets
Bidder Account An API call affecting only bidder-level filter sets. An API call affecting only account-level filter sets.
Child Account This API call will return an error response. An API call affecting only account-level filter sets.

Create a filter set

When creating a filter set, you must specify a time range as either a relativeDateRange, absoluteDateRange, or realtimeTimeRange. When retrieving metrics, the default behavior is for all data to be provided for the entire time range. If you want to receive a time series breakdown over the time range, you may specify timeSeriesGranularity to indicate HOURLY or DAILY intervals.

If you only require a filter set for a short period of time, you may set the isTransient query parameter to true. This will indicate that the filter set is transient, meaning that it will not be persisted indefinitely. Transient filter sets will be available for at least one hour following their creation, but will eventually be deleted. By default, filter sets are not transient.

Bidder-level example

To create a new bidder-level filter set, send a POST request to the bidders.filterSets resource URI, which has the following format:

https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/filterSets

Warning: Bidder-level filter sets are not capable of filtering by creative or deal IDs. If you specify these filters when creating a bidder-level filter set, you will receive an error response.

Request

Here's an example of a POST request that creates a new non-transient bidder-level filter set:

POST https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/filterSets
Authorization: Bearer access token here
Content-Type: application/json

{
  "name": "bidders/12345678/filterSets/bidder-fs",
  "format": "DISPLAY",
  "environment": "APP",
  "platforms": ["TABLET", "MOBILE"],
  "absoluteDateRange": {
    "startDate": {
      "month": 11,
      "day": 26,
      "year": 2017
    },
    "endDate": {
      "month": 12,
      "day": 3,
      "year": 2017
    }
  },
  "timeSeriesGranularity": "DAILY"
}

Response

If the request succeeds, the server responds with a 200 OK status code. The response body will include the created filter set resource, which will be identical to the filter set submitted in the request.

Account-level example

To create a new account-level filter set, send a POST request to the bidders.accounts.filterSets resource URI, which has the following format:

https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/accounts/{account resource ID}/filterSets

Note: The resource ID specified for accounts can be the account ID of any Authorized Buyers account accessible to the bidder account specified in the URI, including the bidder account itself.

Request

Here's an example of a POST request that creates a new non-transient account-level filter set:

POST https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/accounts/87654321/filterSets
Authorization: Bearer access token here
Content-Type: application/json

{
  "name": "bidders/12345678/accounts/87654321/filterSets/account-fs",
  "format": "VIDEO",
  "environment": "WEB",
  "platforms": ["DESKTOP"],
  "absoluteDateRange": {
    "startDate": {
      "month": 11,
      "day": 26,
      "year": 2017
    },
    "endDate": {
      "month": 12,
      "day": 3,
      "year": 2017
    }
  },
  "timeSeriesGranularity": "DAILY"
}
Response

If the request succeeds, the server responds with a 200 OK status code. The response body will include the created filter set resource, which will be identical to the filter set submitted in the request.

Get a filter set

The get method can only get a filter set at the same level it was created. For example, a bidder account should use bidders.accounts.filterSets.get to retrieve a filter set created at the account level rather than the bidders.filterSets.get method.

Bidder-level

You can retrieve a bidder-level filter set by sending an HTTP GET request to the bidders.filterSets resource URI, which has the following format:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/filterSets/{filter set resource ID}
Request

Here's an example:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/filterSets/bidder-fs
Response

If the request succeeds, the server responds with a 200 OK HTTP status code and the retrieved filter set:

{
  "name": "bidders/12345678/filterSets/bidder-fs",
  "format": "DISPLAY",
  "environment": "APP",
  "platforms": ["TABLET", "MOBILE"],
  "absoluteDateRange": {
    "startDate": {
      "month": 11,
      "day": 26,
      "year": 2017
    },
    "endDate": {
      "month": 12,
      "day": 3,
      "year": 2017
    }
  },
  "timeSeriesGranularity": "DAILY"
}

Account-level

You can retrieve an account-level filter set by sending an HTTP GET request to the bidders.accounts.filterSets resource URI, which has the following format:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/accounts/{account resource ID}/filterSets/{filter set resource ID}
Request

Here's an example:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/accounts/87654321/filterSets/account-fs
Response

If the request succeeds, the server responds with a 200 OK HTTP status code and the retrieved filter set:

{
  "name": "bidders/12345678/accounts/87654321/filterSets/account-fs",
  "format": "VIDEO",
  "environment": "WEB",
  "platforms": ["DESKTOP"],
  "absoluteDateRange": {
    "startDate": {
      "month": 11,
      "day": 26,
      "year": 2017
    },
    "endDate": {
      "month": 12,
      "day": 3,
      "year": 2017
    }
  },
  "timeSeriesGranularity": "DAILY"
}

List filter sets

The list method will only return filter sets accessible from the level it is being called. For example, a bidder account will not see filter sets created for itself through bidders.accounts.filterSets.create when calling bidders.filterSets.list.

Bidder-level

You can retrieve all bidder-level filter sets for a given bidder by sending an HTTP GET request to the bidders.filtersets resource URI, which has the following format:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/filterSets
Request

Here's an example listing all bidder-level filter sets for a bidder with an account ID of 12345678:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/filterSets
Response
{
  "filterSets": [{
      "filterSetId": "99994",
      "name": "bidders/12345678/filterSets/test-b-1",
      "relativeDateRange": {
        "durationDays": 30
      }
    },
    {
      "realtimeTimeRange": {
        "startTimeStamp": "2017-11-15T12:30:30.072831583Z"
      },
      "filterSetId": "99995",
      "name": "bidders/12345678/filterSets/test-b-2",
      "timeSeriesGranularity": "HOURLY"
    },
    {
      "absoluteDateRange": {
        "endDate": {
          "day": 12,
          "month": 3,
          "year": 2017
        },
        "startDate": {
          "day": 26,
          "month": 11,
          "year": 2017
        }
      },
      "filterSetId": "99996",
      "name": "bidders/12345678/filterSets/bidder-fs",
      "timeSeriesGranularity": "DAILY",
      "platforms": ["TABLET", "MOBILE"],
      "environment": "APP",
      "format": "DISPLAY"
    }
  ]
}

Account-level

You can retrieve all account-level filter sets for a given account by sending an HTTP GET request to the bidders.accounts.filtersets resource URI, which has the following format:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/accounts/{account resource ID}/filterSets
Request

Here's an example listing all account-level filter sets for a child account with an account ID of 87654321:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/accounts/87654321/filterSets
Response
{
  "filterSets": [{
        "realtimeTimeRange": {
        "startTimeStamp": "2017-11-19T04:24:43.252893487Z"
      },
      "filterSetId": "99997",
      "name": "bidders/12345678/accounts/87654321/filterSets/test-a-1",
      "timeSeriesGranularity": "DAILY"
    },
    {
      "absoluteDateRange": {
        "endDate": {
          "day": 3,
          "month": 12,
          "year": 2017
        },
        "startDate": {
          "day": 26,
          "month": 11,
          "year": 2017
        }
      },
      "filterSetId": "99998",
      "name": "bidders/12345678/accounts/87654321/filterSets/account-fs",
      "timeSeriesGranularity": "DAILY",
      "platforms": ["DESKTOP"],
      "environment": "WEB",
      "format": "VIDEO"
    }
  ]
}

Delete a filter set

You can use the delete method to remove any non-transient filter sets that are no longer needed. It can only remove filter sets accessible from the level it is being called; for example, a bidder account can't delete a filter set created with bidders.accounts.filterSets.create with bidders.filterSets.delete.

Bidder-level

You can delete a bidder-level filter set for a given account by sending an HTTP DELETE request to the bidders.filtersets resource URI, which has the following format:

DELETE https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/filterSets/{filter set resource ID}
Request

Here's an example deleting a bidder-level filter set:

DELETE https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/filterSets/test-b-2
Response

If successful, the request body will be empty. The specified filter set will no longer be accessible.

Account-level

You can delete an account-level filter set for a given account by sending an HTTP DELETE request to the bidders.accounts.filtersets resource URI, which has the following format:

DELETE https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/accounts/{account resource ID}/filterSets/{filter set resource ID}
Request

Here's an example deleting an account-level filter set:

DELETE https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/accounts/87654321/filterSets/test-a-1
Response

If successful, the request body will be empty. The specified filter set will no longer be accessible.

Retrieve RTB troubleshooting metrics

All RTB troubleshooting resources used to receive metrics operate in a similar way—they have a single method to list metrics for the filter set specified through a filterSetName path parameter. The filter set specified will determine what filters and settings will be applied when querying the metrics. Calling these resources from the bidder level will return aggregated metrics from the bidder account and all associated child accounts, whereas a call from the account level will only return metrics for an individual account.

Bid Metrics

The bidMetrics resource is used to retrieve metrics that are measured in the number of bids. For example, you can use this to determine your total number of bids over a given time range, and how many of those were not filtered from the auction, won an impression, etc. Like all other RTB troubleshooting resources used to collect metrics, it only has a list method.

List bidder-level bid metrics

You can list bidder-level bid metrics for a given filter set by sending an HTTP GET request to the bidders.filtersets.bidMetrics resource URI, which has the following format:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/filterSets/{filter set resource ID}/bidMetrics
Request

Here's an example listing bidder-level bid metrics:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/filterSets/bidder-fs/bidMetrics
Response

If the request succeeds, the server responds with a 200 OK status code and a body containing rows of metrics for the specified dimensions and granularity.

{
  "bidMetricsRows": [{
        "bids": {
        "value": "6160"
      },
      "bidsInAuction": {
        "value": "5698"
      },
      "billedImpressions": {
        "value": "1196"
      },
      "impressionsWon": {
        "value": "2920"
      },
      "measurableImpressions": {
        "value": "1160"
      },
      "rowDimensions": {
        "timeInterval": {
          "endTime": "2017-11-29T08:00:00Z",
          "startTime": "2017-11-28T08:00:00Z"
        }
      },
      "viewableImpressions": {
        "value": "683"
      }
    },
    {
      "bids": {
        "value": "104288"
      },
      "bidsInAuction": {
        "value": "94016"
      },
      "billedImpressions": {
        "value": "99"
      },
      "impressionsWon": {
        "value": "125"
      },
      "measurableImpressions": {
        "value": "94"
      },
      "rowDimensions": {
        "timeInterval": {
          "endTime": "2017-11-30T08:00:00Z",
          "startTime": "2017-11-29T08:00:00Z"
        }
      },
      "viewableImpressions": {
        "value": "87"
      }
    },
    {
      "bids": {
        "value": "3999"
      },
      "bidsInAuction": {
        "value": "3631"
      },
      "billedImpressions": {
        "value": "618"
      },
      "impressionsWon": {
        "value": "1819"
      },
      "measurableImpressions": {
        "value": "604"
      },
      "rowDimensions": {
        "timeInterval": {
          "endTime": "2017-12-01T08:00:00Z",
          "startTime": "2017-11-30T08:00:00Z"
        }
      },
      "viewableImpressions": {
        "value": "369"
      }
    },
    {
      "bids": {
        "value": "15"
      },
      "bidsInAuction": {
        "value": "3"
      },
      "billedImpressions": {},
      "impressionsWon": {
        "value": "3"
      },
      "measurableImpressions": {},
      "rowDimensions": {
        "timeInterval": {
          "endTime": "2017-12-02T08:00:00Z",
          "startTime": "2017-12-01T08:00:00Z"
        }
      },
      "viewableImpressions": {}
    }
  ]
}

Note: Any fields set to 0 for a given metric will not appear in the response. The empty billedImpressions and measurableImpressions metrics above indicate that both the value and variance for these are set to 0.

Warning: For any breakdown of data in the response, the response will not include rows if they don't contain at least one non-zero metric. For example, when a timeSeriesGranularity is specified, the response will not include rows for any timeInterval over the filter set's specified time range where all metrics are zero.

List account-level bid metrics

You can list account-level bid metrics for a given filter set by sending an HTTP GET request to the bidders.accounts.filtersets.bidMetrics resource URI, which has the following format:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/{bidder resource ID}/accounts/{account resource ID}/filterSets/{filter set resource ID}/bidMetrics
Request

Here's an example listing account-level bid metrics:

GET https://adexchangebuyer.googleapis.com/v2beta1/bidders/12345678/accounts/87654321/filterSets/account-fs/bidMetrics
Response

If the request succeeds, the server responds with a 200 OK status code and a body containing rows of metrics for the specified dimensions and granularity.

{
  "bidMetricsRows": [{
      "bids": {
        "value": "1748"
      },
      "bidsInAuction": {
        "value": "1421"
      },
      "billedImpressions": {
        "value": "301"
      },
      "impressionsWon": {
        "value": "915"
      },
      "measurableImpressions": {
        "value": "298"
      },
      "rowDimensions": {
        "timeInterval": {
          "endTime": "2017-12-01T08:00:00Z",
          "startTime": "2017-11-30T08:00:00Z"
        }
      },
      "viewableImpressions": {
        "value": "172"
      }
    },
    {
      "bids": {
        "value": "6"
      },
      "bidsInAuction": {
        "value": "2"
      },
      "billedImpressions": {},
      "impressionsWon": {
        "value": "1"
      },
      "measurableImpressions": {},
      "rowDimensions": {
        "timeInterval": {
          "endTime": "2017-12-02T08:00:00Z",
          "startTime": "2017-12-01T08:00:00Z"
        }
      },
      "viewableImpressions": {}
    }
  ]
}

Note: Any fields set to 0 for a given metric will not appear in the response. The empty billedImpressions and measurableImpressions metrics above indicate that both the value and variance for these are set to 0.

Warning: For any breakdown of data in the response, the response will not include rows if they don't contain at least one non-zero metric. For example, when a timeSeriesGranularity is specified, the response will not include rows for any timeInterval over the filter set's specified time range where all metrics are zero.