Downloading an AdWords API Report

in AdWords API

I think I must have written a similar tutorial several times over the years, but it's time to post another one as the method to extract reports from AdWords has just changed once again. The latest version of the AdWords API (v201109) was released a few days ago with an announcement there's a new way to download reports. I've been checking out the changes and playing with the code, so read on if your interested in how it's now working.

What's Changed in the Latest Version of the API?

When the AdWords API was first released, reports were available via the AdWords Report Center and worked asynchronously: they needed to be scheduled then polled in a similar way to the current [adCenter API reporting solution][link-14]. Then, in 2009, Google released a completely revised version of the API with new reporting, which coincided with the change in AdWords to put reporting in the Campaigns tab instead of the Report Center. This version required developers to first define a report using the ReportDefinitionService, then download it via a HTTP request. The actual download was free, but the call to the ReportDefinitionService still used API quota.

Now, from October 2011, we no longer need to define a report first using the ReportDefinitionService; instead, reports can be defined and downloaded using a single HTTP call. The ReportDefinitionService has been depreciated and replaced with an AdHoc reports service that enables you to simply send the ReportDefinition to the AdWords server in the body of a HTTP POST request, then wait for the report to be produced and downloaded.

This new method is advantageous because it uses less resources, so allows applications to download more than one report at a time; moreover, the actual AdWords API SOAP interface is no longer used at all, which finally makes downloading reports completely free of charge!

[link-14]: "adCenter API Reports"

Using the AdHoc Reporting Service

I've just downloaded a few of the latest versions of the Client Libraries, but, for today at least, there aren't any updates to use the new service. Don't let that deter you from digging into this great new feature though; it's not too difficult to construct the request yourself then post it using cURL or something similar.

Composing the Report Definition

The first thing you need to do is specify the parameters of the report you want to create. This is done using a similar XML syntax to the definitions in the ReportDefinitionService, but without the extraneous SOAP bits: Define a ReportDefinition using an XML fragment with the <reportDefinition> tag as the root node. The elements that you can use to describe a report request can be found on the ReportDefinition page in the API documentation.

Although the documentation might seem daunting at first without a client library, a simple trick to generate the XML fragment is to use the ReportDefinitionService from the old version of the API, then log the SOAP that gets generated and use it in your code. Here's an example I've generated to get started with:

<reportDefinition>
    <reportName>Ad Performance Report</reportName>
    <reportType>AD_PERFORMANCE_REPORT</reportType>
    <dateRangeType>CUSTOM_DATE</dateRangeType>
    <downloadFormat>CSV</downloadFormat>
    <selector>
        <fields>Id</fields>
        <fields>Date</fields>
        <fields>AdGroupId</fields>
        <fields>Impressions</fields>
        <fields>Clicks</fields>
        <fields>Cost</fields>
        <fields>Conversions</fields>
        <fields>ConversionValue</fields>
        <fields>AveragePosition</fields>
        <dateRange>
            <min>20110712</min>
            <max>20111010</max>
        </dateRange>
    </selector>
</reportDefinition>
An AdWords API Report Definition

Requesting the AdHoc Report

OK, now we have a basic report request it needs to be submitted to the AdWords API server. The URL to use is: https://adwords.google.com/api/adwords/reportdownload/[API Version], where [API Version] needs to be replaced with the current release of the API, so should currently be: https://adwords.google.com/api/adwords/reportdownload/v201109. Your POST request needs to include the following headers:

  • Authorization - A standard Google Accounts login token obtained from the ClientLogin service.
  • clientCustomerId - The numerical ID of the account for which the report is being produced: For example, “123-456-7890”.

Here's some example PHP code that uses cURL to get an authToken from the ClientLogin API:

<?php
 
// Account login details
$username = "[email protected]";
$password = "pa55word";
$customerId = "123-456-7890";
 
// Get an access code for the user
$url = "https://www.google.com/accounts/ClientLogin";
$params = array(
    "accountType" => "GOOGLE",
    "Email" => $username,
    "Passwd" => $password,
    "service" => "adwords",
    "source" => "test"
);
 
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$curlData = curl_exec($curl);
curl_close($curl);
 
// Parse the response
$curlData = explode("\n", $curlData);
$return = array();
foreach ($curlData as $value) {
    $value = explode("=", $value, 2);
    if (count($value) > 1) {
        $return[$value[0]] = $value[1];
    }
}
// Extract the access token
$authToken = $return["Auth"];
?>
Requesting Access to the AdWords API

