Introduction to ReportDefinitionService

Tuesday, July 13, 2010


Reporting is an integral part of most AdWords API applications. To help you create and manage reports related to your AdWords campaigns, we introduced the ReportDefinitionService in the v201003 version of the AdWords API. In this post, we’ll cover the basics of working with the ReportDefinitionService. If you’ve used the v13 ReportService, you’ll notice that the new ReportDefinitionService differs in many ways from its v13 counterpart.

Retrieving the report fields

To create a report in the v201003 version of AdWords API, you pick a report type of your choice and then retrieve the list of supported fields using getReportFields. The Java code below shows how to retrieve the report fields:

// Get report fields.
ReportDefinitionField[] reportDefinitionFields = 
    reportDefinitionService.getReportFields(
        ReportDefinitionReportType.KEYWORDS_PERFORMANCE_REPORT);
// Display report fields.
System.out.println("Available fields for report:");
for (ReportDefinitionField reportDefinitionField : reportDefinitionFields) {
  System.out.print("\t" + reportDefinitionField.getFieldName() + "("
      + reportDefinitionField.getFieldType() + ")");
}

This feature is quite convenient if you want to display the list of supported fields for a user and allow the users to pick the desired fields. For those who prefer static documentation like in v13, we are working on it, and it will be made available in the near future.

Defining the report

To create a report in the v201003 version of AdWords API, you have to create a report definition first. This is different from the v13 version of API, where you could schedule a report without creating any definitions first. The following Java code snippet creates a report definition:

// Create ad group predicate.
Predicate adGroupPredicate = new Predicate();
adGroupPredicate.setField("AdGroupId");
adGroupPredicate.setOperator(PredicateOperator.EQUALS);
adGroupPredicate.setValues(new String[] {adGroupId});
 
// Create selector.
Selector selector = new Selector();
selector.setFields(new String[] {"AdGroupId", "Id", "KeywordText",
    "KeywordMatchType", "Impressions", "Clicks", "Cost"});
selector.setPredicates(new Predicate[] {adGroupPredicate});
selector.setDateRange(new DateRange(startDate, endDate));
 
// Create report definition.
ReportDefinition reportDefinition = new ReportDefinition();
reportDefinition.setReportName("Keywords performance report”);
reportDefinition.setDateRangeType(ReportDefinitionDateRangeType.CUSTOM_DATE);
reportDefinition.setReportType(ReportDefinitionReportType.KEYWORDS_PERFORMANCE_REPORT);
reportDefinition.setDownloadFormat(DownloadFormat.XML);
reportDefinition.setSelector(selector);
 
// Create operations.
ReportDefinitionOperation operation = new ReportDefinitionOperation();
operation.setOperand(reportDefinition);
operation.setOperator(Operator.ADD);
ReportDefinitionOperation[] operations = new ReportDefinitionOperation[]
    {operation};
 
// Add report definition.
ReportDefinition[] result = reportDefinitionService.mutate(operations);

When successful, the API call creates a report definition under the report section of your account’s Control Panel and Library. You may delete or modify a report definition using the mutate method, with operators as REMOVE and SET respectively. You can also retrieve all report definitions in your account using the get method.

If you’d like to inexpensively validate the report definition before adding it, you can call the mutate method as shown above with the validateOnly header set. This works similar to the validateReportJob method in v13 version of AdWords API. You can refer to our earlier blog post for details on how to use validateOnly headers to validate API calls.

The v201003 version of ReportDefinitionService introduces a new feature called predicates. You can use predicates to filter the results by any field with canFilter=true.. You can also use various operators to define the filtering condition. This is an improvement over v13 where the data could only be filtered using certain predefined fields like campaignId or adGroupId.

The v201003 version of ReportDefinitionService allows you to generate reports for predefined date ranges. This is very useful if you need to download a predefined type of report on a regular basis. For instance, you can create a single report definition with dateRangeType as YESTERDAY, and then use that report definition to download a daily report. This is an improvement over v13 where you needed to schedule a new report every day to accomplish the same task. If you need to download reports for a custom period, you can set dateRangeType as CUSTOM_DATE.

The v201003 ReportDefinitionService currently has some limitations: it lacks support for aggregation types and cross client reports. We are working to add support for these features in a future version of the AdWords API.

Generating and downloading a report

To download a report in the v201003 version of AdWords API, you need to issue a HTTP GET to https://adwords.google.com/api/adwords/reportdownload?__rd=reportDefinitionId. You can get the report definition id from the result returned by the server when you add a report definition as shown in the code sample above. In addition, you need to specify authToken and clientLogin (or clientCustomerId) as http headers to authorize the report download. Note that the clientLogin or clientCustomerId must be the same as the one used while creating the report definition. The sample Java code below downloads a report:

String url = "https://adwords.google.com/api/adwords/reportdownload?__rd="
    + reportDefinitionId;
 HttpURLConnection urlConn = 
    (HttpURLConnection) new URL(url).openConnection();
urlConn.setRequestMethod ("GET");
urlConn.setRequestProperty("Authorization", "GoogleLogin auth="
    + user.getRegisteredAuthToken());
if (user.getClientCustomerId() != null) {
  urlConn.setRequestProperty("clientCustomerId", user.getClientCustomerId());
} else if (user.getClientEmail() != null) {
  urlConn.setRequestProperty("clientEmail", user.getClientEmail());
} else {
  urlConn.setRequestProperty("clientEmail", user.getEmail());
}
urlConn.connect();
copyStream(urlConn.getInputStream(), new FileOutputStream(
    new File(outputFileName)));

The raw HTTP message when executing this code is as shown below:

GET /api/adwords/reportdownload?__rd=XXXXXX HTTP/1.1
Host: adwords.google.com
Accept: */*
Authorization: GoogleLogin auth=XXXXXX
clientEmail: XXXXXX

A major difference between this approach and the v13 approach is that the report generation is inherently synchronous, unlike in v13 where you had to poll regularly using getReportJobStatus to see if a report job completed, and later use getReportDownloadUrl to get the report download url. Also, the report generation in v201003 is much faster than in v13, and most reports complete in a few seconds. The request to download reports will time out after 3 minutes, so we recommend that you use gzipped csv format to minimize transfer size of potentially large reports. GZipped XML format is not yet supported, but we’re working to include this feature in a future version of the AdWords API.

We've included support for ReportDefinitionService in all of our client libraries to help get you started, so please try it out and share your feedback with us on the forum or the projects' issue trackers.

-- Anash P. Oommen, AdWords API Team