Discover 201008: CustomerSyncService - So what’s new?

Wednesday, October 27, 2010


We recently released the second part of the v201008 version of the AdWords API and with it the CustomerSyncService - the AdWords API’s first service to determine the entities that were changed in your account. In this blog post, I’ll discuss our goals for the new service and provide a few examples illustrating how to integrate it with your system.

At our developer workshops, we received lots of great feedback about what you’d eventually like to see in this service. Please keep sharing your feedback with us on our forum.

Getting started

Central to the service is the CustomerSyncService.get method. You’ll use this method to retrieve all entities that have changed within the account for a given date time range and set of campaign IDs. As an example, to select all changes to campaign with id 12345 yesterday (today being October 27th), you would do something like:


// Create date time range.
DateTimeRange dateTimeRange = new DateTimeRange();
dateTimeRange.setMin(“20101026 000000”);
dateTimeRange.setMax(“20101027 000000”);

// Create selector.
CustomerSyncSelector selector = new CustomerSyncSelector();
selector.setDateTimeRange(dateTimeRange);
selector.setCampaignIds(new long[] {12345L});

// Get all account changes for campaign.
CustomerChangeData accountChanges = customerSyncService.get(selector);
The result will be a CustomerChangeData object with the entities that changed over the last day for the campaign specified; for the date time range you specified and the single campaign ID, you would only get one CampaignChangeData object back from within the accountChanges variable. If you had specified more than one campaign ID, you would get back one CampaignChangeData object per campaign.

Syncing up

The general way you can use the service is to:
  1. Get a full list of all current campaigns by performing a CampaignService.get with an empty selector and collect the IDs.
  2. Choose a date time range. This could depend on how granular you want your results, or when you last ran the service.
  3. Create a CustomerSyncSelector incorporating all of the campaign IDs and the date time range.
  4. Run CustomerSyncService.get with the selector.
  5. Process the results by traversing the CustomerChangeData object.
  6. Fetch the new data of the entties for all of the IDs within the CustomerChangeData hierarchy using their respective services
The goal of the CustomerSyncService is to give you a consolidated overview of what has changed over a time period; changes will be grouped together based on their overall outcome. Because of this, the dateTimeRange property will largely determine how your results are consolidated.

If you added a campaign to your account on the previous day, for example, you would receive a CampaignChangeData object with the campaignChangedStatus field set to NEW. Imagine now that you changed the campaign later that day as well. If the service returned a single CustomerChangeData object for each change, there would be two objects within the CustomerChangeData - one for the “new” event and one for the “modified” event. Instead, the two events will be consolidated into one object with the status set to NEW, not FIELDS_CHANGED. If you, however, split the service call into two date time ranges, one before the modification and one after, the first call would return a CampaignChangeData object with the status of NEW, and the second call would return a CampaignChangeData object with the status of FIELDS_CHANGED.

The same consolidation principle applies to child objects also. As an example, imagine you create a campaign, modify it later that day, then create an ad group, and then also modify that ad group later that day. The resulting CustomerChangeData object would resemble:

<rval>
...
  <changedCampaigns>
    <status>NEW</status>
    ...
  </changedCampaigns>
</rval>
Notice that not only is the status field is set to NEW, not FIELDS_CHANGED, but  also ad groups have been omitted even though they were also modified that day. Since the campaign is new, all of the entities within that object would also be new. Because of this, you would only get 1 CustomerChangeData object with no AdGroupChangeData within in it.

As a final example, imagine that you create an ad group into an existing campaign and modify the budget of the campaign during the same time period. The resulting CustomerChangeData object would be:

<rval>
...
  <changedCampaigns>
    <status>FIELDS_MODIFIED</status>
    ...
    <changedAdGroups>
        <status>NEW</status>
        ...
    </changedAdGroups>
  </changedCampaigns>
</rval>
Notice here that since the campaign already existed and the budget was changed, the status is FIELDS_MODIFIED. If the ad group had just been added, and the campaign budget left alone, the status for the campaign would be FIELDS_UNMODIFIED. Because you see the status is not FIELDS_UNMODIFIED, you know to fetch the campaign from the API, as well as the ad group, while syncing.

We believe the CustomerSyncService provides a great new way to save you time from scouring your account for changes. We’re looking forward to your feedback on our forum and look forward to seeing what you create with it.

-- Adam Rogal, AdWords API Team

Discover v201008: Remarketing

Thursday, October 21, 2010


Version v201008 of the AdWords API introduces the UserListService and the CriterionUserList which give you API access to the features available in the ‘Audiences’ tab in the AdWords interface. To learn more about remarketing, visit the AdWords Help Center.

You can set up remarketing using the AdWords API in two steps:

  1. Create a remarketing list.
  2. Create a CriterionUserList to tie your list to an AdGroup.

We’ve also included short code snippets showing you how to manage LogicalUserLists, also known as custom combination lists, and how to monitor your user list size.

Create a remarketing list

Creating a remarketing list involves the creation of two separate entities: the RemarketingList itself and its associated UserListConversionTypes also known as remarketing tags. The following code shows how to create a remarketing list.

