Reporting

Abstract

Custom reporting provides you with a more flexible way to get the data you need.

Caveats

Important

Be aware that action may be required for the following deprecated reporting endpoint.

Old: https://api.gemini.yahoo.com/v1/rest/reports
New: https://api.gemini.yahoo.com/v2/rest/reports/custom

In the context of migrating to the v2 Native API, note the following:

  • If you currently make calls only to /v2/rest/reports/custom for both POST and GET, there is no action required.

  • If you currently make POST calls to /v1/rest/reports, then you need to migrate to the /v2/rest/reports/custom endpoint as soon as possible.

  • If you currently make POST calls to /v1/rest/reports/custom and GET calls to /v1/rest/reports, then you need to migrate to v2 before v1 End of Life (EOL) next year, Sept 1, 2017.

Overview

The workflow for custom reporting is similar to other Native reporting workflows:

  1. The API is asynchronous: Upon submitting a request, you’ll receive a status message containing a request token.

  2. If the initial response status was not ‘completed’, you must periodically make additional requests (passing in the request token) to poll the status.

  3. Consider the data that you own and poll for downloads at reasonable intervals.

  4. Once a report has completed, the status response will contain the URL from which the report can be fetched.


Important

This is a time-limited URL and needs to be downloaded within 6 hours of the report generation.

About Cubes and Dimensions

Custom reporting allows you to query cubes, which are pre-defined collections of fields that define the context of your report. When you query cubes, you can choose the rollup aggregation level, apply various filters, and select which fields you would like the report to include. All fields within a cube are classified as either Fact or Dimension fields. Fact fields are effectively metrics that can be rolled up and aggregated, while dimension fields provide entity details and metadata.

You can use dimensions to request additional entity metadata that is not provided by default in the cube table. If you want attributes from a certain dimension to be included in the report then you must include the dimension’s ID field in the field list. For example, if you would like to include “Ad Landing URL” in a report from the performance_stats cube, then the “Ad ID” must also be requested along with the “Ad Landing URL” field.

Types and Capabilities

Use the following cubes to query the custom reports endpoint:

Type

Description

performance_stats

Provides performance stats for all levels down to the ad level.

slot_performance_stats

Provides performance stats for all levels down to the ad level. Use this cube for per-card Carousel Ads reporting.

site_performance_stats

Provides performance stats for all levels down to the ad group level. Use this cube when querying for native ads campaign data.

campaign_bid_performance_stats

Provides stats for all levels down to the ad group level. Use this cube when evaluating group-level bid modifiers.

structured_snippet_extension_stats

Provides stats for all levels down to the ad level. This cube only contains search performance data that resulted from a Structured snippet extension impression.

product_ad_performance_stats

Provides performance stats for all levels down to the ad level. Use this cube when querying for native ads campaign data. It is only available for native ads.

adjustment_stats

Reporting stats for campaign and account adjustments.

keyword_stats

Standard performance metrics at all entity levels of the account down to the keyword level.

search_stats

Provides keyword level performance data.

ad_extension_details

Performance data that resulted from an ad extension impression.

call_extension_stats

Provides detailed information about click to call conversion details at account, campaign and ad group levels. Both search and native ads data are included in the response.

user_stats

Provides a breakdown across various targeting attributes, such as age, gender, device, geo (country, state, dma, city, zip), both for the physical location of the user and the location of his or her interest.

product_ads

Provides product group as well as product level reporting.

conversion_rules_stats

A breakdown of stats by conversion rules, conversion categories, and other conversion-related info.

domain_performance_stats

Provides domain performance stats for all levels down to the ad group level. It is recommended to use this cube when querying for native ads campaign data.

For more information about each individual cube refer to Cubes.

How to Work with Cubes

Resource URI

https://api.gemini.yahoo.com/v2/rest/reports/custom

Submit a new job

Call: To request a new report, make a POST call to /reports/custom with a request body similar to the following:

 { "cube": "performance_stats",
"fields": [
    { "field": "Ad ID" },
    { "field": "Day" },
    { "alias": "My dummy column", "value": "" },
    { "field": "Impressions" },
    { "field": "Ad Image URL", "alias": "url" }
  ],
"filters": [
    { "field": "Advertiser ID", "operator": "=", "value": 12345 },
    { "field": "Campaign ID", "operator": "IN", "values": [10,20,30] },
    { "field": "Day", "operator": "between", "from": "2014-04-01", "to": "2014-04-30" }
  ]
}

