A few weeks ago, we caught up with Ben Birt from our AdSense API Engineering team in London. Today, we'd like to introduce you to another member of the team -- Nick Johnson, a Software Engineer who joined Google in May 2011.

What’s your main contribution to API development?
I could tell you... but then I would have to use one of those flashy things from Men in Black on you. (We have those at Google). Then I’d probably have to use it on me. I’m essentially a general purpose code monkey at this point in time, but I have some very cool stuff coming into the pipeline soon.

Describe your average day at work
My average day starts with me grabbing a coffee and some cereal from the kitchen. Aside from our (seated) stand up team meeting, everything else changes on a daily basis. So long as I get to do some coding, I’m generally happy.

What do you like most about the AdSense Management API?
I think the Ad Clients list call is my favourite. It’s less typing, so that makes it pretty ideal for making test calls. In all seriousness though, I think the thing I like best is the potential. The ways in which you can use and combine your data are entirely in your hands now.

We have some pretty cool surprises coming from inside Google (but when is that not true?), but we also can’t wait to see what third party developers create.

Tell us one best practice about the API
Think about what you have, and what you need. Be smart with your calls and make the most of them. Try to multiplex and retrieve as much of the data you need in the least number of calls. You need to balance this with the responsiveness of your app though. Quite obviously more data will take more time.

Another important thing is that if you have any problems or feature suggestions, then by all means, please...
...tell Silvano and Sérgio :) (members of the AdSense API Developer Relations team)

Enough work stuff, let’s go personal. We’ve heard that you lived in Scotland for some years. Is it true that they deep fry everything up there?
I think we both know that science has proven any foodstuff can be improved by submerging it in a large quantity of hot fat. It’s like adding “in space” to the end of a plot description. I did live in the beautiful city of Edinburgh (s’up to my homies on the Morningsi-ide) for ten extremely pleasant years, before I moved down to the big smoke for a job with the big G.

No, it’s not true that the Scottish deep fry everything. It would be far more accurate to say they will deep fry anything. Don’t knock it until you’ve tried it though. Deep fried Mars bars are very real, but I’m afraid I never tried them. I was worried I might like them.

Ok, let me ask you some geeky questions now. I’ve heard that you like functional programming...
Truly, your wit is sharp as a pillow.

Functional programming is something I’m slowly getting my head around, but the biggest barrier (for me, at least) is the attitude of the functional programming evangelists. It’s like talking to someone who thinks Emacs is better than Vim.

I mean, come on.

Since it’s obligatory in these sorts of interviews, why don’t you throw some film and book recommendations our way?
I’m at least as big a film nerd as I am a computer nerd (and I do the latter for a living!), so I could literally talk to you all day about that. If I’m completely honest, the film I saw in 2011 which I enjoyed the most was almost certainly Fast [and Furious] 5, but I’m not sure I’d go so far as to say it’s the best film I saw this year. I will always love The Matrix, Fight Club, Pitch Black and Amélie, and right now I’m really quite excited about Joss Whedon(!)’s The Avengers.

If I had to recommend one book it would probably be either The Hitchhiker’s Guide to the Galaxy, or Neal Stephenson’s Cryptonomicon (though that is really not a light read, in any sense of the word). Recently I read, and loved, “The Alloy of Law”, Brandon Sanderson’s follow up to his brilliant Mistborn trilogy, so I think I’ll also have to recommend those books.

Will you fix my computer?

Fine. Will you code my favorite API?
I’m on it.


The AdWhirl SDK provides a framework that allows developers to display banner ads from different ad networks in their iOS and Android applications. You simply tell AdWhirl what ad networks you want to use and the percentage of requests to allocate to each network, and AdWhirl handles the ad requests. But how do you choose an acceptable refresh rate, and what settings should you use for both AdWhirl and your individual ad networks?

AdWhirl has its own refresh rate; when it comes time to refresh, AdWhirl removes the current network’s ad view, chooses a new ad network, and creates a new ad view for that network. So how is this different from the AdMob refresh rate? Well, the AdMob refresh rate determines when its own ad view will request a new ad.

AdWhirl does not know about the specific ad networks’ refresh rates. Most networks expose the refresh rate on the client side; AdWhirl takes advantage of this by turning off refreshing for these networks. AdMob, however, only supports configuring the refresh rate on the server side. Therefore, AdWhirl must rely on you, the developer, to turn off the network refresh rate. Forgetting to do so may result in unexpected refreshes. This is best demonstrated with an example.

Let’s say AdWhirl has selected the AdMob network for displaying an ad, and your AdMob refresh rate is 29 seconds while your AdWhirl refresh rate is 30 seconds. AdWhirl will load up an AdMob view, and then the AdMob view will request and show an ad. After 29 seconds, AdMob decides it's time to refresh, grabs a new ad on it's own, and displays a new ad. AdWhirl has no idea that AdMob just refreshed. One second later, AdWhirl decides it’s time to refresh (30 seconds have passed), and removes the AdMob view and picks a new ad network from which to show an ad.

In the above example, AdMob displayed a new ad that was shown for only one second--it had virtually no chance of being clicked. This results in extra impressions that reduce your click through rate and confuse your customers. To avoid having AdMob refresh on its own, make sure to turn off automatic refreshing for the AdMob publisher ID you are mediating with!

Please post to the forum for any questions regarding refresh rates. You’re also welcome to attend one of our office hours hangouts.


Perfecting the look of your application is challenging, and incorporating ads into your application requires careful thinking. When using the AdMob SDK with Table Views in iOS, a typical challenge is that ads do not stay docked properly to a certain position on the screen. This blog post outlines a simple solution to this common problem.


Consider a simple application in which a UITableViewController is used to handle a list mechanism. If this is the main top level view in the application, getting the ad to remain docked to the bottom or top of the view while the content scrolls is problematic. This is usually because the ad has been placed inside the Table View.


