If you're still on v201609, please migrate to a newer version before October 2, 2017.

Location Extensions

Location extensions allow you to show a business address, phone number and a map marker along with your ad text. Location extensions come in two flavors:

  • AdWords location extensions help people find your locations by showing your ads with your address, a map to your location, or the distance to your business. This extension type is useful to draw customers to your brick-and-mortar location.

  • Affiliate location extensions help people find nearby stores of a retail chain that sell your products. This extension type is useful if you sell your products through retail chains, and want to reach consumers when they are deciding what and where to buy.

AdWords location extensions

AdWords location extensions allow you to show your business address, phone number and a map marker along with your ad text. The locations are managed either through the Google My Business Location Manager or the Google My Business API. The following section shows an end-to-end example of how to create business locations using the Google My Business API and how to link them to your ads using the AdWords API.

Google My Business

Google My Business (GMB) is the central repository for your business locations across all Google products. You don't have to worry about keeping your Google My Business locations and AdWords location extensions in sync. Simply perform a one-time setup of the required feed objects and you're done! AdWords will automatically keep its location extensions synchronized to the latest data from your Google My Business account.

This section guides you through creating business locations programmatically using the Google My Business API and linking them to AdWords by creating the required feed objects. If you want to use the Google My Business Location Manager for creating your locations, skip the following sections and jump right to step 3 in the following process.

Procedure

If you aren't familiar with the concept of feeds in AdWords, read the feed guide for sitelinks. These instructions build off of that guide.

The steps to create and link business locations are as follows:

  1. Authenticate for Google My Business and AdWords API calls (OAuth 2.0).

  2. Create a new location using the Google My Business API.

    1. Use accounts.list to retrieve the Google My Business accounts that you own or have management rights on.
    2. Select the account to work with (for example, AccountType = BUSINESS).
    3. Create the location and specify a label, address, business hours, etc.
  3. Create a new location extensions feed linked to your Google My Business account.

    1. Set systemFeedGenerationData to a PlacesLocationFeedData object containing information about your Google My Business account.
    2. Set origin to ADWORDS.
    3. Do not specify any feedAttributes. AdWords will create these for you automatically because this is a system-generated feed.
    4. Perform a FeedService.mutate() ADD operation.
  4. Associate the feed with the customer.

    1. Use the feedId from step 3.
    2. Use placeholder type 7 for LOCATION.
    3. Use an appropriate matchingFunction.
    4. Perform a CustomerFeedService.mutate() ADD operation.
  5. (Optional) Associate the feed to specific campaigns or ad groups.

    1. Use the feedId from step 3.
    2. Use placeholder type 7 for LOCATION.
    3. Use a matchingFunction to filter based on the label from step 2c.
    4. Perform a CampaignFeedService.mutate() ADD or AdGroupFeedService.mutate() ADD operation.

If you're familiar with feeds for other extensions, you may have noticed that the steps above did not include creating a FeedMapping. Since this feed is a system-generated feed, AdWords already knows how to map the feed's attributes to the placeholder fields for location extensions. There's no need for you to provide that information. The following sections explain how to set the systemFeedGenerationData object when creating a new feed (step 3a). See below for a code example that brings all the pieces together.

Creating the PlacesLocationFeedData object on the feed

Setting the systemFeedGenerationData attribute on your feed tells AdWords to:

  • Link your Google My Business and AdWords accounts.
  • Automatically create feed attributes for your feed.
  • Automatically create a FeedMapping for your feed and the location targeting criterionType (77).
  • (Optional) Limit the set of locations that AdWords syncs from your Google My Business account.

Set the attributes of your PlacesLocationFeedData object as follows:

Attribute Required Description
emailAddress Yes The email address of your Google My Business account owner or one of its managers. This must match the email address provided in oAuthInfo.
oAuthInfo Yes OAuth2 information that grants your AdWords account access to your Google My Business account.
businessAccountIdentifier No The account ID of the managed business whose locations are to be used. If you are using the Google My Business API, you can get this ID from the account_id portion of the name of the Account. Otherwise, you can copy the BUSINESS_ACCOUNT_ID portion from the business URL of the form:
https://business.google.com/b/BUSINESS_ACCOUNT_ID/...
businessNameFilter No Name of the business to sync to AdWords.
categoryFilters No Categories of the listings to sync to AdWords.
labelFilters No Labels of the listings to sync to AdWords.

