Location criteria, first introduced in v201109, are undergoing some changes for the v201206 release. This blog post explains these changes and what they mean for your software.

PHASING_OUT obsolete Location criteria

The Location criteria object has a new field, targetingStatus, which can be one of ACTIVE, OBSOLETE and PHASING_OUT.

  • ACTIVE Locations can be targeted as normal.
  • OBSOLETE Location targets have been retired and cannot be targeted.
  • PHASING_OUT Locations will shortly become obsolete and should not be targeted.
Locations can be phased out for a number of reasons: the location may be re-structured into smaller (or larger areas), geo-political changes, etc. The AdWords UI reflects these changes and now the AdWords API will make these changes visible to developers. We will publish a blog post 4 weeks in advance of a location moving to PHASING_OUT.

What this means for your software

As of the launch of v201206, Location criteria that are PHASING_OUT will still be accepted. Starting 4 weeks later (week of 7/23), adding these targets will cause a CriterionError.Reason.CANNOT_TARGET_CRITERION error message. Please make sure before adding a Location target that it is ACTIVE. Choose a different target if it is labeled OBSOLETE or PHASING_OUT.

Soon to PHASE_OUT

Check out this help center article to learn which specific locations will be removed after July 23rd. The article also provides more detail about the phasing-out process in general.

In addition, we will introduce two new separate targets, one for Serbia and one for Montenegro in the coming weeks. These new targets will replace the current single Serbia Montenegro target, and the targeting status of Serbia Montenegro will change to PHASING_OUT sometime after July 27th.

We have documented this new status field in our downloadable documentation. The LocationCriterionService and CampaignCriterionService will also populate this field. Please update your code to check this field or your application may break.

If you have any questions, please post on the forum or attend one of the AdWords API Office Hours Hangouts.

We’re pleased to announce the launch of AdWords API v201206, which includes new ad group level Flexible reach targeting settings on the Google Display Network, a new query language to retrieve items more flexibly, new report types, and changes to ad scheduling and other services. Below we’ve highlighted some of the new features available to all users. A complete list of changes is available in the release notes.


v201206 highlights:

  • CampaignService and AdGroupService changes for the adgroup override/restrict targeting setting migration - The new Flexible reach setting in AdWords enables advertisers to fine-tune where ads show by choosing settings at the ad group level instead of the campaign level. Once you choose Flexible reach for the campaign, you cannot revert back to your previous setting, and will manage targets and bids at the individual ad group level. 
  • New services for obtaining customer information - we’re introducing the new ManagedCustomerService and CustomerService in v201206, v201109_1 and v201109. These services will be replacing ServicedAccountService and CreateAccountService, starting with v201206. 
  • New reports - We’re introducing a new CLICK_PERFORMANCE_REPORT which provides information on each click, as well as REACH_FREQUENCY reports at the Account, AdGroup and Campaign levels. 
  • AWQL - The AdWords Query Language providing SQL-like syntax queries is now available on some services including Ad Hoc Reporting. 
  • Other changes - AdSchedule targeting has been moved to CampaignCriterionService. The CampaignTargetService is now sunset. 

With the release of v201206, the following versions and services will be deprecated:

  • v13 AccountService - We will sunset this version and service on August 20, 2012 
  • v201109 and v201109_1 - We will sunset these versions on October 26, 2012 

As with every new version of the AdWords API, we encourage you to review the resources in the release notes. If you have any questions please post on the forum or attend one of the AdWords API Office Hours Hangouts.

- The AdWords API Team

Smart Banner advertisements, introduced in AdMob SDK v6.0, help developers utilize the full width of the iPhone and iPad screen for displaying ads. You still have to be smart about using Smart Banners! We are noticing that some of you are having a hard time resetting your ad’s origin when a re-orientation of the device occurs. More specifically, not resetting the ad’s origin correctly causes ads to disappear offscreen after orientation changes. In this blog post, we’ll show you how to keep a Smart Banner docked to the bottom of the screen on iOS.

Smart Banner advertisements, introduced in AdMob SDK v6.0, help developers utilize the full width of the iPhone and iPad screen for displaying ads. You still have to be smart about using Smart Banners! We are noticing that some of you are having a hard time resetting your ad’s origin when a re-orientation of the device occurs. More specifically, not resetting the ad’s origin correctly causes ads to disappear offscreen after orientation changes. In this blog post, we’ll show you how to keep a Smart Banner docked to the bottom of the screen on iOS.

The first thing to do is to initialize a Smart Banner at the bottom of the device’s screen. You can do this by giving the ad an origin corresponding to the screen bottom.

// Initialize the banner docked to the bottom of the screen.
// We start in a portrait orientation so use kGADAdSizeSmartBannerPortrait.
  CGPoint origin = CGPointMake(0.0,
                               self.view.frame.size.height -
                               CGSizeFromGADAdSize(
                                   kGADAdSizeSmartBannerPortrait).height);

  self.adBanner = [[[GADBannerView alloc]
                    initWithAdSize:kGADAdSizeSmartBannerPortrait
                            origin:origin] autorelease];

//Continue rest of initialization here

