Google Ads location extensions

To create Google Ads location extensions, you need to create a Google My Business (GMB) account and populate it with the addresses of all your business locations. Then, associate the GMB account with your location extensions feed to create the location extensions.

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 Google Ads location extensions in sync. Simply perform a one-time setup of the required feed objects for you. Google Ads will automatically keep its location extensions synchronized to the latest data from your Google My Business account.

There are two ways to create locations in Google My Business.

  1. You can use the Google My Business Location Manager for creating your locations. If you follow this approach, you can jump right to linking the locations to your ads using the Google Ads API.
  2. You can use the Google My Business API to create business locations programmatically.

Working with the Google My Business API

To get started with the Google My Business API, visit its home page. We recommend using business accounts rather than personal ones for locations linked to Google Ads. By using a business account, you can share access with other users without having to share your personal account details.

To create business locations programmatically using the Google My Business API,

  1. Start by downloading a client library. Follow the Basic setup guide to create OAuth credentials to work with the Google My Business API.

  2. Use the GMB API to list all the accounts that you own or have management rights on. Select the account to work with.

  3. Use the GMB API to create the locations.

Create a new location extensions feed linked to your GMB account

To create a new location extensions feed, start by creating a Feed object. Perform a FeedService.MutateFeeds create operation to create the feed. The code snippet is shown below.

C#

private static string CreateGMBFeed(GoogleAdsClient client, long customerId,
    string gmbEmailAddress, string businessAccountId, string gmbAccessToken)
{
    // Optional: Delete all existing location extension feeds. This is an optional step,
    // and is required for this code example to run correctly more than once.
    // 1. Google Ads only allows one location extension feed per email address.
    // 2. A Google Ads account cannot have a location extension feed and an affiliate
    // location extension feed at the same time.
    DeleteLocationExtensionFeeds(client, customerId);

    // Get the FeedServiceClient.
    FeedServiceClient feedService = client.GetService(Services.V4.FeedService);

    // Creates a feed that will sync to the Google My Business account specified by
    // gmbEmailAddress. Do not add FeedAttributes to this object as Google Ads will add
    // them automatically because this will be a system generated feed.
    Feed gmbFeed = new Feed()
    {
        Name = "Google My Business feed #" + ExampleUtilities.GetRandomString(),

        PlacesLocationFeedData = new PlacesLocationFeedData()
        {
            EmailAddress = gmbEmailAddress,
            // If the EmailAddress is for a GMB manager instead of the GMB
            // account owner, then set BusinessAccountId to the Google+ Page ID of
            // a location for which the manager has access. This information is available
            // through the Google My Business API. See
            // https://developers.google.com/my-business/reference/rest/v4/accounts.locations#locationkey
            // for details.
            BusinessAccountId = string.IsNullOrEmpty(businessAccountId) ?
                null : businessAccountId,
            // Used to filter Google My Business listings by labels. If entries exist in
            // label_filters, only listings that have at least one of the labels set are
            // candidates to be synchronized into FeedItems. If no entries exist in
            // label_filters, then all listings are candidates for syncing.
            LabelFilters = { "Stores in New York" },
            // Sets the authentication info to be able to connect Google Ads to the GMB
            // account.
            OauthInfo = new OAuthInfo()
            {
                HttpMethod = "GET",
                HttpRequestUrl = GOOGLE_ADS_SCOPE,
                HttpAuthorizationHeader = $"Bearer {gmbAccessToken}"
            },
        },
        // Since this feed's feed items will be managed by Google,
        // you must set its origin to GOOGLE.
        Origin = FeedOrigin.Google
    };

    FeedOperation operation = new FeedOperation()
    {
        Create = gmbFeed
    };

    // Adds the feed.
    MutateFeedsResponse response =
        feedService.MutateFeeds(customerId.ToString(), new[] { operation });

    // Displays the results.
    string gmbFeedResourceName = response.Results[0].ResourceName;
    Console.WriteLine($"GMB feed created with resource name: {gmbFeedResourceName}.");
    return gmbFeedResourceName;
}

You need to populate the following fields that are specific to location extensions feeds:

Attribute Required Description
origin Yes Since the location extensions feed is system-generated, you need to set the origin field to GOOGLE.
attributes No Do not specify any attributes for the feed. Google Ads will create these for you automatically because this is a system-generated feed.
places_location_feed_data Yes Setting the places_location_feed_data attribute to a PlacesLocationFeedData object on your feed tells Google Ads to:
  • Link your Google My Business and Google Ads accounts.
  • Automatically create feed attributes for your feed.
  • Automatically create a FeedMapping LOCATION_EXTENSION_TARGETING criterion type.
  • (Optional) Limit the set of locations that Google Ads syncs from your Google My Business account.

Attributes of PlacesLocationFeedData

Attribute Required Description
email_address Yes The email address of your Google My Business account owner or one of its managers. This must match the email address provided in oauth_info.
oauth_info Yes OAuth2 information that grants your Google Ads account access to your Google My Business account. If you aren't familiar with OAuth2, read the authentication guide first.
business_account_id 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 LOCATION_GROUP_ID portion from the Location group info section of the specified location group.
business_name_filter No Name of the business to sync to Google Ads.
category_filters No Categories of the listings to sync to Google Ads.
label_filters No Labels of the listings to sync to Google Ads.

oauth_info attribute of PlacesLocationFeedData

