Say hello to your new one-stop shop for ads developer news

Monday, November 21, 2011 | 9:13 AM

Labels:

When we originally launched this blog earlier this year, we sought to provide you with the most up-to-date information on the AdSense APIs, as well as useful resources to help with API development. Recently, we've realized that the content we produce can be shared between multiple Ads API developer communities and for this reason we have decided to create one central blog. With this in mind, we'll now be posting on the new Google Ads Developer blog. There, you'll also find information on our AdWords API, DoubleClick for Advertisers API, DoubleClick for Publishers API, and Google AdMob SDK products.

If you're a subscriber of this blog, your feed will automatically be redirected, so you won't have to do a thing to keep getting the latest news. If you decide you'd like to subscribe to a particular label on the new blog (for example, only receive those posts labeled as "adsense_api"), you can choose to do that as well. Also, the old content of this blog is not going anywhere and will continue to be available, even after we switch to the new blog.

The Ads Developer blog will continue to be run by the same team, bringing you all the information you need as an ads developer. We look forward to seeing you over at http://googleadsdeveloper.blogspot.com/.

Posted by the AdSense API Team

AdSense Management API: Diving into Reports

Tuesday, November 8, 2011 | 9:35 AM

Labels: , ,

The most significant feature in v1 of the AdSense Management API is the ability to run reports on your AdSense account: you've got the full functionality of AdSense reports at your disposal to use directly from your software.

While this is an extremely powerful tool, it brings with it a certain complexity that may make it tricky to figure out how to configure your first report. Fear not! This blog post will help you make sense of the different concepts involved in reporting, as well as how to put them together to get the report you need.


Dates

First things first. You need to indicate both a start and an end date with your report, so that you can tell AdSense what period of data to look at. The date range is inclusive of start and end dates, data outside this range will naturally be excluded.

Simple enough? Great, let's move on to the interesting stuff!


Dimensions and metrics

AdSense Management API reports have two main concepts which you'll find across many reporting systems: dimensions and metrics.

Dimensions are the categories or groups that you're reporting across. They define how you group your data and how you organise your report. For example, you may want to track your account performance over time (with dimensions such as DATE, WEEK, and MONTH), across countries (COUNTRY_CODE, COUNTRY_NAME) or across different AdSense products (PRODUCT_CODE, PRODUCT_NAME).

Metrics, on the other hand, represent the values you're measuring. You can measure your account performance by looking at your earnings (EARNINGS), number of clicks (CLICKS), number of page views (PAGE_VIEWS), and so on.

You can use multiple dimensions and metrics in a single report; multiple dimensions represent different groups and subgroups, whereas multiple metrics simply represent different "columns" or values you're measuring.

You'll find the full list of supported dimensions and metrics in the Reports reference.


Filters

Filters allow you to select a subset of data on which to base your report. They're a separate layer of control that restricts the data being processed before it's grouped by the dimensions or measured by the metrics you choose.

You can filter on any dimension with an exact (==) or substring (=@) match. So if you wanted your report data to be limited to earnings from the US, you could set your filter to COUNTRY_CODE==US, whereas if you wanted to limit the data to any country with "United" as part of its name, you could use COUNTRY_NAME=@United.

You can combine multiple filters by using boolean logic with OR and AND operations. Take a look at the relevant section in the filters documentation for more details on that.


A few examples

One of the most common reports would be your monthly earnings for the current year:

start date: 2011-01-01
end date: 2011-12-31
dimensions: MONTH
metrics: EARNINGS
filters: (none)
{
  "totalMatchedRows": "12",
  "headers": [ (...) ],
  "rows": [
    ["2011-01", "41"],
    ["2011-02", "43"],
    (...)
    ["2011-12", "42"]
  ],
  "totals": ["", "504"],
  "averages": ["", "42"]
}

You can add further metrics to track other areas of account performance, such as page views:

start date: 2011-01-01
end date: 2011-12-31
dimensions: MONTH
metrics: EARNINGS, PAGE_VIEWS
filters: (none)
{
  "totalMatchedRows": "12",
  "headers": [ (...) ],
  "rows": [
    ["2011-01", "41", "750"],
    ["2011-02", "43", "760"],
    (...)
    ["2011-12", "42", "755"]
  ],
  "totals": ["", "504", "9000"],
  "averages": ["", "42", "750"]
}

Of course, you may only be interested in the data for your US audience. Note that country code data only started being collected earlier this year, so we'll move the start date forward a bit:
start date: 2011-05-01
end date: 2011-12-31
dimensions: MONTH
metrics: EARNINGS, PAGE_VIEWS
filters: COUNTRY_CODE==US
{
  "totalMatchedRows": "8",
  "headers": [ (...) ],
  "rows": [
    ["2011-05", "21", "375"],
    ["2011-06", "23", "380"],
    (...)
    ["2011-12", "22", "370"]
  ],
  "totals": ["", "176", "3000"],
  "averages": ["", "22", "375"]
}

Or you may want your data to be broken down by country, instead of restricting it to the US:

start date: 2011-05-01
end date: 2011-12-31
dimensions: MONTH, COUNTRY_CODE
metrics: EARNINGS, PAGE_VIEWS
filters: (none)
{
  "totalMatchedRows": "24",
  "headers": [ (...) ],
  "rows": [
    ["2011-05", "US", "21", "375"],
    ["2011-05", "FR", "10", "180"],
    ["2011-05", "JP", "11", "190"],
    ["2011-06", "US", "23", "380"],
    (...)
    ["2011-12", "US", "22", "370"]
  ],
  "totals": ["", "", "350", "6000"],
  "averages": ["", "", "42", "750"]
}

Finally, you may just decide to look at your historical data to see which countries get you the most revenue, so you can choose which audiences to focus on:

start date: 2011-05-01
end date: 2011-12-31
dimensions: COUNTRY_CODE
metrics: EARNINGS
filters: (none)
{
  "totalMatchedRows": "3",
  "headers": [ (...) ],
  "rows": [
    ["US", "175"],
    ["FR", "88"],
    ["JP", "87"]
  ],
  "totals": ["", "350"],
  "averages": ["", "116.67"]
}


Your data, your reports

Ultimately, we can't predict which reports will be the most useful to you, or how you will use AdSense performance data in your applications. Instead, we hope to have made our reporting flexible and adaptable enough that you can get the data you need no matter what you're looking for.

And of course, if you can't figure out how to get that report with exactly the data you were hoping for, come talk to us in the forums, and we'll give you a hand!


AdSense Management API: OAuth 2.0 for native applications

Thursday, November 3, 2011 | 6:22 AM

Labels: , , ,

Following our previous post on OAuth 2.0 for web applications, we are now taking a look at how to use the OAuth 2.0 authentication protocol for native applications, presenting examples for the languages that we are supporting at the moment of writing: Java and Python.


Background

We strongly recommend reading Using OAuth 2.0 to Access Google APIs to learn about the Google implementations of OAuth 2.0 before proceeding with this post.


Java

The Google APIs Client Library for Java features a powerful and easy to use OAuth 2.0 library. We can take advantage of the existing GoogleOAuth2ThreeLeggedFlow helper class to easily perform our authentication flow.

First create an instance of GoogleOAuth2ThreeLeggedFlow, passing the following parameters to the constructor:

  • a key that will be used to associate this flow object with an end user
  • the Client ID for your application
  • the Client Secret for your application
  • the scope you are requesting access to (AdSense in your case)
  • the URI to redirect to
GoogleOAuth2ThreeLeggedFlow authFlow = new GoogleOAuth2ThreeLeggedFlow(
  userId, 
  "INSERT_CLIENT_ID_HERE", 
  "INSERT_CLIENT_SECRET_HERE", 
  "https://www.googleapis.com/auth/adsense.readonly", 
  "urn:ietf:wg:oauth:2.0:oob");

