Hide

AdWords API Objects

A common use case of the AdWords API is to manage campaigns in an AdWords account. This guide will introduce you to the basic AdWords objects like Campaign, AdGroup, etc. that are required for campaign management, explain how they are related to one another, and how to work with them.

We recommend that you brush up your knowledge of AdWords as an advertising platform, and basic concepts about how the AdWords API works before reading this guide. Code examples in this guide use the AdWords API Java library. If you are looking for a client library in another programming language, you can check our complete list of client libraries. Also, the use of a client library is recommended but optional; you may use any SOAP kit in the programming language of your choice to make calls to the API.

Hierarchy and scope

Every AdWords account can be viewed as a hierarchy of objects. Under each account, there are Campaigns that represent advertisement campaigns you are running. Each campaign has multiple AdGroups, which are used to group your ads into logical collections. Each AdGroup has multiple AdGroupAds and AdGroupCriteria. AdGroupAd represents an ad that you are running, and AdGroupCriterion represents a criterion (e.g. keyword) that defines how the ads get triggered.

You can designate criteria at the campaign level which define campaign-wide rules on how the ads get triggered. Finally, there are ad extensions at the campaign level that allow you to provide extra information like phone number, street address, etc. to your ads.

Every object in AdWords is identified by its own ID. Some of these IDs are unique on a global level, while others are only unique within a confined scope, i.e., not on a global level. The uniqueness of each object ID within AdWords is listed below.

Object ID Scope of uniqueness Globally unique?
Budget ID Global Yes
Campaign ID Global Yes
AdGroup ID Global Yes
Ad ID Ad Group No. (AdGroupId, AdId) pair is globally unique.
AdGroupCriterion ID Ad Group No. (AdGroupId, CriterionId) pair is globally unique.
CampaignCriterion ID Campaign No. (CampaignId, CriterionId) pair is globally unique.
Ad Extensions Campaign No. (CampaignId, AdExtensionId) pair is globally unique.
Feed ID Global Yes
Feed Item ID Global Yes
Feed Attribute ID Feed No
Feed Mapping ID Global Yes
Label ID Global Yes

The above ID rules can be useful when designing a local database to store your AdWords objects.

If an object is derived from another object, then it will also have a Type field. For instance, TextAd has a Type field to denote that it is derived from the Ad object. If you're using a dynamic language, you can use this field to check if an object is of a certain type, e.g., check if an Ad object is of type TextAd.

Methods and operations

The AdWords API provides services to manage AdWords objects. For instance, CampaignService manages Campaigns, AdGroupService manages AdGroups, and so on. All such services expose two standard methods: get and mutate.

The get method

As the name implies, get is used to retrieve AdWords objects. For instance, you can use CampaignService.get to retrieve the list of campaigns.

Every get method takes a Selector as input, and returns a Page as a result. The AdWords API doesn't return all the fields of an object by default; you need to specify the list of fields you want to retrieve when building the selector. You can use predicates to filter your results, ordering to sort your results and dateRange to limit the time period for which you are retrieving the results. You also need to specify paging if you are pulling a lot of objects since the AdWords API will raise a SizeLimitError.RESPONSE_SIZE_LIMIT_EXCEEDED error if you try to pull a lot of objects without paging. The following code snippet shows the above concepts in action, where we retrieve and display all the campaigns in an account.

final int PAGE_SIZE = 100;
int offset = 0;

// Create selector.
Selector selector = new Selector();
selector.setFields(new String[] {"Id", "Name"});
selector.setOrdering(new OrderBy[] {new OrderBy("Name", SortOrder.ASCENDING)});
selector.setPaging(new Paging(offset, PAGE_SIZE));

CampaignPage page = null;

do {
  // Get all campaigns.
  page = campaignService.get(selector);

  // Display campaigns.
  if (page.getEntries() != null) {
    for (Campaign campaign : page.getEntries()) {
      System.out.println("Campaign with name \"" + campaign.getName() +
          "\" and id \"" + campaign.getId() + "\" was found.");
    }
  } else {
    System.out.println("No campaigns were found.");
  }

  offset += PAGE_SIZE;
  selector.getPaging().setStartIndex(offset);
} while (offset < page.getTotalNumEntries());

You can learn more about selectors and their behaviors in this blog post or this video. In case you need to quickly look up the available selector fields for different services, you can refer to this guide.

Our client library distribution includes code examples for get methods of all the campaign management methods. For example, you can find the Java client library examples for campaign management services under the basicoperations and campaignmanagement folders of the code examples section.

The query method

The query method is an alternative to get that doesn't use selectors, but rather a SQL-like language called AWQL. The query method is supported by most common services, although there still may be a few where you have to use get. AWQL does not support mutating data.

To show the power of AWQL, consider the example above. Instead of spending four lines writing the selector, you could alternatively write a single string that contains all the same information.