Every time an orientation change occurs, you have to reset the ad’s orientation so it continues to stay docked to the bottom. The best place to implement the above logic is in the willAnimateRotationToInterfaceOrientation:duration: method since the view’s frame has been updated to the new orientation

Update the origin by utilizing the Smart Banner constant that is applicable to your current orientation. The only value that should change is your y-origin, since your x-origin should remain at 0.

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInt
                                        duration:(NSTimeInterval)duration {
  // The updated y value for the origin.
  CGFloat yLocation;

  // Set a new frame to update the origin on orientation change. Remember to set
  // adSize first before you update the frame.
  if (UIInterfaceOrientationIsLandscape(toInt)) {
    self.adBanner.adSize = kGADAdSizeSmartBannerLandscape;
    yLocation = self.view.frame.size.width -
                CGSizeFromGADAdSize(kGADAdSizeSmartBannerLandscape).height
  } else {
    self.adBanner.adSize = kGADAdSizeSmartBannerPortrait;
    yLocation = self.view.frame.size.height -
                CGSizeFromGADAdSize(kGADAdSizeSmartBannerPortrait).height);
  }

  CGRect frame = self.adBanner.frame;
  frame.origin = CGPointMake(0.0, yLocation);
  self.adBanner.frame = frame;
}

If you’re not using mediation, changing the adSize after your first request will cause another request to be made. Make sure that you set the frame after you modify the adSize. This ensures that the ad transition looks smooth across orientation changes.

Your Smart Banner ads are now even smarter. As the orientation of the device changes, your ads should stay docked to the bottom of the screen. If you have any questions about Smart Banners or about the AdMob SDK, feel free to post them in our forum or keep on the lookout for upcoming Hangout office hours.


Today we’ve released the newest version of the DFP API, v201206, which adds a significant number of reporting improvements. The new release also fully supports OAuth 2.0 as the authentication mechanism of choice and we encourage you to switch to OAuth 2.0 from ClientLogin or OAuth 1.0a. A full list of improvements from today’s release can be found on our release notes page.

Reporting improvements

In a few of our recent hangouts, we received the feedback that while our reports were great for generating important performance metrics, the CSV files that you downloaded were not always easily machine readable. To make it easier for you to consume reports, we’ve created a new ExportFormat - CSV_DUMP. Below is a list of the features of this new format:

  • Columns are now shown as Dimension.ENUM_VALUE or Column.ENUM_VALUE
  • All money values are now displayed in micro format in the currency of the network
  • All dates are now displayed as YYYY-MM-DD
  • All date-times are now displayed as YYYY-MM-DDThh:mm:ss±hh:mm
  • There is no "pretty printing" of values (i.e. commas) and there is no total row
You may also notice that the v201204 CSV export format has been replaced by CSV_EXCEL, which can be imported into Excel-like products.

As an important note to some of our developers, after upgrading to v201206, you will most likely need to update your code; many column names have changed to reflect a more accurate description of what metrics they are indeed pulling. For example, the column TOTAL_IMPRESSIONS has been changed to TOTAL_INVENTORY_LEVEL_IMPRESSIONS because the v201204 column could only be used with dimensions like AD_UNIT_NAME on the inventory level, i.e. it could not be used with line items, orders, companies or creatives. Alternatively, TOTAL_LINE_ITEM_LEVEL_IMPRESSIONS in v201206 should now be used with dimensions like LINE_ITEM_NAME and ORDER_NAME for instances where you need to include dynamic allocation impressions from AdSense or Ad Exchange line items. To determine how each column should be updated, visit the old column’s reference page and look for the phrase that begins with “Replaced with …”, e.g.

    Replaced with TOTAL_INVENTORY_LEVEL_IMPRESSIONS beginning in v201206.

Lastly, we’ve improved formatting for inventory reports that don’t use top level ad unit views. Most importantly, the duplicate columns clicks and impressions issue for hierarchical views has been fixed and the flat view report will now match how the report is downloaded from the UI.

OAuth 2.0

If you are an eagle-eyed developer, you may have noticed that we recently added OAuth 2.0 information to our authentication page. OAuth 2.0 is now fully supported in the DFP API and we are progressively adding support in our client libraries; Java, Python, .Net , and Ruby currently have full support, while PHP will very soon. In fact, our DFP test playground already uses OAuth 2.0 with the Java library. Please stay tuned to the project sites or the forum for announcements regarding future support.

Our next hangout is July 18th and we’ll be taking your report questions or anything else you might have on your mind. As always, let us know if you have any questions on our forum.

 - , DFP API Team

If you analyze your own traffic logs, or develop web analytics software, we have some news for you: we’re making a change to how some clicks coming from Google appear in your logs. We're writing this mostly as an industry FYI, because Google Analytics reports will not be affected by this change.

Up to now, referrers for clicks on ads for the term "flowers", for example, would be one of the following:

http://www.google.com/search?...&q=flowers&...
http://www.google.com/aclk?...&q=flowers&...

We’re adding a third possible referrer:

http://www.googleadservices.com/pagead/aclk?...&q=flowers&...&ohost=www.google.com&...