For native applications, we use a special redirect URI:
"urn:ietf:wg:oauth:2.0:oob"

The "oob" part stands for "out of band" and the rest of the string identifies it as a part of the OAuth 2.0 standard.
When we use this redirect URI, instead of redirecting the user's browser to a page on our site with an authorization code, Google will display a page and the authorization code or error response in the title of the page. A text field contained in the page will show instructions for the user to copy and paste it into our application.

To start the flow, let’s ask the user to load the authorization URL in their browser:
System.out.println(“Please go to “ + authFlow.getAuthorizationUrl());

The user will perform their authentication, after that it’s time to ask them to input the authorization code that they got from the authorization server and read that code:
System.out.println(“Please input authorization code: ”);
Scanner in = new Scanner(System.in);
String authorizationCode = in.nextLine();

The last step is to use the authorization code to obtain an access token.
First you’ll need to initialize a transport for communication with the Authorization server and a factory for handling JSON, as the access token will be returned as a JSON object:
JsonFactory factory = new JacksonFactory();
HttpTransport transport = new NetHttpTransport();
authFlow.setHttpTransport(transport);
authFlow.setJsonFactory(factory);

Now you can finalize the authentication flow by obtaining credentials for your user, and then use those credentials to create the Adsense helper object and then send your signed requests to the API:
Credential credential = authFlow.complete(authorizationCode);
Adsense adsense = new Adsense(transport, credential, factory);
AdClients adClients = adsense.adclients.list().execute();


Python

The home of the Google APIs Client Library for Python is also the home of OAuth2Client, a library designed for connecting to resources protected by OAuth 2.0.

First create an OAuth2WebServerFlow object, passing the following parameters to the constructor:
  • the Client ID for your application
  • the Client Secret for your application
  • the scope you are requesting access to (AdSense in your case)
  • an HTTP User-Agent to identify this application
flow = OAuth2WebServerFlow(
  client_id='INSERT_CLIENT_ID_HERE',
  client_secret='INSERT_CLIENT_SECRET_HERE',
  scope='https://www.googleapis.com/auth/adsense.readonly',
  user_agent='your-beautiful-python-app/1.0')

We can perform the authentication calling the ‘run’ function imported from oauth2client.tools, storing the authentication data using a Storage object:
storage = Storage(‘adsense.dat’);
credentials = run(flow, storage);

If the flag ‘auth_local_webserver’ is raised (the default setting), oauth2client.tools will open the authentication URL on a running browser or on the system default browser. After the user performs the authentication, the authorization code will be read from the title of the page shown in the browser. If you don’t want this behaviour, you can disable it like this:
import gflags
gflags.FLAGS.auth_local_webserver = False

In this way we’ll have a flow similar to the one that we have seen in Java: the user will be asked to open the authentication URL in a browser window and then to copy and paste the authorization code back in the application. The only difference is that oauth2client.tools will take care of printing these messages and read the input from the user for us.

The last step is create an httplib2.Http object, authorize it with the previously obtained credentials and then send a request to the API:
http = httplib2.Http()
http = credentials.authorize(http)
service = build(‘adsense’, ‘v1’, http=http)
result = service.adclients().list().execute()


Cool! But I want to know more!

In this post we have seen examples of how to authenticate your native application using the Google implementation of the OAuth 2.0 protocol and the libraries that we are providing to simplify all of the tasks involved.

Now that we know how to perform authentication for both web and native applications, in my next post we are going to see different ways of storing the authentication data.
Stay tuned, and visit our forum if you have any additional question or topic that you would like to discuss!

AdSense Management API: OAuth 2.0 for web applications

Tuesday, November 1, 2011 | 5:32 AM

Labels: , , ,

Following the launch of our new AdSense Management API we want to shed some light on the OAuth 2.0 authentication protocol for web applications, presenting examples for the languages that we are supporting at the moment of writing: Java, Python and PHP.


Background

We strongly recommend reading Using OAuth 2.0 to Access Google APIs to learn about the Google implementations of OAuth 2.0 before proceeding with this post.


