Custom Reporting

Overview

Custom reports provide a more flexible way to get the data you need.

The flow is similar to other Gemini reports:

  1. The API is asynchronous: Upon submitting a request, a status message is received containing a request token.

  2. If the initial response status was not ‘completed’, then the client 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 reports allow 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.

Refer to the section describing Cubes for more information. Refer to section describing Dimensions for details.

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.

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 information about conversions on click 2 call ad extensions.

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.

For more information about each individual cube refer to Cubes.

How to work with Cubes

Resource URI

https://api.gemini.yahoo.com/v1/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”.

  • The Advertiser ID filter must always be “=”.

  • No more than 999 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.

Similar to other Gemini 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
      }
}

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/{token}?advertiserId={advertiserId}

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
 ]
}

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/v1/rest/reports/cob?advertiserId={advertiserId}&date={date} 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.

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

  • Otherwise a 200 Response with the following structure:

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

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
  }
}

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.