Creating the OAuthInfo object on the PlacesLocationFeedData

The oAuthInfo attribute on your PlacesLocationFeedData provides the information required to ensure that your AdWords account is allowed to read locations from your Google My Business account.

Set the attributes of your OAuthInfo object as follows:

Attribute Value Description
httpMethod GET or PUT The HTTP method for getting authorization information.
httpRequestUrl https://www.googleapis.com/auth/adwords The OAuth scope that the AdWords API uses to authorize your requests to Google My Business.
httpAuthorizationHeader Bearer OAUTH_ACCESS_TOKEN The authorization header containing the OAuth access token that grants your AdWords account permission to read from your Google My Business account. In place of OAUTH_ACCESS_TOKEN, substitute an access token generated from OAuth credentials for the emailAddress of the PlacesLocationFeedData and a scope matching httpRequestUrl.

Complete code example

The following code uses the Java client libraries for both the Google My Business API and the AdWords API. Refer to the respective instructions for setting up for your particular language.

Step 1: Authenticate for Google My Business and AdWords API calls (OAuth 2.0)

// Creating the default factory and transport (used later)
JsonFactory jsonFactory = JacksonFactory.getDefaultInstance();
HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();

// Load the credentials from the ads.properties file.
// Please note: This example assumes that your AdWords and MyBusiness accounts
// are linked to the same Google account, and that the Adwords API scope
// (https://www.googleapis.com/auth/adwords) was used when generating the
// refresh token.
// If you are using different Google accounts, you must authenticate
// separately and maintain two credentials (see
// /my-business/content/set-up-java-client).
Credential credential =
    new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .withHttpTransport(httpTransport)
        .fromFile()
        .build()
        .generateCredential();

Step 2: Create a new location using the Google My Business API

// Initialize GMB.
Mybusiness gmb =
    new Mybusiness.Builder(httpTransport, jsonFactory, credential)
        .setApplicationName(APPLICATION_NAME)
        .build();
// Get list of GMB accounts (2a).
Mybusiness.Accounts.List listAccounts = gmb.accounts().list();
ListAccountsResponse response = listAccounts.execute();
List<Account> accounts = response.getAccounts();

// Find the account to work with (2b). The first BUSINESS account is used
// here, but you can use any other account as well (e.g., PERSONAL).
Account mainAccount = null;
for (Account account : accounts) {
  if (account.getType().equalsIgnoreCase("BUSINESS")) {
    mainAccount = account;
    break;
  }
}
if (mainAccount == null) {
  throw new RuntimeException("Main GMB account not found");
}
// Create the location (2c).
Location location = new Location();
location.setLocationName("My Company");
location.setStoreCode("Company-1");
location.setPrimaryPhone("16505550001");
location.setPrimaryCategory(new Category().setCategoryId("gcid:software_company"));
location.setWebsiteUrl("https://www.example.com/");
// Create an address.
Address address = new Address();
List<String> addressLines = new ArrayList<String>();
addressLines.add("1600 Amphitheatre Pkwy");
address.setAddressLines(addressLines);
address.setLocality("Mountain View");
address.setAdministrativeArea("CA");
address.setCountry("US");
address.setPostalCode("94043");
location.setAddress(address);
// Create business hours (optional).
BusinessHours businessHours = new BusinessHours();
List<TimePeriod> periods = new ArrayList<TimePeriod>();
List<String> days =
    Arrays.asList("Monday", "Tuesday", "Wednesday", "Thursday", "Friday");
for (String day : days) {
  TimePeriod period = new TimePeriod();
  period.setOpenDay(day);
  period.setOpenTime("9:00");
  period.setCloseTime("17:00");
  period.setCloseDay(day);
  periods.add(period);
}
businessHours.setPeriods(periods);
location.setRegularHours(businessHours);