Attribute Value Description
http_method GET The HTTP method for getting authorization information.
http_request_url https://www.googleapis.com/auth/adwords The OAuth scope that the Google Ads API uses to authorize your requests to Google My Business.
http_authorization_header Bearer OAUTH_ACCESS_TOKEN The authorization header containing the OAuth access token that grants your Google Ads 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 http_request_url of the PlacesLocationFeedData and a scope matching http_request_url.

Wait for the feed to be ready

Once the Feed is created, Google Ads will create the feed attributes and FeedMapping. Afterwards, it will populate the feed contents by creating the FeedItem objects that correspond to the locations in the GMB account.

You need to wait until the FeedMapping is created to ensure that the feed is properly set up, and that it can be used for the next steps. This can be done by attempting to retrieve the FeedMapping for the relevant feed with placeholder_type equal to LOCATION.

C#

private static FeedMapping GetGMBFeedMapping(GoogleAdsClient client, long customerId,
    string gmbFeedResourceName)
{
    // Get the GoogleAdsService.
    GoogleAdsServiceClient googleAdsService = client.GetService(
        Services.V4.GoogleAdsService);

    // Create the query.
    string query = $"SELECT feed_mapping.resource_name, feed_mapping.status FROM " +
        $"feed_mapping WHERE feed_mapping.feed = '{gmbFeedResourceName}' and " +
        $"feed_mapping.status = ENABLED and feed_mapping.placeholder_type = LOCATION" +
        $" LIMIT 1";

    // Issue a search request.
    PagedEnumerable<SearchGoogleAdsResponse, GoogleAdsRow> result =
        googleAdsService.Search(customerId.ToString(), query);

    // Display the results.
    GoogleAdsRow googleAdsRow = result.FirstOrDefault();
    return (googleAdsRow == null) ? null : googleAdsRow.FeedMapping;
}

If the FeedMapping is not yet available, retry the calls with an exponential back-off policy until the Feed is ready.

C#

private static void WaitForGMBFeedToBeReady(GoogleAdsClient client, long customerId,
    string gmbFeedResourceName)
{
    int numAttempts = 0;
    int sleepSeconds = 0;

    while (numAttempts < MAX_FEEDMAPPING_RETRIEVAL_ATTEMPTS)
    {
        // Once you create a feed, Google's servers will setup the feed by creating feed
        // attributes and feedmapping. Once the feedmapping is created, it is ready to be
        // used for creating customer feed.
        // This process is asynchronous, so we wait until the feed mapping is created,
        // peforming exponential backoff.
        FeedMapping feedMapping = GetGMBFeedMapping(client,
            customerId, gmbFeedResourceName);

        if (feedMapping == null)
        {
            numAttempts++;
            sleepSeconds = (int) (5 * Math.Pow(2, numAttempts));
            Console.WriteLine($"Checked: #{numAttempts} time(s). GMB feed is not ready " +
                $"yet. Waiting {sleepSeconds} seconds before trying again.");
            Thread.Sleep(sleepSeconds * 1000);
        }
        else
        {
            Console.WriteLine($"GMB Feed {gmbFeedResourceName} is now ready.");
            return;
        }
    }
    throw new RpcException(new Status(StatusCode.DeadlineExceeded,
        $"GMB Feed is not ready after {MAX_FEEDMAPPING_RETRIEVAL_ATTEMPTS}" +
        $" retries."));
}

Associate the feed with the customer

Once the feed is ready, you can associate it with a customer by creating a CustomerFeed. Then perform a CustomerFeedService.MutateCustomerFeeds create operation to complete the linking.

The following fields of the CustomerFeed should be set.

Attribute Value Description
feed The feed resource name. The resource name of the feed that was created in the previous step.
placeholder_types LOCATION Indicates that this feed populates location extensions under the connected customer.
matching_function IDENTITY(true) to mark this feed as enabled, and IDENTITY(false) to mark this feed as disabled. See filtering strategies for more details.

C#

private static void CreateCustomerFeed(GoogleAdsClient client, long customerId,
    string gmbFeedResourceName)
{
    // Get the CustomerFeedService.
    CustomerFeedServiceClient customerFeedService = client.GetService(
        Services.V4.CustomerFeedService);

    // Adds a CustomerFeed that associates the feed with this customer for
    // the LOCATION placeholder type.
    CustomerFeed customerFeed = new CustomerFeed()
    {
        Feed = gmbFeedResourceName,
        PlaceholderTypes = { PlaceholderType.Location },
        MatchingFunction = new MatchingFunction()
        {
            LeftOperands =
            {
                new Operand()
                {
                    ConstantOperand = new ConstantOperand()
                    {
                        BooleanValue = true
                    }
                }
            },
            // Specify the function string as IDENTITY(true) to mark this feed as enabled.
            FunctionString = "IDENTITY(true)",
            Operator = MatchingFunctionOperator.Identity
        },
    };

    CustomerFeedOperation operation = new CustomerFeedOperation()
    {
        Create = customerFeed
    };

    MutateCustomerFeedsResponse customerFeedsResponse =
        customerFeedService.MutateCustomerFeeds(
            customerId.ToString(), new[] { operation });

    // Displays the result.
    string addedCustomerFeed = customerFeedsResponse.Results[0].ResourceName;
    Console.WriteLine($"Customer feed created with resource name: {addedCustomerFeed}.");
    return;
}