String awql = "SELECT Id, Name ORDER BY Name ASC LIMIT " + offset + "," + PAGE_SIZE;

Note that there is no FROM clause. This is because the service whose query method you are using already dictates what you are selecting from. AWQL only supports the FROM clause when used for reports. To use this string, you would simply call the service's query method.

page = campaignService.query(awql);

The results of this call are the same as the results of the get call in the example above. Overall, this can be a more succinct and intuitive way to write the same requests as you would with a get call. Use whichever method you find easier; both are provided for your convenience. To learn more, see the AWQL guide.

The mutate method

As the name implies, the mutate method is used to mutate (create, update or remove) an AdWords object. To mutate any object, you need to build an appropriate Operation object. For instance, you need to create a CampaignOperation to mutate a Campaign. The operator field defines the type of operation you wish to perform (ADD, SET, REMOVE), and the operand field holds the object you want to mutate. This code snippet adds a campaign:

// Create campaign.
Campaign campaign = new Campaign();
campaign.setName("Interplanetary Cruise #" + System.currentTimeMillis());
campaign.setStatus(CampaignStatus.PAUSED);
campaign.setBiddingStrategy(new ManualCPC());

// You can optionally provide these field(s).
campaign.setStartDate(new DateTime().plusDays(1).toString("yyyyMMdd"));
campaign.setEndDate(new DateTime().plusDays(30).toString("yyyyMMdd"));
campaign.setAdServingOptimizationStatus(AdServingOptimizationStatus.ROTATE);
campaign.setFrequencyCap(new FrequencyCap(5L, TimeUnit.DAY, Level.ADGROUP));

// Only the budgetId should be sent, all other fields will be ignored by CampaignService.
// You can use BudgetService to create a shared budget.
Budget budget = new Budget();
budget.setBudgetId(budgetId);
campaign.setBudget(budget);

// Set the campaign network options to Search and Search Network.
NetworkSetting networkSetting = new NetworkSetting();
networkSetting.setTargetGoogleSearch(true);
networkSetting.setTargetSearchNetwork(true);
networkSetting.setTargetContentNetwork(false);
networkSetting.setTargetPartnerSearchNetwork(false);
campaign.setNetworkSetting(networkSetting);

GeoTargetTypeSetting geoTarget = new GeoTargetTypeSetting();
geoTarget.setPositiveGeoTargetType(GeoTargetTypeSettingPositiveGeoTargetType.DONT_CARE);
KeywordMatchSetting keywordMatch = new KeywordMatchSetting();
keywordMatch.setOptIn(Boolean.FALSE);

TargetRestrictSetting targetRestrict = new TargetRestrictSetting();
targetRestrict.setUseAdGroup(Boolean.TRUE);
campaign.setSettings(new Setting[] {geoTarget, keywordMatch, targetRestrict});

// Create operations.
CampaignOperation operation = new CampaignOperation();
operation.setOperand(campaign);
operation.setOperator(Operator.ADD);

CampaignOperation[] operations = new CampaignOperation[] {operation};

// Add campaigns.
CampaignReturnValue result = campaignService.mutate(operations);

// Display campaigns.
for (Campaign campaignResult : result.getValue()) {
   System.out.println("Campaign with name \"" + campaignResult.getName()
       + "\" and id \"" + campaignResult.getId() + "\" was added.");
}

Our client library distribution includes code examples for the mutate method of all the campaign management services. For example, you can find the Java client library examples for campaign management services under the basicoperations and campaignmanagement folders of the code examples section.

A common question associated with mutating objects is about the number of objects of a given type an AdWords account can hold. The limits for various types of AdWords objects are listed in this help center article. However, you should use this limit only as a guide when planning your campaigns and should not hard code these limits into your application.

Another point to keep in mind while making mutate calls is that it is better to send multiple operations per request than sending multiple requests with one operation per request, since this reduces the number of roundtrips to the server and thus increase your application performance. You should also try to group your requests by operations to a particular parent entity to increase performance. For example, if you are adding ads, then try to group your requests to add ads to one ad group at a time instead of a single request that adds ads to multiple ad groups. You can read more about these on our best practices guide.

The operator field

As discussed previously with the mutate method, the operator field tells the AdWords API the nature of the mutate operation you wish to perform - ADD, SET or REMOVE. As the name implies, ADD is for creating a new object, SET is for updating an existing object, and REMOVE is for removing an existing object. However, depending on how AdWords manages a certain type of object, some of the operators may not be applicable for some services.

For example, an AdWords campaign cannot be permanently removed once you create it—you can only mark it as removed. While it is "removed" you can still query its details and stats.

The AdWords API doesn't support the REMOVE operator in CampaignService; you need to update a Campaign by changing its status to REMOVED using the SET operator. On the other hand, campaign targets are immutable—you can only use ADD or REMOVE on these objects. More details on how AdWords treats different objects are shown below:

Type Newly Added Enabled Paused Removed / Disabled
Campaign action : mutate
operation: ADD
status : ENABLED
action : mutate
operation: SET
status : ENABLED
action : mutate
operation: SET
status: PAUSED
action : mutate
operation : SET
status: REMOVED
AdGroup action: mutate
operation: ADD
status: ENABLED
action : mutate
operation: SET
status : ENABLED
action: mutate
operation: SET
status : PAUSED
action : mutate
operation: SET
status: REMOVED
AdGroupAd action : mutate
operation: ADD
status: ENABLED
action : mutate
operation : SET
status : ENABLED
action : mutate
operation : SET
status : PAUSED
action: mutate
operation : REMOVE
status: DISABLED
BiddableAdGroupCriterion action: mutate
operation: ADD
status: ENABLED
action: mutate
operation: SET
status: ENABLED
action: mutate
operation: SET
status: PAUSED
action: mutate
operation: REMOVE
status: REMOVED
UserList action: mutate
operation: ADD
status: OPEN
N/A N/A action: mutate
operation: SET
status: CLOSED
Experiment action: mutate
operation: ADD
status: ENABLED
N/A N/A action: mutate
operation: SET
status: REMOVED
Feed action: mutate
operation: ADD
status: ENABLED
N/A N/A action: mutate
operation: REMOVE
status: REMOVED
FeedMapping action: mutate
operation: ADD
status: ENABLED
N/A N/A action: mutate
operation: REMOVE
status: REMOVED
FeedItem action: mutate
operation: ADD
status: ENABLED
N/A N/A action: mutate
operation: REMOVE
status: REMOVED
CustomerFeed action: mutate
operation: ADD
status: ENABLED
N/A N/A action: mutate
operation: REMOVE
status: REMOVED
CampaignFeed action: mutate
operation: ADD
status: ENABLED
N/A N/A action: mutate
operation: REMOVE
status: REMOVED
AdGroupFeed action: mutate
operation: ADD
status: ENABLED
N/A N/A action: mutate
operation: REMOVE
status: REMOVED

Concurrent mutates

When building an AdWords API application, you will often find yourself mutating AdWords objects in parallel, such as when you are using multiple threads to get better throughput for your application, or maybe you have multiple users updating the same object using your application. So it is important to understand how AdWords handles concurrent mutate requests for the same object and to develop your application accordingly.

The general rule of mutating an AdWords object is that you cannot modify the same object concurrently. This includes updating the object from multiple threads in the same application or from different applications (e.g. your application and a simultaneous AdWords Editor session). The AdWords API doesn't provide a way to lock an object before updating, rather, it uses an optimistic approach for locking the objects. If the AdWords API finds that an object is being updated simultaneously by more than one source, it will raise a CONCURRENT_MODIFICATION_ERROR. You can learn more about AdWords API concurrency management in this blog post.

Asynchronous vs. synchronous mutates

AdWords API mutate methods are synchronous—meaning that if you make an API call, then the call returns only after the objects are mutated, or the call fails. While this approach is relatively simple to code, you also need to worry about several other things like load balancing, wasted resources while the machines wait for API calls to complete, etc.

An alternate approach is to mutate the objects asynchronously using MutateJobService. Using MutateJobService, you can create jobs that consist of potentially large batches of operations. Once the job is submitted, AdWords API servers execute the jobs in an asynchronous manner. This frees up your machine to perform other operations and periodically check the job status for completion. Another benefit of using asynchronous APIs is that they incur only 50% of the API cost of synchronous API calls. You can learn more about asynchronous APIs in this video or in batch processing guide.

Mutate validation

The validateOnly SOAP header allows you to test your API calls, without having to change any data. It is useful in checking for missing parameters and incorrect field values. To use this feature, set RequestHeader's validateOnly field to true. The client libraries set this to false by default.

When overridden to true, your request will be fully validated as if it were going to be executed, but the final execution will be skipped. An empty response will be returned if there are no errors. If validation fails, useful error messages will be returned with messages about what failed.

Here's an example of how to set up validateOnly using our Java library.

Credential oAuth2Credential = new OfflineCredentials.Builder()
    .forApi(Api.ADWORDS)
    .fromFile()
    .build()
    .generateCredential();

AdWordsSession session = new AdWordsSession.Builder()
    .fromFile()
    .withOAuth2Credential(oAuth2Credential)
    .build();

session.setValidateOnly(true);

All API calls made using this session will now have the validateOnly header set to true.

The validateOnly header is particularly useful in checking ads for common policy violations. Sometimes ads can be automatically rejected if they fail certain criteria, like using specific words, punctuation, capitalization, or length. If you try to upload ads in batches, one bad ad could cause your entire batch to fail. Testing a new ad with validateOnly will allow you to easily see which ads would be rejected. You can refer to this code example to see this application in action.

Even without using the client library, all you need to do is set up the right SOAP header and you can still validate your mutate requests.

Send feedback about...

AdWords API