Request JSON structure

A typical request will include the following attributes:

  • cube: A pre-defined collection of fields. The cube defines the context of your report and controls the fields you can query across. Note that all fields within a cube are classified as either Fact or Dimension fields. Fact fields are effectively metrics that can be rolled up and aggregated, while dimension fields provide entity details and metadata.

  • fields: The fields list specifies the fields the report will include. The following are guidelines for working with the fields attribute:

  • Rollup is implicitly defined by the level of the requested dimension fields. For example, if your request includes Ad ID as the lowest level, all the fact fields will be aggregated to the ad level.

  • A date field must always be included. You can select either Day, Week or Month as field values, depending on the date rollup you require.

  • The value of the field attribute should be the name of a field in the requested cube.

  • The optional alias attribute allows the field to be renamed. The value provided in the alias attribute is what will be displayed in the reporting header.

  • You can provide alias and value attributes and no field attribute if you want to add a fixed value column to the report.

  • The order of the fields in the fields list is significant - it determines their order in the generated report.

  • You can only ask for a named field once - requesting duplicate fields will result in an error. All alias names must also be unique and distinct from the other named fields in the report.

  • At least one ID field must always be included. It is not possible, for example, to request fact fields to be rolled up to Pricing Type.

  • If you want attributes from a certain dimension to be included in the report, then you must include the dimension’s ID field in the field list too. For example, if you would like to include Keyword Value in a report, then you must also request Keyword ID.

  • filters: The following are guidelines to working with filters:

  • Each cube has certain fields that can be used to filter the report data - refer to the cube fields section for more details.

  • “Advertiser ID” and “Day” filters are required in every report request.

  • supported filter operations are “=”, “IN” and “between”.

  • No more than 1000 values can be specified in the “values” list of an “IN” operator. Note that the Campaign ID filter must always be “IN” to the above list.

  • Regardless of which date field was requested - Day, Week, or Month - you must alway filter using “Day”. The results will be displayed broken down by the date rollup level that was requested - each row in the report will show the first day of that period. For example, if Month is requested as the date rollup level, then the data will be aggregated for the month, including only the days specified by the filter. So if the Day filter is for 2014-04-02 to 2014-04-03, then the total for those two days will be reported in one row with a Month value of 2014-04-01, indicating the first day of the month.

  • Day, Week and Month values should be in ‘YYYY-MM-DD’ format.

Note

Retention is set to 400 days for all the daily data.

Similar to other Native API reports, upon successfully submitting a job request for a custom report, the response will include a token that you will use to poll the job’s status:

{
      "errors": null,
      "response": {
      "jobId": "628cf1c0cd1c5d8a6c1765f618b7a0be34c50bc1564618",
      "status": "submitted",
      "jobResponse": null
      }
}

Working with Multiple Accounts

Up to 1000 accounts can be specified at a time as part of the Advertiser ID field.

Note the following: When multiple account IDs are involved, the first advertiser ID should be used as the advertiserID in the JSON request for data parsing purposes.

Below is a sample JSON snippet showing the advertiser ID filter section for including more than one advertiser ID:

{ "field": "Advertiser ID", "operator": "IN", "values": [ 123456, 45677, 78945 ] }

Selecting Response Format

Custom reports are provided in CSV format by default but you can choose to receive reports in JSON format by passing in ?reportFormat=json in the reporting job request.

Get job status

Call: To query the status of your report request, make a GET call to /reports/custom/{JobId}?advertiserId={advertiserId}

When multiple account IDs are involved, the first advertiser ID should be used as the advertiserID parameter for the subsequent GET reporting call. For example, for a JSON sample request, with “123456” as the first advertiser ID, make a GET call to /reports/custom/{JobId}?advertiserId=123456

Response: The response would be one of the following:

  • 404 Not Found: if {token} is invalid or unknown.

  • 200 (with the following fields): { “jobId”: “the report request token”, “status”: “submitted|running|failed|completed|killed”, “response”: “” }