// Assign a label to the location (optional). This example uses the AdWords
// customer ID as a label to associate the location with an ad group in AdWords.
// You can use any label value to identify locations, or no label at all
// (e.g., filter by business name or category).
location.setLabels(Collections.singletonList(INSERT_CUSTOMER_ID_HERE));
CreateLocationRequest createLocationRequest = new CreateLocationRequest();
createLocationRequest.setLocation(location);
createLocationRequest.setLanguageCode("en-US");
// Use a random request ID.
createLocationRequest.setRequestId(UUID.randomUUID().toString());
Mybusiness.Accounts.Locations.Create createLocation =
    gmb.accounts().locations().create(mainAccount.getName(),
    createLocationRequest);
Location createdLocation = createLocation.execute();

Step 3: Creating a new feed linked to your Google My Business

// Initialize AdWords.
AdWordsSession session = new AdWordsSession.Builder()
    .fromFile()
    .withOAuth2Credential(credential)
    .build();
session.setClientCustomerId(INSERT_CUSTOMER_ID_HERE);
AdWordsServices services = new AdWordsServices();
FeedServiceInterface feedService =
    services.get(session, FeedServiceInterface.class);
// Create the feed object.
Feed gmbFeed = new Feed();
gmbFeed.setName("GMB feed #" + System.currentTimeMillis());
// Create the PlacesLocationFeedData object (3a).
PlacesLocationFeedData feedData = new PlacesLocationFeedData();
feedData.setEmailAddress(GMB_ACCOUNT_EMAIL);
OAuthInfo oAuthInfo = new OAuthInfo();
oAuthInfo.setHttpMethod("GET");
oAuthInfo.setHttpRequestUrl(
    "https://www.googleapis.com/auth/adwords");
oAuthInfo.setHttpAuthorizationHeader(
    String.format("Bearer %s", credential.getAccessToken()));
feedData.setOAuthInfo(oAuthInfo);
gmbFeed.setSystemFeedGenerationData(feedData);
// Since this feed's feed items will be managed by AdWords,
// you must set its origin to ADWORDS (3b).
gmbFeed.setOrigin(FeedOrigin.ADWORDS);
// Note: No feed attributes for the feed were specified, as this is a
// system-generated feed (3c).
// Create an operation to add the feed.
FeedOperation feedOperation = new FeedOperation();
feedOperation.setOperand(gmbFeed);
feedOperation.setOperator(Operator.ADD);
// Add the feed (3d).
FeedReturnValue addFeedResult = feedService.mutate(
    new FeedOperation[] {feedOperation});
Feed createdFeed = addFeedResult.getValue(0);

Step 4: Associate the feed to the customer

CustomerFeedServiceInterface customerFeedService =
    services.get(session, CustomerFeedServiceInterface.class);
CustomerFeed customerFeed = new CustomerFeed();
// Set feedId and placeholder type (4a + 4b).
customerFeed.setFeedId(createdFeed.getId());
customerFeed.setPlaceholderTypes(new int[] {PLACEHOLDER_LOCATION});
// Create a matching function that will always evaluate to true (4c).
Function customerMatchingFunction = new Function();
ConstantOperand constOperand = new ConstantOperand();
constOperand.setType(ConstantOperandConstantType.BOOLEAN);
constOperand.setBooleanValue(true);
customerMatchingFunction.setLhsOperand(
    new FunctionArgumentOperand[] {constOperand});
customerMatchingFunction.setOperator(FunctionOperator.IDENTITY);
customerFeed.setMatchingFunction(customerMatchingFunction);
// Create an operation to add the customer feed.
CustomerFeedOperation customerFeedOperation = new CustomerFeedOperation();
customerFeedOperation.setOperand(customerFeed);
customerFeedOperation.setOperator(Operator.ADD);
// Add the feed (4d).
CustomerFeedReturnValue customerFeedResult = customerFeedService.mutate(
    new CustomerFeedOperation[] {customerFeedOperation});
CustomerFeed createdCustomerFeed = customerFeedResult.getValue(0);

Step 5: Associate the feed to specific ad groups (similar for campaigns)

AdGroupFeedServiceInterface adgroupFeedService =
    services.get(session, AdGroupFeedServiceInterface.class);