Java

The Google APIs Client Library for Java features a powerful and easy to use OAuth 2.0 library.
Using the library is even easier with the GoogleOAuth2ThreeLeggedFlow helper class.

First create an instance of GoogleOAuth2ThreeLeggedFlow, passing the following parameters to the constructor:

  • a key that will be used to associate this flow object with an end user
  • the Client ID for your application
  • the Client Secret for your application
  • the scope you are requesting access to (AdSense in your case)
  • the callback URL where the user should be redirected to in order to complete the flow
GoogleOAuth2ThreeLeggedFlow authFlow = new GoogleOAuth2ThreeLeggedFlow(
  userId,
  "INSERT_CLIENT_ID_HERE", 
  "INSERT_CLIENT_SECRET_HERE", 
  "https://www.googleapis.com/auth/adsense.readonly", 
  "http://example.com/path/to/auth_return");

To start the flow, get the authorization URL and redirect the user there:
String authUrl = authFlow.getAuthorizationUrl();
response.sendRedirect(authUrl);

If the user grants your application permission to access their data, they will be redirected to your callback URL and you’ll need to parse the authorization code from the request:
String authorizationCode = request.getParameter("code");

The last step is to use the authorization code to obtain an access token.
First you’ll need to initialize a transport for communication with the Authorization server and a factory for handling JSON, as the access token will be returned as a JSON object:
JsonFactory factory = new JacksonFactory();
HttpTransport transport = new NetHttpTransport();
authFlow.setHttpTransport(transport);
authFlow.setJsonFactory(factory);

Now you can finalize the authentication flow by obtaining credentials for your user, using those credentials to create the Adsense helper object and then sending your signed requests to the API:
Credential credential = authFlow.complete(authorizationCode);
Adsense adsense = new Adsense(transport, credential, factory);
AdClients adClients = adsense.adclients.list().execute();


Python

The home of the Google APIs Client Library for Python is also the home of OAuth2Client, a library designed for connecting to resources protected by OAuth 2.0.

First create an OAuth2WebServerFlow object, passing the following parameters to the constructor:
  • the Client ID for your application
  • the Client Secret for your application
  • the scope you are requesting access to (AdSense in your case)
  • an HTTP User-Agent to identify this application
flow = OAuth2WebServerFlow(
  client_id='INSERT_CLIENT_ID_HERE',
  client_secret='INSERT_CLIENT_SECRET_HERE',
  scope='https://www.googleapis.com/auth/adsense.readonly',
  user_agent='your-beautiful-python-app/1.0')

Now to start the flow you need to redirect the user to the Authorization URL, providing a callback URL where Google will send the authorization code. You will also need to serialize your flow object somewhere, as we will need to access it again after the redirection to the callback URL:
# in a multiuser environment, associate it to a specific user
# local to your application
store_flow(pickle.dumps(flow))
callback = 'http://example.com/path/to/auth_return'
authorize_url = flow.step1_get_authorize_url(callback)
request_handler.redirect(callback)

Back from the redirect, retrieve your OAuth2WebServerFlow object and proceed to step2, where the authorization code will be parsed from the request and used to request an access token:
flow = pickle.loads(retrieve_flow)
credentials = flow.step2_exchange(self.request.params)

Now you can create an an Http object and use the credentials to authorize it:
http = httplib2.Http()
http = credentials.authorize(http)

Now that your Http object is authorized, instantiate a service wrapper for the AdSense Management API and start querying the API:
service = build("adsense", "v1", http=http)
result = service.adclients().list().execute()


PHP

The Google APIs Client Library for PHP enables PHP developers to work with Google APIs such as the AdSense Management API.
The apiOAuth2 class implements the OAuth 2.0 web-server authentication flow for the PHP language.

To handle the OAuth2 web-server authentication flow in PHP you need to require the source for the apiClient and the source for the service class of the API that you are targeting, create and configure the apiClient for the authentication and then create the Adsense service:
require_once '../../src/apiClient.php';
require_once '../../src/contrib/apiAdsenseService.php';