// Get the UserListService.
UserListServiceInterface userListService =
    user.getService(AdWordsService.V201008.USER_LIST_SERVICE);

// Create conversion type (remarketing tag).
UserListConversionType conversionType = new UserListConversionType();
conversionType.setName("Mars cruise customers #" + System.currentTimeMillis());

// Create remarketing user list.
RemarketingUserList userList = new RemarketingUserList();
userList.setName("Mars cruise customers #" + System.currentTimeMillis());
userList.setDescription("A list of mars cruise customers in the last year");
userList.setMembershipLifeSpan(365L);
userList.setConversionTypes(new UserListConversionType[] {conversionType});

// Create operations.
UserListOperation operation = new UserListOperation();
operation.setOperand(userList);
operation.setOperator(Operator.ADD);

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

// Add user list.
userList = userListService.mutate(operations).getValue()[0];

Tie a remarketing list to an AdGroup

A new type of criteria object called CriterionUserList is now part of v201008. Through this type of criteria you are able to tie a UserList to an AdGroup. As with other types of criteria, this type is also managed through the AdGroupCriterionService. The following code shows you how to create a CriterionUserList and tie it to an existing AdGroup.

// Create user list criteria.
CriterionUserList userListCriteria = new CriterionUserList();
userListCriteria.setUserListId(userList.getId());

// Create biddable ad group criterion.
BiddableAdGroupCriterion userListBiddableAdGroupCriterion = new BiddableAdGroupCriterion();
userListBiddableAdGroupCriterion.setAdGroupId(adGroupId);
userListBiddableAdGroupCriterion.setCriterion(userListCriteria);

// Create operation.
AdGroupCriterionOperation userListAdGroupCriterionOperation = 
    new AdGroupCriterionOperation();
userListAdGroupCriterionOperation.setOperand(userListBiddableAdGroupCriterion);
userListAdGroupCriterionOperation.setOperator(Operator.ADD);

AdGroupCriterionOperation[] criteriaOperations =
    new AdGroupCriterionOperation[] {userListAdGroupCriterionOperation};

// Add ad group criteria.
adGroupCriterionService.mutate(criteriaOperations);

Custom combination list

It’s also possible through the API to create LogicalUserLists, also known as custom combination lists in the AdWords interface. A LogicalUserList lets you group together other UserLists, which includes RemarketingUserLists and other LogicalUserLists, through a series of UserListLogicalRules. The following code shows you how to create a simple LogicalUserList that combines two other remarketing lists, but it’s possible to create more complex combinations using this type of list.

// Remarketing user lists to be referenced.
UserList list1 = new RemarketingUserList();
list1.setId(remarketingUserListId1);

UserList list2 = new RemarketingUserList();
list2.setId(remarketingUserListId2);

// Create logical user list.
LogicalUserList logicalList = new LogicalUserList();
logicalList.setName("Logical list #" + System.currentTimeMillis());
logicalList.setDescription("A list of two other lists");
logicalList.setMembershipLifeSpan(365L);
logicalList.setRules(new UserListLogicalRule[] {
    new UserListLogicalRule(UserListLogicalRuleOperator.ALL,
       new LogicalUserListOperand[] {
            new LogicalUserListOperand(null, list1),
            new LogicalUserListOperand(null, list2),
    })
});

// Create operation.
UserListOperation operation = new UserListOperation();
operation.setOperand(logicalList);
operation.setOperator(Operator.ADD);

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

// Add user list.
UserListReturnValue result = userListService.mutate(operations);

Monitor the size of your list

You also might be interested in monitoring the growth of your list. You can accomplish this by making a simple get() call to the UserListService to retrieve this kind of information. The following code shows you how to retrieve information about all of your user lists.

// Create selector.
UserListSelector selector = new UserListSelector();

// Get all user lists.
UserListPage page = userListService.get(selector);

// Display user lists information.
if (page.getEntries() != null) {
  for (UserList userList : page.getEntries()) {
    System.out.printf("User list with name '%s' has an estimate size of '%d' users.\n",
        userList.getName(), userList.getSize());
  }
}

All code snippets included in this post are based on the AdWords API Java Client Library, other client libraries also include code examples and support for remarketing.

As always, please post your questions about how to use this new service on the forum.

Posted by David Torres, AdWords API Team

Enjoy more API units this holiday season

Wednesday, October 20, 2010


Last year, we provided you with a bonus of 20% more AdWords API units at no additional cost. We’re pleased to announce that we’re bringing back our holiday bonus this year. Starting now and extending through January 15, 2011, you’ll receive 20% more API units at no additional cost.

Here are the details:

  • Developers can purchase AdWords API units at the rate of 1250 for 0.25 USD, up from 1000 for 0.25 USD. Don’t forget that you can apply for preferred AdWords API pricing to receive free units.
  • Advertisers who are eligible for free units will receive credit at the rate of 300 units for every 1 USD of AdWords spend, up from 250 for every 1 USD of AdWords spend. They will be credited the holiday bonus based on their spend in previous months