// Create the ad group feed.
AdGroupFeed adgroupFeed = new AdGroupFeed();
adgroupFeed.setAdGroupId(AD_GROUP_ID);
// Set feedId and placeholder type (5a + 5b).
adgroupFeed.setFeedId(createdFeed.getId());
adgroupFeed.setPlaceholderTypes(new int[] {PLACEHOLDER_LOCATION});
// Define matching function based on the label (5c).
Function matchingFunction = new Function();
String matchingFunctionString = String.format(
    "EQUALS(FeedAttribute[%d, 14], \"%s\")",
    createdFeed.getId(),
    createdLocation.getLabels().get(0));
matchingFunction.setFunctionString(matchingFunctionString);
adgroupFeed.setMatchingFunction(matchingFunction);
// Create an operation to add the ad group feed.
AdGroupFeedOperation operation = new AdGroupFeedOperation();
operation.setOperand(adgroupFeed);
operation.setOperator(Operator.ADD);
// Add the feed (5d).
AdGroupFeedReturnValue result = adgroupFeedService.mutate(
    new AdGroupFeedOperation[]{operation});
AdGroupFeed createdAdGroupFeed = result.getValue(0);

Filtering location extensions

Location extensions are automatically applied to every campaign and ad group under the account. You can apply location extensions to a specific ad group or campaign through filters.

Filtering strategies

Location extensions let you define location filters at several levels of your account using various mechanisms. Use the matchingFunction of a CampaignFeed or AdGroupFeed if you want different locations to appear on ads for different campaigns or ad groups.

The most specific filter takes precedence. For example, let's say you have:

  • a CustomerFeed
  • a CampaignFeed for campaign A
  • an AdGroupFeed for ad group G in campaign A
  • another campaign B that has neither a CampaignFeed nor an AdGroupFeed

With this setup you will get the following behavior (the dotted lines show which matching function is used for which ad):

  • Ads serving for ad group G will only show location extensions for items that match the matching function of the AdGroupFeed.
  • Ads serving for all other ad groups in campaign A will only show location extensions for items that match the matching function of the CampaignFeed.
  • Ads serving for campaign B will show location extensions for items that match the matching function of the CustomerFeed.

Using attributes for filtering

Filters in feed objects limit the feed items that sync via the businessNameFilter, categoryFilters, or labelFilters attributes of the PlacesLocationFeedData object. In addition, filters in the other objects determine which feed items in AdWords will be used as location extensions for a given combination of customer, campaign, and ad group. You might use these filters if:

  • You are using the same Google My Business account with multiple AdWords accounts and each AdWords account is logically associated with a subset of locations.
  • You have locations in your Google My Business account that you don't ever want to show up in ads.

For an account, campaign, or ad group, you can specify matchingFunctions for filtering based on any of the attributes available in the location extensions feed. We recommend filtering based on the following attributes:

  • Labels (Placeholder 14): By specifying labels for each location in Google My Business and using these labels for filtering in AdWords, you can customize your filtering entirely. For example, you can use the customer ID or a unique ID generated by your application.

    If labelFilters is specified, only listings that have any of the specified labels are candidates to be synchronized into FeedItems. If labelFilters has no entries, then all listings are candidates for syncing. In addition, all labels of a Google My Business listing are synced to a feed attribute with feedAttributeId = 14 and type = STRING_LIST. You can filter for feed items that have one or more labels by specifying a condition in your matching function as follows:

    CONTAINS_ANY(FeedAttribute[FeedId,14],{"label1","label2","label3"})
    
  • Business name (Placeholder 1): You can use the business name of the location for granular filtering.

  • Business category (Placeholder 9): Filtering by categories allows you to define broader matches or resolve ambiguity when AND-combined with business name.

Automatic removal of invalid filters

AdWords will perform a daily check of the filters defined for your location extensions. If it determines that no Google My Business locations are matching the filter, it will take the following steps to remove the filter:

Filter location Steps to remove filter
PlacesLocationFeedData Set the following attributes of the PlacesLocationFeedData to null:
  • businessNameFilter
  • categoryFilters
  • labelFilters