$client = new apiClient();

// Visit https://code.google.com/apis/console to
// generate your oauth2_client_id, oauth2_client_secret, and to
// register your oauth2_redirect_uri.
$client->setClientId('YOUR CLIENT ID HERE');
$client->setClientSecret('YOUR CLIENT SECRET HERE');
$client->setDeveloperKey('YOUR_DEVELOPER_KEY_HERE');

// The oauth2_redirect_uri is typically the path 
// to where you host this PHP file.
$this->client->setRedirectUri(‘YOUR_REDIRECT_URI_HERE’);

$adSense = new apiAdsenseService($client);
$client->setScopes(
  array("https://www.googleapis.com/auth/adsense.readonly"));

Call ‘authenticate’ on the client to start the authentication flow. If the user is not yet authenticated, the application will receive an authorization code as GET parameter, and this will then be used by the client to request an access token, returned by authenticate.
All in this simple call:
$client->setAccessToken($client->authenticate());

And there is more. What happens when the access token expires? Nothing that you can perceive. The API client will use the refresh token to request a new access token for you, and you won’t even notice.

Once we are authorized, querying the AdSense Management API is simple as:
$result = $adSense->adclients->listAllAdclients();


That’s all folks! For now...

In this post we have seen examples of how to authenticate your web applications using the Google implementation of the OAuth 2.0 protocol and the libraries that we are providing to simplify all of the tasks involved.
But it’s not all, stay tuned to our blog: in the upcoming posts we will see how to authenticate with OAuth 2.0 using native applications and how to avoid repeated authorization requests for your users, in multi user environments.

If you have any questions about this or other topics, don't hesitate to visit our forum.

AdSense Management API: a primer

Thursday, October 27, 2011 | 5:57 AM

Labels: ,

Earlier this week, we launched the AdSense Management API, a new API open to all AdSense publishers. Today, we'd like to provide you with a few more details on what it can do and how you can use it.


Functionality

The main feature of the Management API, and the one we've had requests for most often, is the ability to run reports. The API provides the full set of AdSense reporting functionality available in the AdSense interface, with a wide array of dimensions and metrics, configurable sorting, and powerful filters. For more details, check the reports.generate method reference.

In addition to reporting, you can also list your inventory, namely your ad clients (the different AdSense products your account is subscribed to), ad units and channels (both URL and custom).

We'll be expanding AdSense Management API functionality in the future, so keep an eye on this blog.


Technology

The new API is based on Google's latest API technology, which means you'll get the same benefits that newer Google APIs provide. These include generic client libraries for major programming languages, OAuth and OAuth 2.0 authentication support, and the APIs explorer.

In addition, since this is a RESTful API based entirely on open standards, you should be able to use it in just about every development environment, as long as you can make HTTP requests!


Getting started

If you're a Java, Python or PHP developer, you should take a look at our guide for using the client libraries. The guide lists all you need to know if you're starting from scratch, guiding you from downloading the client library to obtaining a performance report. The sample code pages for these three languages will soon contain full samples for each API method.

If you want to use other client libraries or skip the client libraries altogether and use the API directly, the getting started guide explains the basics of the AdSense Management API, including the AdSense terminology being used, the URL structure and the calling style. The reference provides details for all of the available methods, their parameters and returns.


More to come

Over the coming weeks, we'll be writing some more in-depth blog posts exploring the AdSense Management API. We'll be focusing on the more complex topics of API usage, such as how to perform authentication, how to persist credential data, and the details in running reports.

In the meantime, feel free to use the forum!


New and updated

Tuesday, October 25, 2011 | 1:56 AM

Labels: , ,

Today, we're thrilled to announce the updated AdSense APIs home page, the release of the AdSense Management API, and the renaming of the existing API.