One way to dock the ad is to encompass the Table View into a container view (e.g. a UIView). This way, instead of inserting the ad into the Table View as a subview, it’s inserted into the encompassing container view (as a sibling of the Table View). Here is an example of the code snippet in the header file:

@interface AdsOutOfTableView : UIViewController  {
 UITableView *tableView_;
 //Other private variables here

@property(nonatomic,retain) IBOutlet UITableView *tableView;

As shown in this example, the GADBannerView is initialized with a frame that has an origin at the bottom of the screen.

Now when the ad is received, it should be added into the container view, and the size of the Table View should be modified accordingly. The height of the Table View's frame cannot be modified directly, but this can be done using an intermediate frame as shown below.

 CGRect tableFrame = tableView_.frame;
 tableFrame.size.height = tableFrame.size.height -

 tableView_.frame = tableFrame;

Now, no matter how much the Table View is scrolled, the GADBannerView stays docked to the bottom of the screen.

Alternatively, keeping the ad docked to the top of the Table View is very similar to the situation shown above. The only difference is that the GADBannerView must be created and drawn at the top of the screen. The resizeTable: method now also has to to shift itself down by the height of the ad:

 CGRect tableFrame = tableView_.frame;

 tableFrame.size.height = tableFrame.size.height -
 tableFrame.origin.y = bannerView_.frame.size.height;
 tableView_.frame = tableFrame;

With those minor tweaks, you will have ads set up correctly alongside your Table View! If you have any questions about this or any other SDK topics, feel free to post them in our forum.


We are excited to start discussing how to use the DFP API from within the Google App Engine (Java) environment. This first blog post in the series focuses on setting up your environment and understanding how to use the API from App Engine. Future posts in this series will build upon the same project to create a sample application. Ultimately, you will be able to make DFP information more accessible within your organization, while also leveraging the ease of scale and deployability that comes with creating applications on Google App Engine.

Setting up your environment

For simplicity sake we will focus on utilizing Eclipse and the Google App Engine Plugin available for Eclipse. Information about setting them up can be found here. If you prefer a different environment setup, you can always view the Getting Started Guide for App Engine for more information.

Create an App Engine project

You’ll need a place to do your coding so create an App Engine project in a similar manner to the screenshots below.

Note: If you would like to download all of the source code in this blog post to follow along you can do so as a tarball or you can browse the code base from our svn repository.


The App Engine Java environment requires JAX-WS when dealing with SOAP interfaces like DFP API so you won’t be able to use the normal Java client library. You’ll need to download this client login auth file to help with authentication. Place this file in your project’s src directory. Next, you’ll need a jar and a wsdl file that we’ve compiled with JAX-WS; place them in the WEB-INF/lib and WEB-INF directory, respectively. See the files highlighted in their respective locations below.

Write some code

Now that you’re set up, it’s time to write some code that uses the DFP API. This first snippet of code performs some setup for your App Engine Servlet.