CampaignFeed Remove the CampaignFeed.
AdGroupFeed Remove the AdGroupFeed.

Next steps

See the matching functions guide to learn more about filtering by feed attribute ID, and the sitelinks feed guide for examples of how to create ad group and campaign feeds.

Affiliate location extensions

If you sell your products through retail chains, affiliate location extensions can help you reach consumers when they are deciding what and where to buy. Affiliate location extensions are similar to location extensions with Google My Business (GMB), but they differ in the following aspects:

GMB location extension Affiliate location extension
Advertiser should link to a GMB account first. No linking to GMB accounts.
Feed locations are created from locations in the GMB account. Feed locations are populated by AdWords based on a chain ID.
Only one feed is allowed per account. Multiple feeds allowed per account.

Procedure

The procedure for setting up affiliate location extensions is similar to the one for creating location extensions with Google My Business.

  1. Create a new affiliate location extensions feed.
  2. Associate the feed to a customer, a campaign, or ad group.

Step 1: Create a new affiliate location extensions feed.

To use affiliate location extensions, you need to create a new affiliate location extensions feed in your account. If you aren't familiar with the concept of feeds in AdWords, read the feed guide for sitelinks. These instructions build off of that guide.

Start by initializing the AdWords session and services.

// Generate a refreshable OAuth2 credential.
Credential oAuth2Credential =
    new OfflineCredentials.Builder()
        .forApi(Api.ADWORDS)
        .fromFile()
        .build()
        .generateCredential();

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

AdWordsServicesInterface adWordsServices = AdWordsServices.getInstance();

Next, create a feed and set its systemFeedGenerationData to an AffiliateLocationFeedData object containing information about the retail chains that sell your products. Make sure you mark the feed as a system-generated feed by setting its origin to ADWORDS.

// Create a feed that will be populated with all the addresses that correspond to the chain ID
// you requested. Do not add FeedAttributes to this object, as AdWords will add them
// automatically because this will be a system generated feed.
Feed affiliateFeed = new Feed();
affiliateFeed.setName("Affiliate location extension feed " + System.currentTimeMillis());

Chain chain = new Chain();
chain.setChainId(chainId);

// Since this feed's feed items will be managed by AdWords, you must set its origin to ADWORDS.
affiliateFeed.setOrigin(FeedOrigin.ADWORDS);

// Set the system feed generation data for AdWords.
AffiliateLocationFeedData feedData = new AffiliateLocationFeedData();
feedData.setChains(new Chain[] {chain});
feedData.setRelationshipType(RelationshipType.GENERAL_RETAILERS);

affiliateFeed.setSystemFeedGenerationData(feedData);

// Create an operation to add the feed.
FeedOperation feedOperation = new FeedOperation();
feedOperation.setOperand(affiliateFeed);
feedOperation.setOperator(Operator.ADD);

FeedReturnValue addFeedResult = feedService.mutate(new FeedOperation[] {feedOperation});
return addFeedResult.getValue(0);
Understanding the AffiliateLocationFeedData object

As with location extension feeds, you don't need to create a FeedMapping or feedAttributes for affiliate location extension feeds. Since this feed is a system-generated feed, AdWords uses the systemFeedGenerationData attribute on your feed to perform the following operations:

  • Automatically create feed attributes for your feed.
  • Automatically create a FeedMapping for your feed.
  • Populate the feed with a list of locations that corresponds to the retail chains that you specified in the systemFeedGenerationData

Set the attributes of your AffiliateLocationFeedData object as follows:

Attribute Required Description
chains Yes The list of chains that you wish to advertise. See the list of valid chain IDs.
relationshipType Yes The relationship type between the advertiser and retail chains.
Waiting for the feed setup to be complete

As with location extension feeds, you need to wait for the affiliate location feed to be ready before it can be associated with the customer. The approach is similar to the way it is done for a location extension feed, except that you need to filter for PLACEHOLDER ID = 30 when calling FeedMappingService.query().

FeedMappingServiceInterface feedMappingService =
    adWordsServices.get(session, FeedMappingServiceInterface.class);