The meaning of the possible statuses is detailed below:

Status

Description

submitted

The job is in queue but work on it has yet to commence.

running

The job is running.

failed

The job ran but unexpectedly failed.

killed

The job was killed, typically due to failure to complete in a timely manner.

completed

The job completed successfully.

When the job is completed, you will receive a URL you will use to download the report data:

 {
      "errors": null,
      "response": {
      "jobId": "628cf1c0cd1c5d8a6c1765f618b7a0be34c50bc1564618",
      "status": "completed",
      "jobResponse": "https://nads.zenfs.com/nads/reportGeneration/628cf1c0cd1c5d8a6c1765f618b7a0be34c50bc1564618.csv"
      }
}

Job response

CSV response: Reports in CSV format will consist of one header row that lists the field names as specified in the request in the order they were requested, and zero or more data rows.

JSON response: When reports are requested in JSON format, the JSON response structure would be as follows:

{ "header":
 { "cube": "cube-name-as-per-the-request"
   "fields": [
       { "fieldName": "Field name as given in the request JSON"
         "fieldType": "DIM|FACT|CONSTANT"
       },
       ...
   ]
 }
 "rows": [
   row-1-json,
   ...
   row-N-json
 ]
}

Examples

The following example shows a report for advertiser 7654, asking for DAY interval stats between the 7th and 9th January 2014, at the ad level for ad_ids 2,3,5,7 and 11. The query does not request ad level metadata but does ask for campaign and advertiser metadata:

{
  "ad": { "fields": ["DETAILS", "STATS"], "filters": {"ids": [2,3,5,7,11]} },
  "campaign": { "fields": ["DETAILS"] },
  "advertiser": { "fields": ["DETAILS"] },
  "filters": {
      "fromDate": "2014-01-07",
      "toDate": "2014-01-09",
      "interval": "DAY",
      "advertiserId": 7654
  }
}

Note

Retention is set to 400 days for all the daily data.

The following example shows another report for advertiser 7654, asking for DAY interval stats between the 7th and 9th January 2014 - this time we are requesting campaign-keyword level stats, as well as campaign and keyword metadata:

{
  "campaign": { "fields": ["DETAILS"]},
  "campaignKeyword": { "fields": ["STATS", "DETAILS"], "filters": {"ids": [2,3,5,7,11]} },
  "filters": {
      "fromDate": "2014-01-07",
      "toDate": "2014-01-09",
      "interval": "DAY",
      "advertiserId": 7654
  }
}

Note

“STATS” must be requested at one level only.

Note

Retention is set to 400 days for all the daily data.

About Books Closed

A day is marked as closed only after all stats data have been received by reporting and close of day adjustments have been received and applied. A month is marked as closed only after all of the days within the month have been closed and any end-of-month processing has been completed and applied.

Call: To query whether books are closed for a given date, make a GET call to

``https://api.gemini.yahoo.com/v2/rest/reports/cob?advertiserId={advertiserId}&date={date}&cubeName={cube_name}`` and pass in the following parameters:

Name

Description

advertiserId

The ID of the advertiser.

date

The date you would like to check if books have been closed in yyyymmdd format in the advertiser’s timezone.

cubeName

The name of the cube that you can query for close of books. The field is optional. Note that you can only pass one cube name at a time. The currently supported cube names include

  • performance_stats

  • keyword_stats

  • conversion_rules_stats

  • search_stats

  • ad_extension_details

  • call_extension_stats

  • user_stats

  • adjustment_stats

  • product_ads

Response: The response would be one of the following:

  • 404 Not Found: if {advertiserId} is invalid or unrecognized

  • 400 Bad Request: if an invalid date has been passed, or if an invalid cube name has been passed.

  • Otherwise a 200 Response with the following structure:

{ "advertiserId": 1234,
  "advertiserTimezone": "America/New_York",
  "isDayClosed": true|false,
  "isMonthClosed": true|false
}

Sample cube-specific response:

{ "advertiserId":1234,
  "advertiserTimezone":"America/New_York",
  "cubeName":"user_stats",
  "dayProgressPercent":100,
  "isMonthClosed": true|false,
  "isDayClosed": true|false
}