Once you've got your token it needs to be placed into the Authorization header along with the clientCustomerId:

<?php
$httpHeaders = array(
    "Authorization: GoogleLogin auth=$authToken",
    "clientCustomerId: $customerId"
);
?>
AdWords API Report Authorization Header

Your ReportDefinition needs to be sent in the __rdxml parameter:

<?php
$reportDefinition = "<reportDefinition>";
$reportDefinition .= "<selector>";
$reportDefinition .= "<fields>Id</fields>";
$reportDefinition .= "<fields>Date</fields>";
$reportDefinition .= "<fields>AdGroupId</fields>";
$reportDefinition .= "<fields>Impressions</fields>";
$reportDefinition .= "<fields>Clicks</fields>";
$reportDefinition .= "<fields>Cost</fields>";
$reportDefinition .= "<fields>Conversions</fields>";
$reportDefinition .= "<fields>ConversionValue</fields>";
$reportDefinition .= "<fields>AveragePosition</fields>";
$reportDefinition .= "<dateRange>";
$reportDefinition .= "<min>20110712</min>";
$reportDefinition .= "<max>20111010</max>";
$reportDefinition .= "</dateRange>";
$reportDefinition .= "</selector>";
$reportDefinition .= "<reportName>Ad Performance Report</reportName>";
$reportDefinition .= "<reportType>AD_PERFORMANCE_REPORT</reportType>";
$reportDefinition .= "<dateRangeType>CUSTOM_DATE</dateRangeType>";
$reportDefinition .= "<downloadFormat>CSV</downloadFormat>";
$reportDefinition .= "</reportDefinition>";
 
$params = array("__rdxml" => $reportDefinition);
?>
Report Definition XML

Now we can send this off and should get our report back:

<?php
$url = "https://adwords.google.com/api/adwords/reportdownload/v201109";
 
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_HTTPHEADER, $httpHeaders);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$reportData = curl_exec($curl);
curl_close($curl);
 
print "$reportData\n";
?>
Retrieving the Report from the API

← Google and Its Quality Score Rules Using OAuth with the AdWords API →

To help me decide what to write about, I'd like to asses the value of my blog posts to see which ones people find most beneficial. If you found the information here useful then could you please +1 it, but if you didn't find what you were looking for then please leave a comment and I'll be happy to help where I can. Thanks!

Comments

I'm keen to get feedback on my posts, so if you have any questions or comments, then please send me a message and I'll be happy to help.

Steffen

Works like a charm. First straight forward tutorial, and no need to hassle with the PHP Library for a simple Report Download. Thanks a lot.

Reply

Ah joy... well, as I posted here, I will post my solution. Much to my (non)dismay, I was unaware of a simple fact.

...was not able to authenticate off of my /localhost/

Reply

Sorry for the spam, but further to this... My account credentials should be fine? When I use them with the php library and set them in the auth.ini file, I do not have any problems authenticating. I'm trying to specifically not use the library for my purposes.

Reply

Additionally:

Q.) I'm a bit confused about "source" => "test" ...what exactly is this for, what are the potential options?

Q.) auth=$authToken? ...I thought all that was needed was a Developer token?

Thanks ahead of time.

Reply

This always seems to give me a: "Undefined index: Auth" error

Reply

I get the error :

!!!2|||-1|||[ReportDefinitionError.CUSTOMER_SERVING_TYPE_REPORT_MISMATCH @ selector]???

Also the docs here : http://code.google.com/apis/adwords/docs/reportingtopics.html mention that we need to provide a developerToken in http headers. Is it compulsary ?

Regards Silver

Reply

Ewan

Hi Silver,

Sorry for the delay in replying. The error means that the type of report you're trying to download isn't valid; what value have you got in the <reportType> tag?

The developer token wasn't originally required, but it will be compulsory eventually; the current deadline is for the 29th of November, but I heard there was a possibility that might be delayed. It's a pretty small change anyway: Just add something like, "developerToken: $developerToken", to the $httpHeaders array in the example code above. Or, an easier thing to do would be to just use the AdWords API Client Library; it's been updated to include reporting since I wrote this post, and will deal with the token header for you when you create the user object.

Reply