You can view your AdWords API usage in your MCC account, by clicking the AdWords API Center link under the My Account tab.

You can use this as an opportunity to try out and take advantage of the many new features just released in version v201008. As always, we encourage you to use the AdWords API as efficiently as possible.

Happy Holidays,
Jason Shafton, Product Marketing Manager
on behalf of the entire AdWords API Team

Introducing two new ValueTrack parameters

Tuesday, October 19, 2010


We just announced two new ValueTrack parameters on the Inside AdWords blog. ValueTrack is a feature that helps you pass dynamic AdWords ad click information in your Destination URL. The new {matchtype} parameter provides you with the matchtype of the keyword for search ads (“b” for broad, “p” for phrase, and “e” for exact). The new {network} parameter gives you information about where the ad appeared (“g” for Google search, “s” for search partners, and “d” for display partners).

To learn more about how to implement all 13 ValueTrack parameters, visit the AdWords Help Center.

-- Jason Shafton, Product Marketing Manager

AdWords Downtime: October 16, 10am-2pm PDT

Thursday, October 14, 2010


We'll be performing routine system maintenance on Saturday, October 16 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.

Best,
- Eric Koleda, AdWords API Team 

Discover v201008 - ServicedAccountService

Tuesday, October 12, 2010


The ability to retrieve a list of client accounts and their details is useful when you’re managing a large number of accounts using the AdWords API. This was previously possible only with AccountService in the legacy v13 version of the AdWords API. The v201008 version introduces the ServicedAccountService, which brings similar functionality to the new AdWords API. This blog post discusses the differences between the old AccountService and the new ServicedAccountService.

Retrieving client account hierarchy

In v13, you could retrieve the list of client accounts linked to an MCC using the getClientAccounts or getClientAccountInfos methods of AccountService. In the v201008 version of the AdWords API, you can use the get method of ServicedAccountService to get the same results. The following code shows the service in action.

// Get the ServicedAccountService.
ServicedAccountService servicedAccountService =
    (ServicedAccountService) user.GetService(AdWordsService.v201008.
        ServicedAccountService);
 
ServicedAccountSelector selector = new ServicedAccountSelector();
 
try {
  ServicedAccountGraph graph = servicedAccountService.get(selector);
 
  if (graph != null && graph.accounts != null) {
    // Display the accounts.
    Console.WriteLine("There are {0} customers under this account" +
        " hierarchy.", graph.accounts.Length);
    for (int i = 0; i < graph.accounts.Length; i++) {
      Console.WriteLine("{0}) Customer id: {1}\nLogin email: {2}\n" +
          "Company name: {3}\nIsMCC: {4}\n", i + 1,
          graph.accounts[i].customerId, graph.accounts[i].login,
          graph.accounts[i].companyName,
          graph.accounts[i].canManageClients);
    }
  }
} catch (Exception ex) {
  Console.WriteLine("Failed to retrieve accounts. Exception says \"{0}\"",
      ex.Message);
}

ServicedAccountService also allows you to retrieve links that exist between the accounts. To retrieve the links, set the enablePaging field of ServicedAccountSelector to false. The following code shows how to retrieve account links:

selector.enablePaging = false;
selector.serviceTypes = new ServiceType[] { ServiceType.UI_AND_API,
    ServiceType.API_ONLY };
...
...
if (graph != null && graph.accounts != null) {
  // Display the accounts.
  ...
  ...
  // Display the links.
  foreach (Link link in graph.links) {
      Console.WriteLine("There is a {0} link of type {1} from" +
         "{2:###-###-####} to {3:###-###-####}", link.typeOfLink,
         link.serviceType, link.managerId.id, link.clientId.id);
  }
}

An important difference between AccountService.getClientAccounts and ServicedAccountService.get is that getClientAccounts returns only the immediate child accounts, whereas ServicedAccountService.get() returns all of the accounts in the hierarchy. This was harder to do in v13 as you first had to call getClientAccountInfos to find out whether or not a child account is a manager, and then recursively call getClientAccounts to navigate the entire account hierarchy.

To retrieve only the immediate child accounts of your MCC to mimic the behavior of v13’s getClientAccounts method, you can select the relevant accounts as follows:

private Account[] GetClientAccountsForMCC(ServicedAccountGraph graph,
    long mccId) {
  List retval = new List();
  foreach (Link link in graph.links) {
    if (link.managerId.id == mccId) {
      foreach (Account account in graph.accounts) {
        if (account.customerId == link.clientId.id) {
          retval.Add(account);
        }
      }
    }
  }
  return retval.ToArray();
}

Retrieving and updating account information

In v13, you can retrieve and update some fields of a client account using getAccountInfo and updateAccountInfo. This functionality isn’t yet available in v201008, but will be available in a future version of the AdWords API.

Retrieving MCC alerts

In v13, you could retrieve the MCC alerts about your child accounts using getMccAlerts. This functionality is now available through AlertService, another new service introduced in v201008. We will write more about AlertService in a future post.

Please check out this service and share your feedback with us on the forum.

-- Anash P. Oommen, AdWords API Team