String query =
    String.format(
        "SELECT FeedId, FeedMappingId, AttributeFieldMappings WHERE "
            + "FeedId = %d AND PlaceholderType = %d AND Status = ENABLED",
        feed.getId(), PLACEHOLDER_AFFILIATE_LOCATION);

FeedMapping retval = null;
FeedMappingPage page = null;

int numberOfAttempts = 0;
do {
  numberOfAttempts++;
  page = feedMappingService.query(query);

  if (page.getTotalNumEntries() == 0) {
    long sleepSeconds = (long) Math.scalb(5, numberOfAttempts);
    System.out.printf(
        "Attempt #%d to get FeedMapping was not successful. "
            + "Waiting %d seconds before trying again.%n",
        numberOfAttempts, sleepSeconds);
    Thread.sleep(sleepSeconds * 1000);
  } else {
    retval = page.getEntries(0);
    break;
  }

} while (numberOfAttempts < MAX_FEED_MAPPING_POLL_ATTEMPTS);

if (retval == null) {
  throw new IllegalStateException("Affiliate location feedmapping isn't setup correctly.");
}
return retval;

Step 2: Associate the feed to a customer, campaign, or ad group

Once the feed is ready to use, you can create a CampaignFeed object to associate it with a campaign. Associating the feed to an ad group or the customer is similar, except that you'd create an AdGroupFeed or CustomerFeed object, respectively, and use an appropriate matching function.

The following code snippet filters the affiliate location extensions for a campaign to serve only locations from a single retail chain ID.

/**
 * The placeholder ID for affiliate locations. See
 * https://developers.google.com/adwords/api/docs/appendix/placeholders for a complete list of
 * valid values.
 */
private static final int PLACEHOLDER_AFFILIATE_LOCATION = 30;

/** Placeholder feed ID for chain ID attribute. */
private static final int PLACEHOLDER_FIELD_CHAIN_ID = 10;

...

CampaignFeedServiceInterface campaignFeedService =
    adWordsServices.get(session, CampaignFeedServiceInterface.class);

CampaignFeed campaignFeed = new CampaignFeed();
campaignFeed.setPlaceholderTypes(new int[] {PLACEHOLDER_AFFILIATE_LOCATION});

campaignFeed.setCampaignId(campaignId);
campaignFeed.setFeedId(feed.getId());

Function matchingFunction = new Function();
matchingFunction.setFunctionString(
    String.format(
        "IN(FeedAttribute[%d, %d], {%d})", feed.getId(), attributeIdForChainId, chainId));

campaignFeed.setMatchingFunction(matchingFunction);

CampaignFeedOperation operation = new CampaignFeedOperation();
operation.setOperator(Operator.ADD);
operation.setOperand(campaignFeed);

CampaignFeedReturnValue addedCampaignFeedResult =
    campaignFeedService.mutate(new CampaignFeedOperation[] {operation});
return addedCampaignFeedResult.getValue(0);

The feed attribute ID can be retrieved from the feed's FeedMapping as follows:

/**
 * The placeholder ID for affiliate locations. See
 * https://developers.google.com/adwords/api/docs/appendix/placeholders for a complete list of
 * valid values.
 */
private static final int PLACEHOLDER_AFFILIATE_LOCATION = 30;

/** Placeholder feed ID for chain ID attribute. */
private static final int PLACEHOLDER_FIELD_CHAIN_ID = 10;

...

for (AttributeFieldMapping fieldMapping : feedMapping.getAttributeFieldMappings()) {
  if (fieldMapping.getFieldId() == PLACEHOLDER_FIELD_CHAIN_ID) {
    return fieldMapping.getFeedAttributeId();
  }
}
throw new IllegalStateException("Affiliate location feed mapping isn't setup correctly.");

Valid matching functions

The following table shows the list of supported matching functions, and their common use cases.

Use case Matching function Remarks
Filter by chain ID IN(FeedAttribute[FeedId, ChainAttributeId], {"CH1234", "CH2345"}) You can filter for up to a maximum of 20 chain IDs.
Target an entity for all locations in the feed IDENTITY(true)
Turn off affiliate locations for an entity IDENTITY(false)

Send feedback about...

AdWords API
AdWords API
Need help? Visit our support page.