We've regularly heard that publishers want to obtain their AdSense performance reports programmatically. While this was already possible for our host partners, other AdSense publishers could only monitor their earnings through their AdSense accounts. So, we're launching a new RESTful API based on the latest Google technology that will be available to all AdSense publishers. Among its capabilities are the ability to list the products you're using, and run reports on your ad units and channels. Keep an eye on this space, as we'll be expanding the new API's functionality over the coming months.

We're also renaming the existing API to AdSense Host API, to make it clear that it's only targeted at our host partners. For existing AdSense host partners using the Host API, nothing changes except the name - your code remains the same and no action is required on your part.

Be sure to check back with this blog over the next few days, as we'll be posting some introductory content on using the new AdSense Management API.

Happy coding!


AdSense API from Scratch Part 3 - Generating and Managing Ad Code

Thursday, June 30, 2011 | 8:54 AM

Labels: , ,

This is the third and final post in the “AdSense API from Scratch” series, where we take a look at how to develop a full AdSense API implementation, using best practices, in PHP 5.

In Part 1, we looked at how to get started with development, and made our first createAccount call. In Part 2, we dealt with error handling and account associations. This time, we’ll look at how to generate ad code, and the best practices to follow when doing so.


Generating ad code

For the first time in this guide, we’re accessing a service other than the AccountService, namely the AdSenseForContentService, so we need to provide a different WSDL location. Note that this also applies to the AdSenseForSearchService, but we’re using AdSense for Content (AFC) as an example.

$wsdl = 'https://sandbox.google.com/api/adsense/v3/' +
    'AdSenseForContentService?wsdl';

// Get AdSenseForContentService.
$afcService = new SoapClient($wsdl, $options);


We’re also performing an operation on a publisher account, instead of simply creating or associating with one. We thus need to specify which account to work with, via the client_id header:

$client_id = 'ca-pub-xxxxxxxxxxxxxxxx';
$client_id_header = new SoapHeader($namespace, 'client_id', $client_id);
$afcService->__setSoapHeaders(array($developer_email_header,
$developer_password_header, $display_locale_header, $client_id_header));


The client ID is more commonly known as the publisher ID, and in the case of AFC, is of the form ca-pub-xxxxxxxxxxxxxxxx.

After this, it’s a matter of passing in our ad unit preferences:

$result = $afcService->generateAdCode(array(
    'synServiceId' => 'ca-pub-xxxxxxxxxxxxxxxx',
    'adStyle' => array(
        'backgroundColor' => '#FFFFFF',
        'borderColor' => '#000000',
        'textColor' => '#00FF00',
        'titleColor' => '#0000CC',
        'urlColor' => '#FF3300'),
    'adUnitType' => array('value' => 'TextOnly'),
    'adLayout' => array('value' => '728x90'),
    'isFramedPage' => false,
    'cornerStyles' => array(
        'value' => 'DEFAULT')));


You can find the full example for this method, including basic error handling, here.


createAccount and generateAdCode

An important step of setting up a new account is generating ad code for it. This is because the generateAdCode method has the side effect of initializing certain features in a new account, particularly when it comes to reporting.

Because of this, we recommend that you run generateAdCode right after createAccount, if possible; you don’t need to wait for the publisher account to be verified and approved. Feel free to discard the generated HTML, as we’re only interested in the side effects!


Changing accounts

If your implementation automatically inserts the ad code into your publishers’ pages, there is one other fact that you need to be aware of, when it comes to ad code generation: ad code generation is static, and the resulting code is tied to the specified publisher account.

This means that if your system gives users the ability to create a new AdSense account (or associate to an existing one) after the initial one, you’ll need to make sure that you regenerate and update all of their ad code, so that ads will be tied to the new account. This is a common mistake many implementations make and something we actively look for in the review process, so save time by thinking about it in advance!


Wrapping up

We’ve gone from an empty text editor to three full examples of how to perform the basic AdSense API host functionality: account creation, account association and ad code generation. I hope you found this series informative, and that it sets you well on your way to coding your own implementation!

For any questions, comments or suggestions, feel free to talk to us in the forum!