This new referrer is on a different domain named ‘www.googleadservices.com’, and has a new path of ‘/pagead/aclk’. The query is still there as the GET parameter ‘q’ and the originating host for the click is there as the GET parameter ‘ohost’. For example, if the click came from google.ca, the new referrer format would be http://www.googleadservices.com/pagead/aclk?...&q=flowers&...&ohost=www.google.ca&...

We’re making this change because we’re trying to improve the experience of clicking on an ad for our users. For historical reasons, Google currently uses two redirects on two different domains for many of the ads on our site. We are streamlining our infrastructure to remove one of these redirects, which brings users to ad landing pages faster, leading to a better user experience for our users and a better return on ad clicks for our advertisers.

The new referrer format ensures that advertisers will still get the relevant bits of information about a search that drove traffic to their site, but without the extra redirect.

In order to give everyone enough time to change any referrer log parsing software, we’ll be keeping the number of affected searches at a low percentage through July. In August, we’ll be increasing the number of affected queries to 100%. When we’re done, you should expect to see all three forms of the URLs.

Editor's note: We'd like to share this announcement from Mike Winton, who founded and leads Google's global Developer Relations organization. --Stan Grinberg, Ads Developer Relations

Google I/O, our annual developer conference, begins in just two days, and this year, we’re bringing you more than 130 technical sessions, 20 code labs and 155 Sandbox partners. If you’re not here in San Francisco, you can still sign up for one of our 350+ I/O Extended events around the world or tune in to I/O Live to watch the livestream from wherever you are. This year’s conference kicks off on June 27 with the first day’s keynote at 9:30 a.m. and the second day’s keynote on June 28 at 10:00 a.m. PDT, so tune in early at developers.google.com/io to avoid missing the action!

Bookmark developers.google.com/io to watch I/O Live from your desktop, or download the Google I/O mobile app to access the live stream from your phone or tablet. For the truly entrepreneurial, check our liveblogging gadget, which lets you add your commentary and the live video feed from the Google I/O keynotes to your blog.

More than 40 sessions on Android, Chrome, Google+ and your favorite APIs will be streamed live with captions, and all remaining session videos will be recorded and available shortly after the conference on Google Developers Live and the conference website. Between sessions, we’ll bring you behind-the-scenes footage featuring interviews with Googlers and attendees, tours of the Sandbox and more. The stream will also continue through our After Hours party (June 27 starting at 7:00 p.m. PDT), where we've teamed up with top entertainers, inventors, artists, educators and visionaries from all over the world for an amazing evening.

We previously discussed how to show a custom image using the Google AdMob SDK when an ad request can’t be filled. In the second and final part of this series, we’ll explain how to resume showing AdMob ads if, for example, internet connectivity is restored.

We previously discussed how to show a custom image using the Google AdMob SDK when an ad request can’t be filled. In the second and final part of this series, we’ll explain how to resume showing AdMob ads if, for example, internet connectivity is restored.

In part 1, we demonstrated how to hide the ad and display a custom image when the first ad request fails. However, the AdMob SDK doesn't make another ad request until it successfully receives an ad, so you must schedule your own refresh. Here’s how to do it:

private final Handler refreshHandler = new Handler();
private final Runnable refreshRunnable = new RefreshRunnable();
private boolean firstAdReceived = false;

@Override
public void onFailedToReceiveAd(Ad ad, ErrorCode code) {
  if (!firstAdReceived) {
    // Keep code from part 1.
    ...
    // Schedule an ad refresh.
    refreshHandler.removeCallbacks(refreshRunnable);
    refreshHandler.postDelayed(
        refreshRunnable, REFRESH_RATE_IN_SECONDS * 1000);
  }
}

private class RefreshRunnable implements Runnable {
  @Override
  public void run() {
    // Load an ad with an ad request.
    adView.loadAd(new AdRequest());
  }
}

A Handler is used to schedule an ad refresh at your desired refresh rate. Before making the postDelayed call, the handler removes any pending posts that may be queued.

With these changes, your application will request an AdMob ad at a regular interval. Once a request is successful, the existing code in onReceiveAd swaps out your custom image with an AdMob ad, and AdMob starts refreshing automatically.

If the user either leaves your app or clicks on your custom ad, you want to pause your refresh handler when your app is not visible to the user. This is an Android best practice that will help preserve battery life. You can override Android’s onStop and onStart callbacks to stop and start ad refreshes, as shown below:

@Override
public void onStop() {
  super.onStop();
  // Remove any pending ad refreshes.
  refreshHandler.removeCallbacks(refreshRunnable);
}

@Override
public void onStart() {
  super.onStart();
  if (!firstAdReceived) {
    // Request a new ad immediately.
    refreshHandler.post(refreshRunnable);
  }
}

This code prevents your app from making ad requests when the user exits your app but immediately requests an ad when the user returns to your app.

That’s it! You’ve successfully integrated a placeholder image into your application to stand in when an ad request can’t be filled. Check out the full example if you have trouble setting up the code.

As always, let us know on the forum if you have any questions about the Google AdMob SDK, or join us during office hours.

There are times when an ad request can’t be filled--for example, when the internet connection goes out on a mobile device. In part 1 of this 2-part series, we’ll demonstrate how to display a custom image using the Google AdMob SDK when AdMob can’t retrieve an ad.

