Better know a service: InfoService

Friday, March 27, 2009


We, at the AdWords API Team, are often asked questions such as "Where have all my units gone?" and "How many API units has a particular account used in the last month?" Luckily, we have supplied you with a great set of tools with InfoService to answer these questions. In this blog post, we'll talk about some basic uses of this service, as well as some caveats that can be solved using some more advanced techniques. All code examples have been coded using the AdWords Java Client Library.


Update: both of these examples have now been included as utility methods in the file UnitsUtils.java. The example links below have been updated as well.

Where have all my units gone?

"Where have all my units gone?" is one of the most frequent questions asked by our developers seeking to trim down their API usage. Although InfoService provides the method getUnitCountForMethod, it is not inherently obvious how to generate a full mapping of usage. The heart of the problem is that, to call getUnitCountForMethod, you must pass it a service name and method. To get a full mapping of method to usage, getUnitCountForMethod must be called for each service and method pair. In the method UnitUtils.getMethodUsage, I have shown how you might do this.

The method is broken into two parts: populating a full mapping of service name to list of method names, and calling getUnitCountForMethod for each mapping. The result of each call is then put into a new map, referred to as
methodUsage in the method. When the method has finished running, which may take a few seconds, methodUsage will have a mapping of serviceName.methodName to quotaUsage and the output will resemble:

AccountService.getAccountInfo = 3
AccountService.getClientAccountInfos = 257
AccountService.getClientAccounts = 0
AccountService.getMccAlerts = 0
AccountService.updateAccountInfo = 0
...
AdService.addAds = 5005
AdService.checkAds = 0
AdService.findBusinesses = 0
AdService.getActiveAds = 0
AdService.getAd = 0
AdService.getAdStats = 0
AdService.getAllAds = 0
AdService.getMyBusinesses = 0
AdService.getMyVideos = 0
AdService.updateAds = 0
...
TrafficEstimatorService.checkKeywordTraffic = 0
TrafficEstimatorService.estimateAdGroupList = 0
TrafficEstimatorService.estimateCampaignList = 0
TrafficEstimatorService.estimateKeywordList = 0

As you can see, many of my units went towards adding Ads. Using this data, I could enter my monthly values into a spreadsheet and plot my usage over several months. Not only could I easily spot where all of my units have gone, but I would also be able to spot any out of the ordinary behavior as well.

As a side note, regardless of the credentials supplied to the service, this method will only gather data against the developer token. Meaning that, supplying a clientEmail or clientCustomerId will not give a finer grained set of results.

How many API units has a particular child account used in the last month?

Another great feature of InfoService is that it allows you to determine how many units a particular child account has used over a period of time. This information can be used to invoice clients, if you are developing for an Agency, or to perform cost/ctr analysis, if you wished to optimize your accounts per API spend.

There is one caveat, however. Let's say that we have an account structure that resembles the one below:




We have a top most MCC, Top-MCC, which is the root of our tree. Since our goal is to generate a mapping of child account to the amount of quota used, a first approach may be to run getUnitCountForClients for each client, as shown below:

InfoService.getUnitCountForClients(["Sub-MCC-1",
"Sub-MCC-2", "Client-1", "Client-2",
"Client-3", "Client-4"],
"3/1/2009", "3/31/2009");

From the results, you can create a mapping that resembles:

Sub-MCC-1 = 55
Sub-MCC-2 = 70
Client-1 = 500
Client-2 = 650
Client-3 = 600
Client-4 = 400

You'll notice that while this data gives you some idea of client usage, there's no aggregation of client usage up to the MCC; Sub-MCC-1 returns just the number of units called directly on that account, such as from a command with headers:

<email>Top-MCC</email>
<password>passwordForTop-MCC</password>
<developerToken>...</developerToken>
<applicationToken>...</applicationToken>
<userAgent>...</userAgent>
<clientEmail>Sub-MCC-1</clientEmail>

What you may actually want is an aggregation of unit usage such as:

Top-MCC = 2275
Sub-MCC-1 = 1305
Sub-MCC-2 = 470
Client-1 = 500
Client-2 = 650
Client-3 = 600
Client-4 = 400

In the method UnitUtils.getClientUnitsUsage, I show how to traverse the full account tree below the top most MCC and sum the units for each client to produce a mapping like the one above. However, if by some chance, a client has two parent accounts, linked through UI/API and API, and those parents are both distant children of the same parent, that client will be doubly counted. We've also shown how to keep track of these doubly counted clients in the demo.

We hope that these new utility methods will help you keep track of your API usage and stay tuned for more great demos like these!

--Adam Rogal, AdWords API Team

AdWords API sandbox - Best practices

Friday, March 20, 2009


The API sandbox is open to anyone who wants to test code during development, and it's completely free. We recommend using the sandbox as much as possible to catch your bugs during development so they won't hit your production account later. Here are some tips on using the sandbox effectively:


Initialize your sandbox account

Make sure that the first call to the sandbox is a get() call from AccountService, preferably AccountService's getClientAccounts(). Assuming you use user@domain.com as the login email, this call will initialize the sandbox and create 5 test client accounts, namely client_1+user@domain.com to client_5+user@domain.com for your sandbox account. While making this call you should not provide the clientEmail or clientCustomerId headers, since this call expects an MCC account to succeed. 

While making a getClientAccounts() call to the sandbox, set the SOAP headers as follows:

email: address of any google account, such as a Gmail account
password: password of the account
useragent: set to any identifying string
developerToken: set to the value for email, with the string '++USD' (or the currency code of your choice) appended
applicationToken: ignored, and could be set to anything or left out
clientEmail: should be either set to the empty string or left out
clientCustomerId: should be either set to the empty string or left out

The sandbox database is usually refreshed once every month, wiping out all client accounts. Making getClientAccounts() as your application's first API call ensures that all your calls happen against a properly initialized sandbox account.

Simulate error responses

Because a good application needs to gracefully handle errors thrown by the AdWords API, the sandbox provides a mechanism for simulating error messages. If you use user@domain.com++errorCode as the email for a call to the sandbox, the sandbox will return an error response with error code set as the desired errorCode, and a text message indicating that an error response has been forced by the sandbox. 

The error code should be set to one of the valid error codes. For instance, by providing login email as user@domain.com++17, I can simulate error code 17 (account exceeded maximum number of allowed campaigns). 

The SOAP response looks as follows:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Body>
    <soapenv:Fault>
      <faultcode>soapenv:Server.userException</faultcode>
      <faultstring>Error forced by the request (Sandbox)</faultstring>
      <detail>
        <ns1:fault xmlns:ns1="https://adwords.google.com/api/adwords/v13">
          <ns1:code>17</ns1:code>
          <ns1:message>Error forced by the request (Sandbox)</ns1:message>
          <ns1:trigger>user@domain.com++17</ns1:trigger>
        </ns1:fault>
      </detail>
    </soapenv:Fault>
  </soapenv:Body>
</soapenv:Envelope>

Similarly, you can also test for some policy violations in ads and keywords. For instance, providing repeated punctuation in the ad or keyword text, such as "Hello World!!" as the ad title, should trigger a policy violation error. However, the sandbox doesn't have all of the policy checks in place, so you can't test your application against every possible policy violation, e.g. trademark-related violations. 

Generate reports

Since generating reports is one of the most common calls in the AdWords API, the sandbox provides features to test each stage of your report generation logic. In the sandbox, you can create either a report whose status does not change, or a report whose status changes from pending to deleted. If you include any one of the following strings in the report name field while creating it, it will create a report with the specified status.

  • fixstatus=Pending
  • fixstatus=InProgress
  • fixstatus=Completed
  • fixstatus=Failed

If the name doesn't contain any of the above codes, the sandbox will create a report whose status changes as follows:

  • During the first minute since the report job was scheduled, the status is Pending.
  • During the second minute, the status is InProgress.
  • During the third minute, the status is Completed.
  • After the third minute, the report is deleted.

Also, a call to getAllJobs will return four reports, one for each value of ReportJobStatus. Sandbox reports do not return any data related to any live accounts. So if you want to test your report parsing logic against some live data, you can generate a report of the desired type in the Reports Center of your production account, download it in xml format, and use it to develop and test your code.  

Handling account limits

As with a live account, an AdWords sandbox account can hold a maximum of 25 active campaigns, with up to 100 active ad groups per campaign. If your program runs into these limits, then you can change the status of some campaigns or ad groups to "deleted."

TrafficEstimatorService and KeywordToolService behavior

Both TrafficEstimatorService and KeywordToolService are available for use in AdWords API sandbox. However, both these services return fake data. TrafficEstimatorService will give you fake data for Position, CPC, and Clicks per day. KeywordToolService can give you fake Seed-based keyword suggestions when using getKeywordVariations. It can also give you content-based keyword suggestions and SiteKeyword statistics when using getKeywordsFromSite.

The AdWords API sandbox can greatly help you with your development by preventing bugs from hitting production account during early stages of development. You can find more information on AdWords API sandbox at http://code.google.com/apis/adwords/docs/developer/adwords_api_sandbox.html.

-Anash P. Oommen, AdWords API Team

AdWords Downtime: March 14, 10am-2pm PDT

Tuesday, March 10, 2009


We'll be performing routine system maintenance on Saturday, March 14 from approximately 10:00am to 2:00pm PDT. You won't be able to access AdWords or the API during this time frame, but your ads will continue to run as normal.

Cheers,
-Jeffrey Posnick, AdWords API Team