   * Perform initialization of servlet and cached resources used to
   * access DFP API.
  public void init(ServletConfig config) throws ServletException {

    // Generate an authToken.
    try {
      authToken = regenerateAuthToken();
    } catch (Exception exception) {
      throw new ServletException("Could not generate an Auth Token.",

   * Regenerate the client login auth token that the servlet uses.
   * @throws Exception
  public synchronized String regenerateAuthToken() throws Exception {
    ClientLoginAuth clientLoginAuth = new ClientLoginAuth(EMAIL_ADDRESS, 
    return clientLoginAuth.getAuthToken();

This next snippet of code handles the actual web browser requests.

  public void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException {
    try {
      // Retrieve an object handle to our network service.
      NetworkService networkService = new NetworkService();
      NetworkServiceInterface networkServiceInterface =

      // Prepare header object to make server call
      SoapRequestHeader requestHeader = new SoapRequestHeader();
      requestHeader.setApplicationName("Hello World");
      ClientLogin clientLogin = new ClientLogin();

      // Make protected call to the server.
      String rootAdUnitId = "";
      Network currentNetwork = networkServiceInterface.getCurrentNetwork(
          requestHeader, null);
      // Extract data from object returned from server.
      rootAdUnitId = currentNetwork.getEffectiveRootAdUnitId();

      resp.getWriter().println("Hello, world. Your root ad unit id is: "
          + rootAdUnitId);
    } catch (Exception e) {
      // Perform exception handling.
      throw new ServletException("Error occurred. Check logs for specific "
          " details about the error.");

This particular code snippet retrieves the root ad unit for our network whenever someone accesses the application. You can view the full sample servlet code here.


To make sure your code works, let’s deploy the project locally. Right-click on your project and then choose “Run” and select the “Web Application” option from the submenu. This will deploy your code to a locally running App Engine server. The console will display the URL to access the application (usually http://localhost:8888/). Clicking on this link and then the subsequent servlet link should return a page similar to this.

Next Time

Next time, we’ll extend the project to do some background processing and start using some other services from the DFP API.


We really hope you didn’t have an issue, but if you did there is a troubleshooting README file included in the sample code.

Let us know if you have any questions, and happy holidays!

Editor’s note: As many of you are planning your 2012 advertisement strategy, we’d like to share with you this post from Karim Temsamani. It’s a look back on 2011 and provides a great perspective on how mobile really took a step forward in the advertising ecosystem. -- Stan Grinberg, Ads Developer Relations Team

Mobile turned a corner this year. As smartphones and tablets became a part of our everyday lives, business owners’ conversations shifted from 'Why should I advertise on mobile or build a mobile website?' to 'How do I get started?’.

Five major industry trends emerged in 2011 that will carry us into 2012, and beyond.

1 - Everyone goes mobile
Smartphones and tablets proved that they weren’t just for the geekiest - er, ‘tech savviest’ - among us. These devices are increasingly becoming the norm and they continue to change how people connect with each other, and with businesses, everywhere. According to our research with IPSOS earlier this year:

  • 79% of smartphone consumers use their phones to help with shopping, from comparing prices, to finding more product info, to locating a retailer.
  • 70% use their smartphones while in a store.
  • 77% have contacted a business via mobile, with 61% calling and 59% visiting the local business.
It’s not just that more people are using smartphones and tablets (though the numbers are skyrocketing at an accelerating pace)—it’s that a huge, and fast-growing base of smartphone users, now expect to engage with businesses on mobile. The mainstream consumer got mobilized in 2011.

2 - Mobile search transforms shopping, forever
Analyzing mobile search trends helped the industry better understand how people were using their mobile devices in 2011. For starters, we learned a lot about the ‘timing’ of mobile and tablets. These devices enable us to be constantly connected to the internet, as mobile usage has proven to be complementary to the desktop. We got a clearer picture of how search is changing the ways we shop and connect with businesses. More people are looking for deals both en route to stores and within them on mobile - in the retail category, “Black Friday” related mobile queries were over 200% higher this year than in 2010. Users have also developed some mobile-specific shopping habits - for example, 44% of all searches for last minute gifts and store locator terms are projected to come from mobile devices this holiday season. For procrastinators, mobile has come to the rescue!

In October, we looked at some of the newest ways marketers can build their businesses via mobile search. But, this is only the beginning - whether people are trying to find or call a business, compare prices in a store, or visit a site or app directly from their phones, search and search ads will be the tools that shape a new shopping experience, enabling us connect with businesses, research and buy products on or offline, all via mobile.

3 - Progress with the mobile advertising pipes
As an industry, we came a long way in terms of improving the ‘pipes’ - the systems, products and technologies that advertisers use to build, serve, and measure mobile ads. It’s still early days, but the progress with standards like MRAID and the momentum behind HTML5, are helping to rally the mobile community and make it easier for marketers and customers to connect on the platform. Getting existing tools to ‘speak mobile’ has been another key to helping mobile advertising grow-up as quickly users and businesses want it to. Across search and display, the tools the industry is already familiar with are getting mobilized. There’s plenty of work still to do, but significant progress is being made - watch this space in 2012.

4 - Tablets join the mobile party
Tablets made quite a splash this year. Usage trends sharpened - we’re seeing that people people use these devices to shop, consume media, have fun, and they do so most frequently in the evenings. Tablets are a third screen to be reckoned with for marketers - we saw a 440% growth in traffic from tablets in November 2011 compared to December 2010 on the AdMob network. The business potential is tremendous: not only are users more inclined to shop and make purchases on tablets, but because campaigns can be more effective running across several screens instead of one, tablets offer an incremental opportunity for marketers. Our research with Nielsen showed that campaigns on several screens can be ‘Better Together’ - indeed, in cases like Adidas’, that proved to be true.

5 - Businesses start (actually) thinking mobile first
Smartphones and tablets aren’t small desktop computers - they’re new devices being used in entirely new ways. This year, businesses began to embrace this at scale and many saw good things happen when they built ad campaigns and websites specifically for mobile. Ticketsnow’s success with a mobile optimized site - increased site traffic, and more ticket sales - is just one example of the benefits of building for mobile. Initiatives like GoMo and platform-specific ad features will help businesses better connect with mobile customers in the coming months, and beyond.

It’s hard to believe, but as far as the industry has come in 2011, we’re still in the earliest chapters of mobile’s story. The ways people connect to businesses on their mobile devices and the tools they’re using to connect from them progressed by leaps and bounds this year and soon, we’ll see the mainstream shift that changes the way mobile connects people with brick-and-mortar storefronts as well. Mobile will be moving full speed ahead in 2012 so keep those sleeves rolled-up and those seatbelts fastened - we’ll see you then.

Posted by: Karim Temsamani, VP Mobile Ads


Adding animations to banner ads can provide a nice touch to how the ad transitions onto the screen. This blog post will show you how to animate an AdMob banner on iOS.

We will specifically focus on block-based animation methods which were introduced in iOS 4. If you’re using an older version of iOS, you can achieve the same effect using the beginAnimations:context: and commitAnimations: class methods in UIView.

Sliding a banner up onto the screen

The key to animating banners is changing one of the animatable properties in UIView across a certain period of time. iOS will then choose how to animate the AdMob banner across this specified time using its internal logic along with any options that have been specified. Let’s look at how to animate a banner to slide up onto the application’s screen.

First, the AdMob banner is initialized with a frame outside of the bounds of the screen (specifically underneath the bottom of the screen). Once the ad is received, it can be animated upwards through its height. Since the banner is sliding up and onto the screen, only the y-coordinate will change during animation. The code for initializing the banner is shown below.

// Initialize the banner off of the screen
self.adBanner = [[[GADBannerView alloc]    
                           GAD_SIZE_320x50.height)] autorelease];

The next step is to implement adViewDidReceiveAd: to set the final frame for the AdMob banner and tell iOS to animate across the two values using the animateWithDuration:animations: method.

- (void)adViewDidReceiveAd:(GADBannerView *)adView {

  [UIView animateWithDuration:1.0 animations:^ {
    // Final frame of ad should be docked to bottom of screen
    adView.frame = CGRectMake(0.0,
                              self.view.frame.size.height -

It’s as easy as that! Now, instead of instantly appearing on the screen, the banner ad gracefully slides up in the application using animation.

Customized animations

You can experiment with other animatable properties of UIView as well. For example, try sliding the banner onto the screen from left to right by changing the initial frame to the left of the screen instead of beneath it. If you want to get even more creative, try experimenting with the Core Animation classes. These classes give you powerful animation functionality and allow you to customize keyframe and timing functions.

Pro tip: Be thoughtful about where and how you’re going to use animations. It’s easy to go overboard.

If you have any questions about animations on iOS or about the AdMob SDK in general, feel free to post them in our forum. Have fun animating!

In this installment of the Discover DFP API v201111 series, we present new features we’ve added to reports in the API. In addition to merged ad server columns, which helps upgraded publishers reports on both DART and DFP ad servers, you can now use dimension attributes for greater control in reporting.

Dimension Attributes

Dimension attributes let you break down your report by additional fields associated with the dimension. For example, you can now add the trafficker, external ID, and order start date as dimension attributes associated to your order dimension in a delivery report. This is useful if you would like to see how each of your orders is doing and which trafficker was responsible for that order.

In the past, you would get this information by running a report for orders and then looking up the orders with Order Service to inspect the attributes. Now, it’s as simple as adding values to the dimensionAttributes field on your ReportQuery object and the corresponding fields will be integrated into the report. The following code snippet shows you how to create a report job with dimension attributes:
// Create report job.
ReportJob reportJob = new ReportJob();

// Create report query.
ReportQuery reportQuery = new ReportQuery();
reportQuery.setDimensions(new Dimension[] {Dimension.ORDER});

// Set dimension attributes for order dimension.
reportQuery.setDimensionAttributes(new DimensionAttribute[] {

// Set columns to report on.
reportQuery.setColumns(new Column[] {

You can check out the full example in the RunDeliveryReportExample in the Java client library. Notice that you can only add dimension attributes for dimensions that you have in the report. For example, if you tried to add LINE_ITEM_EXTERNAL_ID, and you only have order (but not line item) as a dimension, you will get the following error:


Be sure to check out our updated reporting examples in the client libraries and take a look at our documentation for a full mapping of supported dimension attributes and the fields they represent.

We are always looking for ways to improve the API and we’d love to get your feedback. Let us know what you’d like to see in the API or discussed in a blog post by posting on our forum. We’re also more than happy to chat during one of our office hours hangouts.


We’ve heard some questions recently about the degree that geotargeting is supported through our API. Let’s explore how geotargeting can be managed through the DFA API.

First, here’s a reminder about how geotargeting works in the DoubleClick for Advertisers product. As explained in this help center article (DFA sign-in required), combining multiple locations even if they are within different geographic categories always results in an “OR” relationship between them. Targeting the countries Mexico and the United States alongside the Canadian province of Ontario will cause your ad to be displayed if the impression originates from the United States or Mexico or Ontario.

Let’s see how this example plays out through the API. We need to use the State and Country classes. These classes contain extra fields that are filled in with descriptions when the objects are returned from our server. You only need to fill in the id field when you send us an object that represents a target criterion for an ad. As explained on our best practices page, our ID numbers rarely change and caching them locally is always a good idea. If you have to retrieve them, reference our example code and the ad service documentation.

Once you have the numbers, you can retrieve your ad from our server and add the desired targets. For example, this Python code will add the United States, Mexico, and Ontario as desired targets to an ad:

# Get the ad that needs geotargeting added.
ad = ad_service.GetAd(targetable_ad_id)[0]

# Create and add country targeting criteria.
country_targeting_criteria = {
    'exclude': 'False',
    'countries': [{'id': UNITED_STATES_COUNTRY_ID}, 
                  {'id': MEXICO_COUNTRY_ID}]
ad['countryTargetingCriteria'] = country_targeting_criteria

# Add state targeting. Provinces are considered states.
ad['states'] = [{'id': ONTARIO_STATE_ID}]

# Save changes. This ad now serves only when an impression originates from 
# the United States, Mexico, or Ontario.
ad_save_result = ad_service.SaveAd(ad)[0]

Remember that only ad types that extend TargetableAdBase are targetable. If you run into any problems or have questions about targeting through the API, we’d be glad to help on our forum.

Last month, we announced the ability to create both custom and template creatives using the DFP API. Today we’ll show you can use these premium-only features to create richer creatives with custom HTML.

Custom or template

The difference between custom and template creatives is that custom creatives have their HTML snippet set within them, while template creatives are instantiated from system or user defined HTML snippets. Deciding which one to use depends on your network’s needs. If your network deals primarily with traffickers using the DFP UI, it may be beneficial for them to use creative templates in their workflow. The API could be used to retrieve these templates and report on them, but your traffickers would most likely want to create the creatives from templates in the UI.

However, if you are developing a platform in which traffickers spend most of their day, it may scale better to template the HTML yourself within your content management system (CMS) and use custom creatives for the advertisements. You could store custom HTML snippets and prompt the user for assets to insert. In essence, you would be creating your own templates, but without the overhead of template creatives.

Creating custom creatives

To create a custom creative, you first have to define your HTML snippet:
  String htmlSnippet = "<a href='%%CLICK_URL_UNESC%%%%DEST_URL%%'>"
      + "<img src='%%FILE:IMAGE_ASSET%%'/></a><br>Click for great deals!");
  CustomCreative customCreative = new CustomCreative();
Notice here that the CLICK_URL_UNESC, DEST_URL, and FILE macros are used to customize the creative at serving time. CLICK_URL_UNESC will insert the clickthrough URL while DEST_URL inserts the URL that the ad points to. The FILE macro will reference any attached assets to the creative, in this case one named IMAGE_ASSET.
  // Set the custom creative image asset.
  CustomCreativeAsset customCreativeAsset = new CustomCreativeAsset();
  customCreativeAsset.setAssetByteArray(/* Byte array from image. */);
      String.format("image%s.jpg", System.currentTimeMillis()));
      new CustomCreativeAsset[] {customCreativeAsset});
You would then call CreativeService.createCreative on customCreative to instantiate on the server. After creating the creative, you can then review it using the creative’s previewUrl attribute or the newly added getPreviewUrl method. When updating custom creatives, you don’t need to pass the asset byte array each time. Instead, you can leave it null with assetId set to what it was assigned to when created. The full example can be found on the Java client library page, as well as in our other libraries.

As a final note, custom creatives can be used for many other purposes beyond the simple image ad above. Including a SWF file as an asset, for example, is a common way of creating flash banner ads. You can even include a Google+ +1 button and customize the +1’s destination URL with the DEST_URL macro.

We have a few more posts lined up for the Discover DFP API v201111 series, but if there’s any other topics you’d like to see, please let us know on the forum.

- , DFP API Team


In addition to retrieving performance statistics, AdWords API developers often use the reporting system to get structural information about an account. These reports can be used to quickly synchronize a local database without having to make a series of expensive get() calls to the API. Unlike v13 which had a dedicated Structure Report for this purpose, newer versions of the API support this use case by allowing for zero-impression data to be returned in all of the normal performance reports. Zero-impression rows are simply those that received no impressions over the timespan of the report, which provide little use when calculating performance but are are needed to download the full contents of the account.

In v201109 we added the field ReportDefinition.includeZeroImpressions, which you can use to influence whether or not zero-impression data is included in your report. Setting this field to "false" will remove zero-impression data from your reports, but be aware that setting it to "true" does not guarantee that zero-impression rows will be returned.

Fields that segment the report, such as "Date", "AdNetworkType1", or "ClickType", will prevent zero-impression data from being returned even if includeZeroImpressions is explicitly enabled on the report definition. This is done is to ensure that reports don’t grow too large, as segmentation splits a single row into many. Additionally, in many cases it’s not possible to assign a zero-impression row to one of the segments. For example, there is no ad slot (top vs. other) value that makes sense to assign to a keyword that never had an impression. The "Notes" column of the report types documentation indicates which fields will prevent zero-impression rows from being returned.

Because segmentation and zero-impression rows are not compatible, we recommend that you use one set of reports for downloading the account structure and another set for getting performance statistics. This allows you to get the zero-impression rows you need without sacrificing the powerful insights that segmentation provides. If you have any questions on how to leverage reports in your application, you can reach us on the developer forum or during office hours.

Starting today, the AdSense Management API is available as part of AdSense Services in Google Apps Script. This means that you’ll be able to do things like:
  • Create AdSense performance reports for your AdSense accounts in a Google spreadsheet
  • Create a chart based on your AdSense reporting data and display it in a Google Spreadsheet
  • Embed your scripts in a Google Sites page, for instance to import a chart
  • Use triggers to schedule the execution of your scripts, for instance to periodically update the chart imported in the Google Sites page
Accessing the API from Google Apps Scripts is very easy. The following snippet of code shows how to generate a report and populate columns of a spreadsheet with the data retrieved:
function generateReport() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Reports');
  var startDate = Browser.inputBox(
      "Enter a start date (format: 'yyyy-mm-dd')");
  var endDate = Browser.inputBox(
      "Enter an end date (format: 'yyyy-mm-dd')");
  var args = {
    'dimension': ['MONTH']};
  var report = AdSense.Reports.generate(startDate, endDate, args).getRows();
  for (var i=0; i<report.length; i++) {
    var row = report[i];
    sheet.getRange('A' + String(i+2)).setValue(row[0]);
    sheet.getRange('B' + String(i+2)).setValue(row[1]);
    sheet.getRange('C' + String(i+2)).setValue(row[2]);
    sheet.getRange('D' + String(i+2)).setValue(row[3]);
    sheet.getRange('E' + String(i+2)).setValue(row[4]);
If you want to generate a chart from your data instead of populating the spreadsheet, that’s very easy as well:
function generateLineChart() {
  var doc = SpreadsheetApp.getActiveSpreadsheet();
  var startDate = Browser.inputBox(
      "Enter a start date (format: 'yyyy-mm-dd')");
  var endDate = Browser.inputBox(
      "Enter an end date (format: 'yyyy-mm-dd')");
  var adClientId = Browser.inputBox("Enter an ad client id");
  var args = {
    'filter': ['AD_CLIENT_ID==' + adClientId],
    'dimension': ['MONTH']};
  var report = AdSense.Reports.generate(startDate, endDate, args).getRows();
  var data = Charts.newDataTable()
      .addColumn(Charts.ColumnType.STRING, "Month")
      .addColumn(Charts.ColumnType.NUMBER, "Page views")
      .addColumn(Charts.ColumnType.NUMBER, "Ad requests")
      .addColumn(Charts.ColumnType.NUMBER, "Matched ad requests")
      .addColumn(Charts.ColumnType.NUMBER, "Individual ad impressions");
  // Convert the metrics to numeric values.
  for (var i=0; i<report.length; i++) {
    var row = report[i];
  var chart = Charts.newLineChart()
      .setTitle("Performances per Month")
  var app = UiApp.createApplication().setTitle("Performances");
  var panel = app.createVerticalPanel()
A shiny line chart will be displayed in your spreadsheet, as shown in the following picture:

You can start using the service by checking out the reference documentation, that contains also some sample scripts, and this tutorial that implements the use cases mentioned above.

Happy Google Apps Scripting with the AdSense Management API!

Edit: fixed typo.


Yesterday, the Google Analytics team posted some exciting new enhancements to the Google Analytics SDK:

  • EasyTracking Library - EasyTracker libraries for both iOS and Android enable tracking of your application down to the Activity (or UIViewController for iOS) level with almost no coding required on your part. Additionally, improved integration with the Google Analytics SDK means better responsiveness on iOS as well as automatic session management on both platforms.
  • Updated Google Analytics SDK - Newly released iOS version 1.4 and Android version 1.4.2 contain several bug fixes, including more reliable methods for sending hits on iOS and a fix for the Android Market referral issue.
  • More samples - New open source application aimed to help reduce the ramp-up time for new developers who want to track their apps. This application exercises all the Google Analytics APIs that are available to mobile application developers. You can find them at trunk/src/tracking/mobile.

To read more, check out the full post on the Google Analytics Blog.

We’re happy to announce we’ve just launched AdSense Management API v1.1!

With the new features in this release, you’ll be able to retrieve ad units via custom channels (and vice-versa), make GET calls on most inventory items, and access extended targeting information on custom channels.

Take a look at our updated documentation for more details.

Let us know if you have any questions, and happy holidays!


A new version of the DoubleClick for Advertisers (DFA) API has arrived: v1.16. This release consists entirely of security and performance enhancements. It does not alter the objects exposed by the API.

Deprecation of v1.14

The version from two releases ago, v1.14, is now considered to be deprecated. As previously announced, v1.14 will be removed from service on January 21st, 2012. Be sure to migrate any applications currently using v1.14 by this time. Consider it an opportunity to move to v1.16!

Sunset of v1.15 in Early March

It’s always sad to see a friend go before its time, but our faithful companion v1.15 will be leaving us slightly earlier than usual. This version will be sunset in early March, a period of 6 months from its release date instead of the usual 7 months. We expect this to be the only version whose lifetime is shortened within the next few release cycles. Please use this time window to test out and migrate to v1.16.

With the release of v1.16, we have updated our release notes page. Please bring any feedback or questions you may have to our forum.

The v201111 version of the DoubleClick for Publishers (DFP) API introduces SuggestedAdUnitService which lets you get and approve those ad units that have tags on your web pages, but no corresponding ad units in DFP.  By default, only ad tags that have 10 or more requests will be returned as suggested ad units. They can be approved using performSuggestedAdUnitAction, after which they become ad units and you can manipulate them using InventoryService.  To use this service, please make sure you have a premium account and that you have enabled the feature in the User Interface.

Why Use Suggested Ad Units?

A simple use case for suggested ad units is for new publishers or blog owners to create new tags for articles and posts on their site and approve suggested ad units based on the number of impressions they generate. This gives you the chance to see how well your content does before targeting line items to your ad units. The ApproveSuggestedAdUnitsExample from the client libraries will show you how to do this.

A more involved use case for publishing platforms is to tag all the pages generated by the users and perform some operations on content that generates a sizable number of impressions.  These operations can include:
  1. Approving the suggested ad unit and targeting line items to it
  2. Promoting the page as featured content
  3. Recognize the user for quality content and auto-approve their pages
Here's a Java code sample of how you would do this:
// Set the number of requests to 50 or more.

// Statement to fetch suggested ad units in descending order by number of 
// requests.
String statementText = "ORDER BY numRequests DESC LIMIT 500";
Statement filterStatement = 
    new StatementBuilder(statementText).toStatement();
SuggestedAdUnitPage page = new SuggestedAdUnitPage();

// List of suggested ad unit ids to approve.
List<String> suggestedAdUnitIds = new ArrayList<String>();
page = suggestedAdUnitService.getSuggestedAdUnitsByStatement(

if (page.getResults() != null) {
  for (SuggestedAdUnit suggestedAdUnit : page.getResults()) {
    if (suggestedAdUnit.getNumRequests() >= NUMBER_OF_REQUESTS) {
      // Add it to the ID list to be approved.
       * Promoting the page as a featured content.
       * Recognize the user for quality content and auto-approve their 
       * pages.

if (suggestedAdUnitIds.size() > 0) {
  // Modify statement to select suggested ad units from the list.
      "WHERE id IN (" + StringUtils.join(suggestedAdUnitIds, ",") + ")");
  // Create action to approve suggested ad units.
  ApproveSuggestedAdUnit action = new ApproveSuggestedAdUnit();
  // Perform the action.
  UpdateResult result = suggestedAdUnitService.performSuggestedAdUnitAction(
      action, filterStatement);
These are just some of the things we think suggested ad units can be used for; we'd love to hear your ideas on our forum or at an Office Hours Hangout.


You might not realize it if you use our client libraries, but at its core the AdWords API is based on SOAP and XML. Crafting a request by hand can be tricky, and even some SOAP toolkits have problems serializing to the correct format. In version v201109 of the API we enabled additional XML validation so that you will now be alerted to structural issues with your requests.

The format of the request’s XML payload is specified by an XML Schema definition (XSD) embedded in the WSDL document for the service. The schema describes very precisely the types and elements that can appear in the request. In past versions of the API the server was somewhat lenient in how it processed the incoming XML. For example, it would silently ignore unknown elements. This had the potential to hide problems with your code or cause mysterious behavior.

With enhanced XML validation enabled, the aforementioned errors can be caught earlier, as the request payload must fully match the format in the schema. Below is a sample request and response showing a validation error for an unknown element.


<?xml version="1.0"?>
<soapenv:Envelope xmlns:soapenv="">
    <get xmlns="">


<?xml version="1.0"?>
<soap:Envelope xmlns:soap="">
        Unmarshalling Error: cvc-complex-type.2.4.a: Invalid content 
        was found starting with element 'foo'. One of '{
        }' is expected.

In this case the response is indicating that only the elements "ordering" or "paging" are permitted in this part of the request. Please note that this error is thrown as a raw SOAP fault, and is not wrapped in an ApiError object. There is no need to add special exception handling for these errors, as they are designed to be detected and resolved during the development phase of your application. If they do occur in your production environment you should log them for later analysis.

There are some side effects of using stricter XML validation that you should be aware of:

  • The order of the elements in the request now matters. The XSD lists elements in a sequence, and the order of the elements in the request must match. That same order is reflected in the API’s reference documentation, and our client libraries ensure that it is always respected.
  • Correct element ordering is also required for ad-hoc report download requests.
  • The xsi:type attributes in a request will always be checked and the values must use the correct namespace.

This additional XML validation has been enabled in the sandbox environment for a year and half, so if your application already works there then this change should be transparent. If you have any questions about this or other aspects of the API, you can reach us on the developer forum or during office hours.


Last month we provided a new channel for developers to reach us: AdWords API office hours on Google+ Hangouts. Based on positive feedback from participants, we've decided to schedule additional Hangouts.

In this next round we are including one more time slot for the European region. Please join us via Google+ Hangouts during the following hours:

  • U.S. session: Friday, 16th Dec, 1PM EST / 10AM PST;
  • Europe session: Friday, 16th Dec, 11AM London / 12 PM Frankfurt / 3PM Moscow.

These Hangouts have no set agendas, so please come with questions and issues you'd like to discuss, such as, challenges you're having during migration to v201109 or issues while using one of our client libraries.

You can find the up-to-date schedule and how-to-join instructions on our community page. We look forward to talking with you face-to-face, but until then you can reach us on the AdWords API forum with any comments or questions.

The AdWords API office hours for European region has started!

- , AdWords API Team.


The Google AdMob SDK makes it easy to serve AdMob ads and monetize your mobile applications. If your app contains a ScrollView, the placement of the ad in your layout can be tricky. In this post, we will discuss the best practice for adding AdMob ads to scrollable content.

Consider the following XML snippet (XML attributes omitted for brevity):

    <TextView android:text="Place very long string here..."/>

Let’s say we want to place an ad in this layout. Defining an AdView in XML is pretty straightforward with the Google AdMob SDK:


Now we have to determine where to insert the AdView in the layout. If we were to insert the AdView inside the LinearLayout after the TextView, the ad would be displayed at the bottom of the ScrollView.

This is a poor ad placement from the user's perspective. Depending on the length of the app content, the ad either sits awkwardly somewhere in the middle of the screen or is hidden at the bottom of the ScrollView.

To improve the user experience, we can move the ad outside the ScrollView and use a RelativeLayout to pin the ad to the bottom of the screen. This is the needed XML markup:

<?xml version="1.0" encoding="utf-8"?>
    <ScrollView android:id="@+id/scrollLayout"
        <LinearLayout android:layout_height="fill_parent"
            <TextView android:layout_height="wrap_content"
                android:text="Place very long string here..."/>

The layout_alignParentBottom attribute pins the AdView to the bottom of the screen and the android:layout_above attribute sets the ScrollView above the AdView. If the ScrollView is not explicitly set to sit above the AdView, the ad will overlay the bottom of the ScrollView. Let’s see what the final result looks like.

This layout looks much cleaner! The ad is displayed at the bottom of the screen and will stay locked to the bottom as we scroll through the app content, providing a more natural user experience.

If you have questions about this post or about the AdMob SDK, feel free to ask us in the forum or join us at our upcoming office hours Hangout session. Start monetizing your mobile applications today!


Following the launch of the AdSense Management API in October 2011, we visited our AdSense API Engineers in London to get to know them a bit better. Our guest today is Ben Birt, a Software Engineer who has worked on the AdSense API team since October 2010.

What’s your main contribution to API development?
I write a lot of the code! More seriously, my general concerns are on the reports side of the API, as well as general code design/maintenance.

Describe your average day at work.
An average day usually consists of the usual: reading/answering email, maybe attending a meeting or two, and then the more fun stuff: actually writing code. I usually end up working on two or three code-related tasks at a time, each of which might take me a week or so.

What do you like most about the AdSense Management API?
I’m really happy that for the first time ever, AdSense publishers have access to data that has traditionally been limited to the AdSense website. App developers have in the past been forced to screenscrape AdSense, but now have access to a much more robust method of data access that is safer for the end user (since they don’t have to give up their password), and easier to use for the developer.

I also really like that because we have built a standard Google API, we get a bunch of integrated tools for free: auto-generated client libraries for just about any language you can name, command-line access to the API (via GoogleCL), and more!

Tell us one best practice about the API.
Being intelligent about the requests you make will save you bandwidth and API quota. Inventory really doesn’t change all that often (especially ad clients), so it’s fine to cache some data for at least a little while.

You can also use ETags to help with this. However, don’t worry about requesting more quota - we fully expect any developer with a moderately successful app/website to need more fairly quickly.

Ok, now we want to know more about you outside work. Tell us one thing that you like about London.
I grew up in the middle of the countryside, so I love the sheer number of things to see, places to eat, and activities to do here. It’s also really easy to get around.

Let’s talk about hobbies. What book, movie and TV show would you recommend to our users?
I’m just going to end up sounding like a sci-fi geek, but here you are:
Book: If you’re into sci-fi, I strongly recommend pretty much anything by Iain M. Banks. I really love his writing style; especially anything set in the “Culture” universe.
Movie: Star Trek (as in the new one). I think it’s a great action-oriented reboot of the franchise with fast pace and excellent cast.
TV show: I really love QI. You might not have heard of it if you’re not British.
It’s a quiz show hosted by Stephen Fry who is one of the funniest and most interesting people on Earth, but it’s not really anything like any other quiz show - the contestants are usually all comedians so every episode is hilarious.

Mmm, now we want to know how much of a geek you are. Top Games of 2011?
These are in no particular order:
The Witcher 2: The makers of this game managed to improve on what was already a near-perfect game in the original Witcher. The game has a really well-thought-out plot - nearly every single task/quest is linked to the main story in some way; it could almost be read like a book. The game also looks gorgeous.
The Elder Scrolls V Skyrim: The game looks amazing, particularly when you’re outside, halfway up a mountain and can see across half of Skyrim! I love the sheer number of things you can do in this world: it’s not all connected up in a (near) single narrative like The Witcher 2; instead you get a massive open world where you can literally do whatever you want.

Thanks Ben, please go back to code our favorite API!
Sorry, I just got Skyrim delivered - I’ll be working from home. ;)

Edit: fixed typo.


Mobile developers--let’s Hangout! We have been answering your questions on the AdMob forum, but we want to take support to another level. That’s why we are excited to announce our first Google+ Hangout Office hours on December 14th at 5pm Eastern (2pm Pacific). We are looking forward to leveraging this technology to connect with you in a way we haven’t been able to before.

With the recent upgrade to both the Android and iOS SDKs, there should be plenty to discuss. We’ll be on hand to answer any technical questions you may have or take in your feedback. If you’ve got a brain teaser of a question, please add it to this forum post ahead of time so we can make sure to get you an answer.

You will need 3 things to Hangout with us:

  1. A Google+ account (sign up here)
  2. The Google voice and video plugin installed on your computer
  3. A quiet place to hangout so we can hear you

Please let us know if you’re planning on attending by clicking the “I’ll be there” button on our event page. Hangouts are limited to 10 people at a time, so if you can’t get in right away please try again later in the hour. For more information about Hangouts, visit the Google+ Help Center. We look forward to seeing you soon, but until then feel free to post any questions you may have in our forum.


We’re very pleased to announce the release of AdWhirl v3.1.1 for both Android and iOS platforms. This update heralds support for the Nexage ad network and includes refreshed adapters for Millennial Media, InMobi, and AdMob—ensuring support for their latest SDK versions.

Additionally, we’ve taken the opportunity to fix several bugs, specifically:

  • (iOS) Reachability NPE [Issue 118]
  • (iOS) Null dereference error [Issue 179]
  • (Android) Build rules for creating the AdWhirl jar
  • (Android) Fixes for Android 1.5/1.6 crashes [Issue 221]

Go ahead and kick the tires; you can find the zips listed on our downloads page. As always, holler at us on the forum if you encounter any issues.

Over the last few weeks, we’ve identified a list of common questions that some of you’ve been asking. In this post, we'd like to share the answers with all of you.

AdSense Host API v3

- How do I set the AdSense login email and the AdSense login password of the application developer for a request to the API?

All requests sent to the AdSense Host API Web Services must include the following header elements:
Check our code examples to see how to include the headers for different languages and different types of requests.

- How do I handle the account confirmation email when I’m developing against the API Sandbox?

The AdSense Host API Sandbox is a replica of the production API services but with some additional support that helps developers test and debug their applications.

The production web services require that when a developer creates an account for a publisher, that publisher receives an email which asks them to go to a web page to perform various actions.

The Sandbox sends the email request to you, the developer (instead of the publisher), which lets you see the messages the publisher would have seen. However, the verification link in that email will not work, because the Sandbox doesn't have a replica of the AdSense website to which to take the publisher.

When developing against the Sandbox you can use the following special request headers to include zip, phone and approval settings that are normally requested of the publisher by email:

AdSense Management API

- How do I check the API usage statistics for my project?

You can check the usage statistics for a project in the API console under the "Reports" tab:

If the current usage is approaching the 10k daily limit, or you estimate that future usage will exceed it, you may request additional quota via the "Quotas" tab in the API console.

If you have any additional questions on these topics, please post on our forum or join one of our upcoming AdSense APIs Office Hours Hangouts.

In the v201111 release of the DoubleClick for Publishers (DFP) API, we're bringing you the ability to target your ad units and line items specifically for the mobile platform. The following walk-through based on the CreateMobileLineItem example of the client libraries describes how to create mobile-targeted line items.

Set your Target Platform

The first step is to set the new attribute targetPlatform to MOBILE to specify that the line item is targeted towards mobile platforms rather than the default web browser platform.  Please note that the target platform attribute has also been added to ad units and that attribute needs to be set to MOBILE as well for the targeting to work.

Set your Targeting

We've introduced four mobile targeting options to enable you to target the right platform:
  1. device manufacturer
  2. mobile carrier
  3. mobile device
  4. mobile device submodel

Here is how you set up your targeting to target just Google devices:
Technology manufacturer = new Technology();
// The ID for the Google device manufacturer was fetched from the 
// Device_Manufacturer PQL table.

DeviceManufacturerTargeting manufacturerTargeting = 
    new DeviceManufacturerTargeting();
    new Technology[] {manufacturer});

TechnologyTargeting technologyTargeting = new TechnologyTargeting();

Targeting targeting = new Targeting();

LineItem lineItem = new LineItem();

That's it! Your line item is now set to target just Google devices.

For mobile device targeting, you can specify two lists of devices: one that is targeted and one that is excluded.  This allows you to target a device manufacturer but exclude certain devices within that family.  However, if a device is part of a device targeting inclusion list, another device from the same manufacturer cannot be in the exclusion list.  For example, putting the Nexus S in the inclusion list and the Nexus One in the exclusion list will result in the following targeting error:

GenericTargetingError.CONFLICTING_INCLUSION_OR_EXCLUSION_OF_SIBLINGS @ targeting.deviceFamilyTargeting

Instead, we recommend targeting the Google device manufacturer and excluding the Nexus One with the device exclusion list.

As always, we value your feedback, so feel free to leave your questions or comments on our forum or join us at one of our upcoming developer Hangouts.

As part of routine upgrades to our infrastructure to improve performance and reliability and along with the announced sunsets scheduled for February 29th, we are planning to change our SSL certificates to use wildcards in the common name (CN). Our certificates will therefore be configured as CN * instead of

In most cases we foresee no changes required on your side, but we recommend testing your code to ensure your transport layer can handle this type of certificate. To test this you can send an API request against our sandbox environment, which has always used wildcards in its certificate. If your request works with the sandbox, you can rest assured that this change will not affect your production code. If you encounter host verification errors, we recommend updating your SSL libraries and retesting. As always, we encourage you to post any questions or concerns regarding this change in our forum.