There are times when an ad request can’t be filled--for example, when the internet connection goes out on a mobile device. In part 1 of this 2-part series, we’ll demonstrate how to display a custom image using the Google AdMob SDK when AdMob can’t retrieve an ad.

First, create a layout file called main.xml. Your layout might look like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <LinearLayout android:id="@+id/adLayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >
        <ImageView android:id="@+id/image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/your_image"
            android:visibility="gone" />
    </LinearLayout>
</LinearLayout>

Note that in this layout:

  • The LinearLayout with identifier adLayout is the container for your custom image as well as the AdMob ad.
  • The ImageView assumes you have a custom image named your_image in the res/drawable directory.
  • The image visibility is set to gone because it doesn’t need to be shown unless AdMob fails to receive an ad.

Next, create and load an ad in your Activity’s onCreate method. Optionally, you can also add an onClick event to your custom image to launch a web page in case there’s still an internet connection.

private AdView adView;
private ImageView imageView;

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  adView = new AdView(this, AdSize.BANNER, "YOUR_AD_UNIT_ID");
  adView.setAdListener(this);
  LinearLayout layout = (LinearLayout) findViewById(R.id.adLayout);
  layout.addView(adView);
  adView.loadAd(new AdRequest());
  imageView = (ImageView) findViewById(R.id.image);
  imageView.setOnClickListener(this);
}

@Override
public void onClick(View view) {
  Intent intent = new Intent(
      Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
  startActivity(intent);
}

You can then implement AdMob’s AdListener callbacks to determine if you need to show a custom image. If AdMob invokes onReceiveAd, hide your custom image and display the ad. If onFailedToReceiveAd is invoked, hide the AdMob ad and display your custom image. The following code demonstrates these concepts:

private boolean firstAdReceived = false;

@Override
public void onReceiveAd(Ad ad) {
  firstAdReceived = true;
  // Hide the custom image and show the AdView.
  imageView.setVisibility(View.GONE);
  adView.setVisibility(View.VISIBLE);
}

@Override
public void onFailedToReceiveAd(Ad ad, ErrorCode code) {
  if (!firstAdReceived) {
    // Hide the AdView and show the custom image.
    adView.setVisibility(View.GONE);
    imageView.setVisibility(View.VISIBLE);

    // Turn off the click listener if there is a network error.
    if (code == ErrorCode.NETWORK_ERROR) {
      imageView.setOnClickListener(null);
    } else {
      imageView.setOnClickListener(this);
    }
  }
}

You only need to show your custom image if AdMob fails to receive an ad on the first request. You can determine if AdMob has previously received an ad by using the firstAdReceived flag.

These steps are sufficient to display a custom image if AdMob fails to return an ad. Tune in tomorrow for part 2 of this series, where we’ll discuss best practices on serving network ads when the user regains a network connection. Part 2 will also include a full code example demonstrating concepts from both posts.

Reach out to us know on the forum if you have any questions about the Google AdMob SDK, or join us during office hours.

Update: Added link to part 2 of this post.

The Ruby programming language is currently a popular choice for web development with Rails being the most commonly used framework. With this in mind we're releasing a new demo application that shows how to easily use the AdWords API Ruby client library with Rails.

This simple web application demonstrates the following:

  • authorization against AdWords with OAuth 1.0a and credentials re-use
  • accounts hierarchy retrieval and account selection
  • simple service request (CampaignService.get) and display results
  • basic AdHoc reporting functionality with download support

Check out the README file on installation instructions and detailed walkthrough for the demo.

Download the application from the library site or via git. It is also mirrored on GitHub (pull requests are welcome).

As you may have noticed in v201204, how you populate teams with users has changed a bit. Starting in v201204, teams are now populated by associating users with a team, much like line item creative associations. Associations give you the ability to define per-team permissions for users and remove users through PQL on the server, rather than modifying a large list of IDs on the team object.

Creating the team

Creating team objects works the same way as in previous versions; you call TeamService.createTeams specifying the initial set of properties on the team, such as to which inventory and companies the team has access. To add users to this empty team, however, you will need to create user team associations for every user you want to add to the team. When creating the association, you can also specify an access override if you have that feature enabled on your network; e.g., you can add a user limiting them to have read only access to entities on that team.

As a side note, you may find some teams have already been created for you by Google. These teams have negative IDs and their name will describe their purpose. The team with the name “All entities”, for example, gives all joined users access to all entities in the network.

Getting the teams

Now that you’ve created a team and associated users with it, it’s simple to retrieve either all users on that team, or all teams to which a user belongs. To retrieve all users on a team, make a call to UserTeamAssociationService.getUserTeamAssociationsByStatement with the PQL statement:
    WHERE teamId = :teamId LIMIT 200
where you’ve bound :teamId to the team’s ID and iterate through each page to collect the results. To retrieve all teams to which a user belongs, make the same service call, but pass the user’s ID instead of the team’s such as:
    WHERE userId = :userId LIMIT 200
where you’ve bound :userId to the user’s ID and iterate through each page again to collect the results.

Removing someone from the team

In v201204, removing a user from a team is equivalent to deleting that user’s team association. To delete associations, make a call to UserTeamAssociationService.performUserTeamAssociationAction with a PQL statement including either the team ID, user ID, or both. To delete just a single team member, pass the statement:
    WHERE teamId = :teamId and userId = :userId
You can also delete all members of a team by passing a PQL statement with just the team:
    WHERE teamId = :teamId
Lastly, you may just want to remove a subset of users from a team. To do this, pass a PQL statement like:
    WHERE teamId = :teamId and userId in (123,456,789)
where you’ve bound :teamId to the team’s ID, and 123, 456, and 789 represent IDs of users that you want to remove.

Our next hangout is July 18th and we’d love to see you there. As always, let us know if you have any questions on our forum.


 - , DFP API Team

Last week we announced the limited release of AdWords scripts, a new JavaScript-based cloud programming environment that you can use to update and report on your AdWords accounts. The feature will be rolling out to all customers over the coming weeks, but in the meantime you can join us in a webinar this Thursday, June 21st at 2pm EDT/11am PDT to see scripts in action.

Last week we announced the limited release of AdWords scripts, a new JavaScript-based cloud programming environment that you can use to update and report on your AdWords accounts. The feature will be rolling out to all customers over the coming weeks, but in the meantime you can join us in a webinar this Thursday, June 21st at 2pm EDT/11am PDT to see scripts in action.

The webinar will be hosted using Google+ Hangouts on Air, and will include:

  • An overview of what AdWords scripts are.
  • A discussion around how they work and what they can be used for.
  • A live tutorial showing how to create and run them.

We'll leave plenty of time to address any questions you have, and you can submit them ahead of time on this Google Moderator page. RSVP for the webinar by clicking the "I'll be there" button on the event's page and don't forget to subscribe to the AdWords scripts forum for future updates.

To prepare for the introduction of new mobile capabilities in the AdWords API, we are making changes to the URL Performance Report and the Automatic Placements Performance Report in v201109 and v201109_1.

In the URL Performance Report:
  • The Url field format is changing from
    {mobile-app-id}.adsenseformobileapps.com/{publisher-id} to
    {mobile-app-id}.adsenseformobileapps.com. 
  • We are removing the {publisher-id} from the Url since the {mobile-app-id} rarely gets associated to more than one {publisher-id}. 
In the Automatic Placement Performance Report:
  • Statistics for all mobile applications that have been grouped under the adsenseformobileapps.com Domain will now be broken out by mobile application. 
  • The statistics for each mobile app will be at a Domain of the form
    {mobile-app-id}.adsenseformobileapps.com. 
These changes take effect on Monday, July 9th.

If you have any questions or concerns about this change, please post on the forum or attend one of the AdWords API Office Hours Hangouts.

Today we announced the limited release of AdWords scripts, a new way to programmatically access and manipulate your AdWords campaigns. Built on Google Apps Script technology, these scripts are written in JavaScript, stored in your AdWords account, and run in the cloud. They provide simple access to the most popular AdWords data and functionality, making it possible for a wide range of users to build tools and integrations quickly.

Today we announced the limited release of AdWords scripts, a new way to programmatically access and manipulate your AdWords campaigns. Built on Google Apps Script technology, these scripts are written in JavaScript, stored in your AdWords account, and run in the cloud. They provide simple access to the most popular AdWords data and functionality, making it possible for a wide range of users to build tools and integrations quickly.

AdWords scripts include built-in support for Google Spreadsheets and HTTP services, allowing you to pull in important data and take action in your account. Additionally, the ability to send email makes it possible to develop advanced reporting and data analysis solutions. We expect that customers with limited resources or technical expertise will find this a compelling platform for building specialized tools and workflows.

AdWords scripts are a supplement to the existing AdWords API, and their compact interface makes them ideal for building small projects or for performing one time actions. For example, let’s compare the code needed to add a keyword to an ad group.

AdWords API (Java)

// Create keyword.
Keyword keyword = new Keyword();
keyword.setText("mars");
keyword.setMatchType(KeywordMatchType.BROAD);

// Create biddable ad group criterion.
BiddableAdGroupCriterion biddableAdGroupCriterion = 
    new BiddableAdGroupCriterion();
biddableAdGroupCriterion.setAdGroupId(adGroupId);
biddableAdGroupCriterion.setCriterion(keyword);
biddableAdGroupCriterion.setDestinationUrl(
    "http://www.example.com/mars");
ManualCPCAdGroupCriterionBids bids = new ManualCPCAdGroupCriterionBids();
bids.setMaxCpc(new Bid(new Money(null, 500000L)));
biddableAdGroupCriterion.setBids(bids);

// Create operation.
AdGroupCriterionOperation operation =
    new AdGroupCriterionOperation();
operation.setOperand(biddableAdGroupCriterion);
operation.setOperator(Operator.ADD);
AdGroupCriterionOperation[] operations = new
    AdGroupCriterionOperation[] {operation};

// Add keyword.
AdGroupCriterionReturnValue result =
    adGroupCriterionService.mutate(operations);

AdWords scripts

adGroup.createKeyword("mars", 0.50, "http://www.example.com/mars");

Having a simple interface means that not every feature or setting is exposed, but it should limit the need for deprecations and migrations. Scripts can currently operate against campaigns, ad groups, ads and keywords, with the possibility of new data being made available based on customer demand. No registration or developer token is required to write scripts and they are free to use.

For more information about AdWords scripts see our developer documentation, which includes example scripts and tutorials. If you have questions or comments please reach out to us on the forum, and we can’t wait to hear about the exciting scripts you come up with!

A few months ago Ben Birt and Nick Johnson gave us some useful insights about the development of the AdSense Management API. This week, Gregory Block shares his experience of development against the API. Greg started the Google Publisher Toolbar project and is now the Team Leader of the development behind it.

Hello Greg, thanks for agreeing to be interviewed! Can you briefly describe your project and why you started the development?

The project started as a thought experiment - what would AdSense look like if we didn’t have a web interface for people to log in to, and we could only give you information within the context of your own site? It was originally called “AdSense Minus AdSense”, in homage to Garfield Minus Garfield.

Now, it’s a central part of our publisher strategy moving forward. Our customers use our products in concert with one another, but we send them to each product to figure out what’s going on.

Think of it as an “in-context” review tool for everything you do with your site. Ultimately, it will incorporate all of our platforms - AdSense, the DoubleClick Ad Exchange, DoubleClick for Publishers, Analytics, Webmaster Tools... we want you to know about all the information available within the context of the page you’re looking at.

People look at the websites they build and manage hundreds or thousands (and for some, more) of times each working day; they use our frontends only sporadically. We push information down into the place they need it most, at the right moment, in the right context.

You have more than 18 thousand users and an average rating of 4 stars: are you happy with your project?

It’s been hugely successful internally at convincing people to look beyond product silos and really focus on the needs of our end users. Ultimately, I’m aiming to provide a better, more accessible, more immediate, and more integrated experience than they can get from our web products. We’re going to support the whole publisher ecosystem, and I’m excited about all of the things we can do in that space.

It’s also a great showcase for our APIs - most of what the chrome extension does is accessible by any user from our public APIs.

What about the development process? Do you have any suggestions for other developers?

The process begins and ends with the end user. Efforts like the Google Publisher Toolbar drove our API strategy because we had a clear need we were trying to meet. Know your user, and have a clear vision for the product and how it helps that user do what they need to do.

Behind every good app is a good idea; but a good idea isn’t good enough - execution matters. The other important thing, in my opinion, is the toolchain. We take a strict approach towards building verifiably correct JavaScript, enforce strong type safety, and we bake in unit testing at development time. The toolbar isn’t one binary - it’s lots of binaries, all interacting with each other through messaging and callbacks, and we wouldn’t be able to get here without the help and support of our tools infrastructure.

If you had to mention one thing about developing against the AdSense API that positively impressed you during the development, what would that be?

Speed, speed, speed. A thin skin on the API is an order of magnitude faster than anything you can get out of our frontends. I think the API is well within reach of most of our publishers, and we can learn a lot from what people build from it. Some of those ideas we’ll be able to feed back in.

First and foremost, use the client libraries. There’s a vast amount of stuff taken care of automatically, and you’ll write and maintain less code.

Second, get your OAuth2 flow in place early. You’re going to spend a lot of time using it, and so it’s best to get that done right away. You’ll be tempted to just hack in a key you generated by hand into the source, but user experience matters. (I’m speaking from my own failures here.)

Third, think about security. We take a very, very cautious approach about inserting content into the page, and deciding what information is allowed to live in the DOM. We could improve the user experience by loosening that restriction, but we’re looking to bulletproof the product against social engineering and information leakage. As new features propagate down through the chrome versions, we’ll be using more and more of those secure mechanisms to deliver content in-site - the Chrome Infobars API, for example, will allow us to replace our in-page notification bar with one that is less intrusive to the user and doesn’t interact with page content. Sandboxed iframes will allow us to further restrict the security container of the in-page content, and allow us to move content that previously lived in stand-alone windows into in-page overlays and provide a richer experience to publishers. We use chrome as our sole platform because it’s secure - and when it comes to surfacing sensitive information like publisher revenue, security matters.

Last, prototype early, prototype often. There’s a whole skunkworks Android application we launched solely to experiment with and theorize on. Moreover, and in many ways more importantly, I depend on a UX person to cycle through a lot of ideas with me before roughing them out in code; we then cycle back through and iterate once we’re looking at implementations until we’re happy. On more than one occasion, I’ve cut a corner and not fully implemented something that was different in the mocks, and I’ve regretted it every. single. time. Don’t underestimate the power of good design.

And if you had the magic powers to request one additional feature and have it released immediately, what would that feature be?

In the immortal words of River Song, “Spoilers”.

What else do you do at Google?

I’m also responsible for the DoubleClick Ad Exchange Seller frontend here in London, as well as running a team called Publisher Insights that recommends revenue-impacting changes to the sites of AdSense and Ad Exchange publishers through simulated A/B experimentation.

Let’s talk hobbies and personal interests. What interests do you have outside work?

I play an awful lot of video games. I play through most games exactly once, to keep the size of the Pile of Shame (the games I bought but haven’t played yet) low. I’m currently on Act 3 of Diablo 3, and having mixed emotions about the experience.

I also have a Basset Hound named Daisy, who takes up an inordinate but pleasurable amount of my time.

Soooo.....what about Mass Effect3?

Utterly devastated. Taking reasonably ‘hard sci-fi’ and giving it a magical ending is a cardinal sin; I literally wish I could un-play all three. No amount of tender, love and care is going to help me forget.

There. I’ve said it. I feel better already.

Thanks Greg! Keep up the good work!


Interested in more Google+ Office Hour Hangouts? We know you are because attendance has been great! We've scheduled another round for all of our products this summer. You can view the newly scheduled hangouts on the ...
Interested in more Google+ Office Hour Hangouts? We know you are because attendance has been great! We've scheduled another round for all of our products this summer. You can view the newly scheduled hangouts on the Google Developers events page. Please RSVP by clicking the “I’ll be there” button if you plan on attending. You can also continue to follow our schedule by subscribing to the Google Ads Developer Office Hours calendar which is also linked on the sidebar to the right of this blog entry.

New for this round, in response to requests, we will be posting the link to the hangout in each of our respective forums. Apparently you guys are extremely interested in coming but sometimes forgetful and wanted an extra email reminder from the forums.


In case you haven’t joined us before, you will need 3 things to join the hangout:
These hangouts are informal and conversational, which make them a great place to ask questions or give us feedback. If you have questions about our office hours program, reach out to us on the forums.



Today, we’d like to present the new DFP API Playground for test networks, built on Google App Engine using the new ads Java client library.

What’s New
  • Test networks can be created using the playground application
  • OAuth2.0 authentication using the Java client library with automatic token refresh
  • Uses a push queue to make API calls in background tasks and stream results back using the Channel API
Please note that the playground only makes test networks accessible, so you will not be able to view production or old sandbox networks through the application. We’ve made the project open-sourced so you can get more details on integrating DFP API with App Engine through the project repository.

Test Network Creation
The new playground makes it simple for API developers to create test networks and get started with DFP API. All you have to do is log in with a Google account that’s not already associated with a test network and you will be prompted to create a new one.

1. Visit http://dfp-playground.appspot.com/. You’ll be asked to sign in with your account if you haven’t already done so.

2. Authorize the application to make requests to DFP API on your behalf (you’ll only have to do this once).



3. Click the “Create Test Network” button.



4. And you’re done! You can now configure your test network (language, currency, etc) by following the link to the DFP user interface.



We are always looking for ways to help API developers be more productive, so if there are any features you would like to see in the playground application or in the API, please leave us a comment at our forum. We’d also love to chat with you at one of our Office hours hangouts.

In Google AdMob SDK v6.0 and above, you can request ads from multiple ad networks, including AdMob, while controlling how the requests are allocated among those networks. With this new feature, called mediation, you configure a mediation placement at mediation.admob.com by assigning each network either an eCPM or a percentage value.

In Google AdMob SDK v6.0 and above, you can request ads from multiple ad networks, including AdMob, while controlling how the requests are allocated among those networks. With this new feature, called mediation, you configure a mediation placement at mediation.admob.com by assigning each network either an eCPM or a percentage value.

Some of you have asked how AdMob uses these values to determine the network order, so we'd like to take this opportunity to explain. We’d also like to discuss what happens when you add an ad network to an existing mediation placement.

Network Allocation Methods

There are two ways in which traffic is allocated across ad networks.

  1. eCPM values. Input the eCPM you expect to get paid from each ad network you work with. AdMob then sorts the ad networks by their eCPM values from highest to lowest, and the result becomes the network order used to request ads. The network with the highest eCPM value is the first network Admob goes to with an ad request.

  2. Percentages. Alternatively, you can assign percentage values to each ad network. Mediation randomly determines the first network using the given percentages, and then normalizes the remaining percentages to determine the next ad network. This process continues until all configured networks have been selected. Note that any ad network with 0% percentage allocation will be ignored.

Unlike AdWhirl, which refreshes its configuration on each ad refresh, AdMob Mediation refreshes its configuration once every 300 seconds. This means that the SDK uses the same network order until a new mediation configuration is fetched.

Adding a New Network to an Existing Application

It's important to know how your application will behave when you add a new ad network to it. Remember that anytime you add a new ad network, you need to include the corresponding ad network adapter in your app. If the adapter cannot be found, the AdMob SDK skips that network and moves on to the next one.

Don't worry if your application doesn’t include the ad network adapter. For placements with eCPM values, the added network doesn't affect existing versions of the application. Similarly, for placements using percentage configurations, percentages are effectively normalized across existing valid ad networks, as invalid networks are automatically thrown out.

Let us know on our forum if you have any questions about mediation placements or general questions about the Google AdMob SDK. You can also ask us questions at our next hangout session.

New to v1.18 of the DFA API is support for In-Stream video creatives which allow you to serve ads into a publisher’s video player. The way you upload assets and associate them with an In-Stream video creative differs from other types of creatives.

New to v1.18 of the DFA API is support for In-Stream video creatives which allow you to serve ads into a publisher’s video player. The way you upload assets and associate them with an In-Stream video creative differs from other types of creatives.

Walk-Through

Unlike standard creative assets, you may not upload an in-stream asset unassigned to a creative. Therefore the first step to setting up a new In-Stream video creative has to be making the creative itself. The creative must start off inactive and cannot be activated until at least one media asset is assigned to it. You can start the process using our Java client library like so:

DfaSession session = new DfaSession.Builder().fromFile().build();
DfaServices dfaServices = new DfaServices();
CreativeRemote creativeService = 
    dfaServices.get(session, CreativeRemote.class);

// Create the In-Stream video creative.
InStreamVideoCreative inStreamVideoCreative = 
    new InStreamVideoCreative();
inStreamVideoCreative.setAdvertiserId(advertiserId);
inStreamVideoCreative.setName(creativeName);
inStreamVideoCreative.setVideoDuration(videoDuration);
// In-Stream video creatives have to be created inactive. One can only 
// be set active after at least one video media file has been added to
// it.
inStreamVideoCreative.setActive(false);

// Set the video details based on the Video Ad Serving Template (VAST)
// specification.
inStreamVideoCreative.setAdId(adId);
inStreamVideoCreative.setDescription(description);
inStreamVideoCreative.setSurveyUrl(surveyUrl);
inStreamVideoCreative.setClickThroughUrl(clickThroughUrl);

// Save the In-Stream video creative.
CreativeSaveResult creativeSaveResult = 
    creativeService.saveCreative(inStreamVideoCreative, campaignId);

Once the creative exists, you can begin uploading assets for it. This process uses the new InStreamAssetUploadRequest object. The DFA website UI has the capability to transcode video formats during this step, but transcoding is not available through the API. You’ll need to upload media files for all of the video formats you need instead. We’ll start by adding a single media (video) asset since that is all that is required for an In-Stream creative to be activated:

// Create the In-Stream video creative asset.
CreativeAsset inStreamVideoAsset = new CreativeAsset();
inStreamVideoAsset.setName(assetName);
inStreamVideoAsset.setContent(Media.getMediaDataFromFile(pathToFile));

// Create an upload request to make this asset a media file for an 
// existing In-Stream creative.
InStreamAssetUploadRequest inStreamAssetUploadRequest = 
    new InStreamAssetUploadRequest();
inStreamAssetUploadRequest.setMediaFile(true);
inStreamAssetUploadRequest.setInStreamAsset(inStreamVideoAsset);
inStreamAssetUploadRequest.setCreativeId(creativeSaveResult.getId());

// Save the media file to your In-Stream creative.
InStreamVideoCreative inStreamVideoCreative =
    creativeService.uploadInStreamAsset(inStreamAssetUploadRequest);

In-Stream video creatives can have video assets associated with them that will not be served. Video assets default to this state when uploaded. You need to choose the video assets you want to be served:

for (InStreamMediaFile mediaFile : inStreamVideoCreative.getMediaFiles()) {
  mediaFile.setPickedToServe(true);
}

The creative is now ready to be served. You can take the opportunity to add additional types of ads to it. The two options are companion banners - Flash banners that display on the webpage during and after the pre-roll video plays, and non-linear ads - interactive Flash or static image banners that display over the pre-roll video as it’s playing. Both types of additional content follow the same upload workflow using InStreamAssetUploadRequest, only instead of setting the mediaFile flag to true, you set the companion or nonLinear flag instead.

Now that the creative has associated assets, it can be activated:

inStreamVideoCreative.setActive(true);
CreativeSaveResult creativeSaveResult =    
    creativeService.saveCreative(inStreamVideoCreative, campaignId);

That’s all there is to it. Complete code examples containing these steps are in our Java, Python, and .NET client libraries. We’re always available to field any of your questions on our forum.

Today, we announced a major new feature in AdWords that will benefit app developers using AdMob. For the first time, AdWords advertisers will have access to mobile app inventory, giving them the ability to create and manage ad campaigns directly from the AdWords interface. This means that AdMob partners will have access to more than one million advertisers currently using AdWords.

Today, we announced a major new feature in AdWords that will benefit app developers using AdMob. For the first time, AdWords advertisers will have access to mobile app inventory, giving them the ability to create and manage ad campaigns directly from the AdWords interface. This means that AdMob partners will have access to more than one million advertisers currently using AdWords.

What does this mean for app developers?

Starting today, a new campaign type is available in AdWords that makes it easy to launch an ad campaign to run on mobile apps on the AdMob network. If you are interested in learning how this will exist in the AdWords account see HERE.

This will give far wider pool of advertisers the ability to bid for and run ads in your apps. Over time, we’re confident this increased demand improve performance and result in the delivery of more high quality ads that are well suited to users’ interests.

In the short term, you’ll see more Google ads served in your app as advertisers start using this new feature.

How does this affect filtering?

All filters you currently use for AdMob ads will be respected for AdWords ads as well. However, please be aware that your filters will still not apply to Google Certified Ad Networks. You will be able to opt out of showing ads from Google Certified Ad Networks if you require filters across all your inventory.

Posted by Vishay Nihalani, Product Manager, Google Mobile Ads