Google Ads

Dynamic Remarketing  |  AdWords API  |  Google Developers

Dynamic Remarketing
ads are display ads customized for each impression, showing content related to
a user’s previous visits to a website.

Dynamic remarketing has many benefits, including:

  • Scalability: You can create ads that scale with your products or services,
    when paired with your feeds.
  • Simple yet powerful feeds: Once you create the feeds, the Google Ads product
    recommendation engine will pull products and services, determining the best
    mix of products for each ad based on popularity and what the visitor viewed
    on your site.
  • High-performance layouts: Google Ads predicts which dynamic ad layout is
    likely to perform best for the person, placement and platform where the
    ads will show.
  • Real-time bid optimization: With enhanced CPC and conversion optimizer,
    Google Ads calculates the optimal bid for each impression.

There are two types of Dynamic Remarketing campaigns supported using the
AdWords API: retail and non-retail. Dynamic Remarketing for retail requires the
feed provided by Merchant Center, where as non-retail can be maintained using
Feeds, FeedMappings and FeedItems.

This guide will walk through two examples that use feeds to update
Dynamic Remarketing ads.

Prerequisites

Install Global Site Tag and Remarketing Event Snippet

To implement dynamic remarketing, you need to tag your site for
remarketing
. You can retrieve the
googleGlobalSiteTag
or
googleEventSnippet
via the AdWords API using the
ConversionTrackerService.

Here are the steps for embedding tags in your website manually:

  1. Get the global site tag and the remarketing event snippet.

    The global site tag sets a new cookie on your site which collects information
    about the ad click that brought a visitor to your site and adds website
    visitors to standard remarketing lists in your Google Ads account.

    To make sure the tagging works with dynamic remarketing, select Collect
    specific attributes or parameter to personalize ads
    during the step Create
    the Google Ads tag data source
    , as shown below:

    Detailed instructions to acquiring the global site tag and remarketing event
    snippet can be found at
    this help page

  2. Install the global site tag.

    You must install the global site tag on all the pages of your website that
    send remarketing information, but you need only one global site tag for each
    Google Ads account. The event snippet can be used to track additional actions
    that are to be counted as remarketing events. Install this snippet on site
    pages you’d like to track, right after the global site tag in the
    section.

    The global site tag also works with other tags such as Google Analytics tags.
    To read more about how tags work in Google Analytics, you can refer to this
    guide
    .

  3. Install an event snippet on site pages you would like to track, with
    corresponding customer parameter values.

    Custom parameters are elements in your remarketing tag code that allow your
    tag to send information about specific items or selections on your website to
    your Google Ads account. Custom parameters are directly related to business
    data feeds, where you add the values that correspond to the information
    the tag collects.

    To use dynamic remarketing, you’ll need to use the custom parameters marked
    as “Required” on
    this page.

    When you add the value of a custom parameter to your remarketing tag,
    it will sync with your feed to show the same product or service in
    your ads previously viewed by the same visitor.

    Here is an example of how to install an event snippet for a retail site (note
    the ecomm_prodid is the
    Merchant Center Product ID
    that corresponds to the product on the page):

    gtag('event', 'page_view', {
      ecomm_pagetype: 'product',
      ecomm_prodid: 34592212,
      ecomm_totalvalue: 29.99,
      ecomm_category: 'Home & Garden',
      isSaleItem: false
    });
    

    In addition to the standard business types, dynamic remarketing parameters
    also support the use of
    custom feed templates
    via the
    dynx_itemid,
    which provides more control over feed contents.
    Here is an example:
    Note: The dynx_itemid corresponds to the
    feed item ID
    of an item on the page):

    gtag('event', 'page_view', {
      dynx_itemid: ['CORS9', 'XSS7'],
      dynx_pagetype: 'conversionintent',
      dynx_totalvalue: 78.98
    });
    

    For detailed definitions of the parameters and their valid values, please
    refer to this guide.

    The event name you use (e.g. page_view in the above example) can be a
    custom event name of your choosing or one of our recommended standard events.

    It doesn’t need to match any specific value for the purpose of implementing
    dynamic remarketing, as long as the event data parameters (ecomm_pagetype,
    ecomm_prodid, ecomm_totalvalue in this example) are correctly set.

    For detailed documentation on custom parameters for different business types
    and how gtag.js works, refer to
    Dynamic Remarketing Parameters
    and
    gtag.js for Remarketing.

With feed-based dynamic remarketing, you’ll create a feed of all your products
or services along with attributes like unique IDs, images, and prices.
Using the details from your feed to create responsive ads, dynamic remarketing
shows the most relevant information in these ads to people who previously
visited your website.

To implement feed based dynamic remarketing, you need the following:

  1. Set up your Dynamic Display Ad feeds
    through the Google Ads UI, and ensure that you have the
    corresponding Feed IDs.

    Alternatively, you could use the API to create a Feed, FeedMapping,
    and FeedItems for use with your Dynamic Remarketing ads. Refer to the Feed
    Placeholders page for the list of required attributes and placeholder field
    IDs for each type of remarketing feed.

    Read more about feed services.

    The diagram below shows the relationship among feed components and the
    related workflow:

  2. When setting up Google Ads tag data source, make sure to select the same
    business type as your feed, as shown below:

Example: Adding and removing real estate listings

Let’s say you have Dynamic Remarketing ads for your real estate website. New
listings get added to inventory, while sold properties get removed. The goal
is to update your Dynamic Remarketing ads to reflect your current inventory.

Step 1 – Get information about your listings setup

In order to manage your real estate listings, you’ll need to retrieve the
FeedMapping
for your Feed and the Real Estate vertical’s placeholder
type
.
The FeedMapping will tell you the
FeedAttribute
in your Feed that corresponds to each placeholder
field
.
The code sample below defines a method that retrieves the FeedMapping and
builds a map of placeholder
fieldId
keys to
feedAttributeId
values.

/**
 * Returns a map from placeholder field ID to feed attribute ID for the given
 * combination of feed ID and placeholder type.
 */
public static Map getPlaceholderToAttributeMap(Long feedId,
    Integer placeholderType, AdWordsSession session, AdWordsServices adWordsServices)
    throws ApiException, RemoteException {
  Selector selector = new SelectorBuilder()
    .fields("AttributeFieldMappings")
    .equals("FeedId", feedId.toString())
    .equals("Status", FeedMappingStatus.ENABLED.getValue())
    .equals("PlaceholderType", placeholderType.toString())
    .build();

  // Get the FeedMappingService.
  FeedMappingServiceInterface feedMappingService =
    adWordsServices.get(session, FeedMappingServiceInterface.class);

  // Submit the 'get' request.
  FeedMapping feedMapping = feedMappingService.get(selector).getEntries(0);

  // Build a map from placeholder field ID to feed attribute ID from the FeedMapping.
  Map fieldMap = Maps.newHashMap();
  for(AttributeFieldMapping attributeFieldMapping :
      feedMapping.getAttributeFieldMappings()) {
    fieldMap.put(attributeFieldMapping.getFieldId(),
        attributeFieldMapping.getFeedAttributeId());
  }
  return fieldMap;
}

Step 2 – Construct operations to add the new listings

Now that the utility method above is in place, constructing the operations for
adding new listings is straightforward. The basic steps for each new listing
are:

  1. Get the mapping from placeholder field ID to feed attribute ID using the
    utility method.
  2. For each attribute of the listing (listing ID, listing name, image URL,
    etc.), create a
    FeedItemAttributeValue
    with its
    feedAttributeId
    set to the ID found in the mapping for the corresponding placeholder field.
  3. On the FeedItemAttributeValue, set the appropriate value field for the
    attribute’s placeholder field. For example, for listing ID, set the
    stringValue
    field because the LISTING_ID field has a data type of STRING.
  4. Once you have all of the FeedItemAttributeValue objects, create a new
    FeedItem
    and set its
    feedId
    to the ID of your Feed, and its
    attributeValues
    to the collection of FeedItemAttributeValue objects.
  5. Create a new
    FeedItemOperation
    where the
    operator
    is set to ADD and the
    operand
    is set to the FeedItem.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE");

List newFeedItemOperations = Lists.newArrayList();

// First, get the mapping from placeholder field ID to feed attribute ID.
// Note that 16 is the placeholder type ID for the Real Estate vertical.
Map fieldMap = getPlaceholderToAttributeMap(feedId,
  16, session, adWordsServices);

FeedItemAttributeValue listingId = new FeedItemAttributeValue();
listingId.setFeedAttributeId(fieldMap.get(1));
listingId.setStringValue("ABC123DEF");

FeedItemAttributeValue listingName = new FeedItemAttributeValue();
listingName.setFeedAttributeId(fieldMap.get(2));
listingName.setStringValue("Two bedroom with magnificent views");

FeedItemAttributeValue finalUrl = new FeedItemAttributeValue();
finalUrl.setFeedAttributeId(fieldMap.get(12));
finalUrl.setStringValues(new String[] {"http://www.example.com/listings/"});

// Insert additional attributes here, such as address, city, description, etc.

FeedItemAttributeValue imageUrl = new FeedItemAttributeValue();
imageUrl.setFeedAttributeId(fieldMap.get(8));
imageUrl.setStringValue("http://www.example.com/listings/images?listing_id=ABC123DEF");

FeedItemAttributeValue contextualKeywords = new FeedItemAttributeValue();
contextualKeywords.setFeedAttributeId(fieldMap.get(11));
contextualKeywords.setStringValues(
    new String[] {"beach community", "ocean view", "two bedroom"});

// Create the FeedItem, specifying the Feed ID and the attributes created above.
FeedItem feedItem = new FeedItem();
feedItem.setFeedId(feedId);
feedItem.setAttributeValues(new FeedItemAttributeValue[]{
    listingId,
    listingName,
    finalUrl,
    // Include additional attributes...
    imageUrl,
    contextualKeywords});

// Create an operation to add each FeedItem.
FeedItemOperation feedItemOperation = new FeedItemOperation();
feedItemOperation.setOperator(Operator.ADD);
feedItemOperation.setOperand(feedItem);
newFeedItemOperations.add(feedItemOperation);

// Repeat the above for additional new listings.

Step 3 – Construct operations to remove sold listings

The process for removing sold listings is even simpler—all you need are
the
feedId
and the
feedItemId
of each sold listing.

The basic steps for each listing you want to remove are:

  1. Create a new
    FeedItem
    and set its
    feedId
    to the ID of your Feed, and its
    feedItemId
    to the listing’s item ID.
  2. Create a new
    FeedItemOperation
    where the
    operator
    is set to REMOVE and the
    operand
    is set to the FeedItem.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE");

List feedItemIds = Lists.newArrayList(
    // feed item ID 1,
    // feed item ID 2,
    // ...
    );

List removeFeedItemOperations = Lists.newArrayList();
for(Long feedItemId : feedItemIds) {
  // When removing you can simply specify the feedId and the feedItemId.
  FeedItem feedItemToRemove = new FeedItem();

  feedItemToRemove.setFeedId(feedId);
  feedItemToRemove.setFeedItemId(feedItemId);

  FeedItemOperation removeOperation = new FeedItemOperation();
  removeOperation.setOperator(Operator.REMOVE);
  removeOperation.setOperand(feedItemToRemove);

  removeFeedItemOperations.add(removeOperation);
}

Step 4 – Submit the add and remove operations

This step is just like any other mutate operation in the API. To actually apply
the changes, simply pass the union of the two collections of
FeedItemOperations
you created above to
FeedItemService.mutate().

// Get the FeedItemService
FeedItemServiceInterface feedItemService =
    adWordsServices.get(session, FeedItemServiceInterface.class);

// Combine the lists of operations.
List allOperations = Lists.newArrayList(newFeedItemOperations);
allOperations.addAll(removeFeedItemOperations);

// Pass the collection of FeedItemOperations to the mutate method.
FeedItemReturnValue itemsUpdateReturnValue =
    feedItemService.mutate(allOperations.toArray(new FeedItemOperation[allOperations.size()]));

System.out.printf("Updated %d items%n", itemsUpdateReturnValue.getValue().length);

Example: Updating flight prices

Assume you have a flight reservation site where you’ve set
up Dynamic Remarketing ads, and you want to update the sale price on some
flights and remove the sale price on others. To ensure that your ads display the
correct prices for each flight, you’ll want to update the price on each flight’s
corresponding
FeedItem.

Step 1 – Construct operations to update the sale prices

This is similar to creating new FeedItems, except you can just specify the
FeedItemAttributeValue you want to modify, and the placeholder field IDs
will come from the list of fields for the Flights
vertical
.

The basic steps for each flight entry to modify are:

  1. Get the mapping from placeholder field ID to feed attribute ID using the
    utility method.
  2. For each attribute of the flight (sale price, flight price, etc.), create a
    FeedItemAttributeValue
    with its
    feedAttributeId
    set to the ID found in the mapping for the corresponding placeholder field.
  3. On the FeedItemAttributeValue, set the appropriate value field for the
    attribute’s placeholder field.
  4. Once you have all of the FeedItemAttributeValues, create a new
    FeedItem
    and set its
    feedId
    to the ID of your Feed, its
    feedItemId
    to the ID of the flight’s feed item ID, and its
    attributeValues
    to the collection of FeedItemAttributeValues.
  5. Create a new
    FeedItemOperation
    where the
    operator
    is set to SET and the
    operand
    is set to the FeedItem.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE");

List updateFeedItemOperations = Lists.newArrayList();

// First, get the mapping from placeholder field ID to feed attribute ID.
// Note that 13 is the placeholder type ID for the Flights vertical.
Map fieldMap = getPlaceholderToAttributeMap(feedId,
  13, session, adWordsServices);

// Update the sale price on the first flight
Long newSalePriceFeedItemId = Long.valueOf("INSERT_FEED_ITEM_ID");
FeedItemAttributeValue salePrice = new FeedItemAttributeValue();
salePrice.setFeedAttributeId(fieldMap.get(12));
salePrice.setStringValue("1,309.89 USD");

FeedItem feedItemForNewSalePrice = new FeedItem();
feedItemForNewSalePrice.setFeedId(feedId);
feedItemForNewSalePrice.setFeedItemId(newSalePriceFeedItemId);
feedItemForNewSalePrice.setAttributeValues(new FeedItemAttributeValue[] {salePrice});

// Clear the sale price on the second flight, and update its regular price
Long removedSalePriceFeedItemId = Long.valueOf("INSERT_FEED_ITEM_ID");
FeedItemAttributeValue removedSalePrice = new FeedItemAttributeValue();
removedSalePrice.setFeedAttributeId(fieldMap.get(12));

FeedItemAttributeValue newFlightPrice = new FeedItemAttributeValue();
newFlightPrice.setFeedAttributeId(fieldMap.get(6));
newFlightPrice.setStringValue("499.99 USD");

FeedItem feedItemForRemovedSalePrice = new FeedItem();
feedItemForRemovedSalePrice.setFeedId(feedId);
feedItemForRemovedSalePrice.setFeedItemId(removedSalePriceFeedItemId);
feedItemForRemovedSalePrice.setAttributeValues(
    new FeedItemAttributeValue[] {removedSalePrice, newFlightPrice});

// Create the FeedItemOperations to update the FeedItems.
for(FeedItem feedItemToUpdate : new FeedItem[]{ feedItemForNewSalePrice,
                                                feedItemForRemovedSalePrice}) {
  FeedItemOperation updateFeedItemOperation = new FeedItemOperation();
  updateFeedItemOperation.setOperator(Operator.SET);
  updateFeedItemOperation.setOperand(feedItemToUpdate);

  updateFeedItemOperations.add(updateFeedItemOperation);
}

Step 2 – Submit the update operations

As with the add and remove operations, to actually apply these changes, simply
pass the collection of
FeedItemOperations
you created above to
FeedItemService.mutate().

To implement merchant center-based dynamic remarketing, you need the following:

  1. Merchant Center account linked to a Google Ads account.
  2. Approved products in your Merchant Center feed.
  3. When setting up a Google Ads tag data source, make sure to select “Retail” as
    the Business Type.

Read more about creating a product feed in the merchant
center
.

Additionally, feed creation can be automated via
Content API for Shopping.

So you have a retail site that uploads product listings to Google Merchant
Center and you want to remarket groups of products to users who visited the
retail site. These users might have visited a product page or placed an item in
a basket or checkout, recorded by the triggering of a remarketing tag.
You can then create a campaign to target only this group or expand to similar
audiences to increase your reach.

Read more about audience list generation best
practices
.

You will need the following to set up such a campaign:

  1. Remarketing List.
  2. Merchant Center account.
  3. Product Feed from Merchant Center.
  4. Media required for Responsive Ads for Display.

Here is the list of ad creatives that support Merchant Center product feeds:
* Responsive Display Ads
* Multi-Asset Responsive Display Ads

Step 1 – Create a campaign linked to a Merchant Center product feed

In order to be able to remarket retail products, you’ll need to create a
campaign targeting the
Display Network.
This will require the following:

  • A Budget
    to specify how much the campaign is able to spend.
  • A BiddingStrategyConfiguration
    to configure how the campaign will be configured to bid.
  • A remarketing list
    including the list of users to target with the campaign.
  • A ShoppingSetting
    to specify which Merchant Center account the product feed will be used for the campaign.

The basic steps for configuring the campaign are:

  1. Create a new campaign, setting the
    AdvertisingChannelType
    to
    DISPLAY.
  2. Set the Budget
    for the campaign. This can be a newly created budget or a shared budget.
  3. Set the
    BiddingStrategyConfiguration
    for the campaign. The different types of strategies available for
    Dynamic Remarketing campaigns can be found
    here.
  4. Set the ShoppingSetting
    for the campaign.
    Note: CampaignService is used here, rather than
    AdGroupService, since the feed must be attached at campaign level.

  5. Apply the mutate operation to ADD the new campaign to the account.

Code Example:

C#

private static Campaign CreateCampaign(AdWordsUser user, long merchantId, long budgetId)
{
    using (CampaignService campaignService =
        (CampaignService) user.GetService(AdWordsService.v201809.CampaignService))
    {
        Campaign campaign = new Campaign
        {
            name = "Shopping campaign #" + ExampleUtilities.GetRandomString(),
            // Dynamic remarketing campaigns are only available on the Google Display
            // Network.
            advertisingChannelType = AdvertisingChannelType.DISPLAY,
            status = CampaignStatus.PAUSED
        };

        Budget budget = new Budget
        {
            budgetId = budgetId
        };
        campaign.budget = budget;

        // This example uses a Manual CPC bidding strategy, but you should select the
        // strategy that best aligns with your sales goals. More details here:
        //   https://support.google.com/adwords/answer/2472725
        BiddingStrategyConfiguration biddingStrategyConfiguration =
            new BiddingStrategyConfiguration
            {
                biddingStrategyType = BiddingStrategyType.MANUAL_CPC
            };
        campaign.biddingStrategyConfiguration = biddingStrategyConfiguration;

        ShoppingSetting setting = new ShoppingSetting
        {
            // Campaigns with numerically higher priorities take precedence over those with
            // lower priorities.
            campaignPriority = 0,

            // Set the Merchant Center account ID from which to source products.
            merchantId = merchantId,

            // Display Network campaigns do not support partition by country. The only
            // supported value is "ZZ". This signals that products from all countries are
            // available in the campaign. The actual products which serve are based on the
            // products tagged in the user list entry.
            salesCountry = "ZZ",

            // Optional: Enable local inventory ads (items for sale in physical stores.)
            enableLocal = true
        };

        campaign.settings = new Setting[]
        {
            setting
        };

        CampaignOperation op = new CampaignOperation
        {
            operand = campaign,
            @operator = Operator.ADD
        };

        CampaignReturnValue result = campaignService.mutate(new CampaignOperation[]
        {
            op
        });
        return result.value[0];
    }
}

Java

private static Campaign createCampaign(
    AdWordsServicesInterface services, AdWordsSession session, long merchantId, long budgetId)
    throws RemoteException {
  CampaignServiceInterface campaignService =
      services.get(session, CampaignServiceInterface.class);

  Campaign campaign = new Campaign();
  campaign.setName("Shopping campaign #" + System.currentTimeMillis());
  // Dynamic remarketing campaigns are only available on the Google Display Network.
  campaign.setAdvertisingChannelType(AdvertisingChannelType.DISPLAY);
  campaign.setStatus(CampaignStatus.PAUSED);

  Budget budget = new Budget();
  budget.setBudgetId(budgetId);
  campaign.setBudget(budget);

  // This example uses a Manual CPC bidding strategy, but you should select the strategy that best
  // aligns with your sales goals. More details here:
  //   https://support.google.com/adwords/answer/2472725
  BiddingStrategyConfiguration biddingStrategyConfiguration = new BiddingStrategyConfiguration();
  biddingStrategyConfiguration.setBiddingStrategyType(BiddingStrategyType.MANUAL_CPC);
  campaign.setBiddingStrategyConfiguration(biddingStrategyConfiguration);

  ShoppingSetting setting = new ShoppingSetting();
  // Campaigns with numerically higher priorities take precedence over those with lower
  // priorities.
  setting.setCampaignPriority(0);

  // Set the Merchant Center account ID from which to source products.
  setting.setMerchantId(merchantId);

  // Display Network campaigns do not support partition by country. The only supported value is
  // "ZZ". This signals that products from all countries are available in the campaign. The actual
  // products which serve are based on the products tagged in the user list entry.
  setting.setSalesCountry("ZZ");

  // Optional: Enable local inventory ads (items for sale in physical stores.)
  setting.setEnableLocal(true);

  campaign.setSettings(new Setting[] {setting});

  CampaignOperation op = new CampaignOperation();
  op.setOperand(campaign);
  op.setOperator(Operator.ADD);

  CampaignReturnValue result = campaignService.mutate(new CampaignOperation[] {op});
  return result.getValue(0);
}

Python

def CreateCampaign(client, merchant_id, budget_id):
  """Creates a new Display Network campaign.

  Args:
    client: an AdWordsClient instance.
    merchant_id: a int merchant center ID.
    budget_id: a int budget ID.

  Returns:
    The campaign that was successfully created.
  """
  campaign_service = client.GetService('CampaignService', 'v201809')

  campaign = {
      'name': 'Shopping campaign #%d' % uuid.uuid4(),
      # Dynamic remarketing campaigns are only available on the Google Display
      # Network.
      'advertisingChannelType': 'DISPLAY',
      'status': 'PAUSED',
      'budget': {
          'budgetId': budget_id
      },
      # This example uses a Manual CPC bidding strategy, but you should select
      # the strategy that best aligns with your sales goals. More details here:
      # https://support.google.com/adwords/answer/2472725
      'biddingStrategyConfiguration': {
          'biddingStrategyType': 'MANUAL_CPC'
      },
      'settings': [{
          'xsi_type': 'ShoppingSetting',
          # Campaigns with numerically higher priorities take precedence over
          # those with lower priorities.
          'campaignPriority': 0,
          'merchantId': merchant_id,
          # Display network campaigns do not support partition by country. The
          # only supported value is "ZZ". This signals that products from all
          # countries are available in this campaign. The actual products which
          # serve are based on the products tagged in the user list entry.
          'salesCountry': 'ZZ',
          # Optional: Enable local inventory ads (items for sale in physical
          # stores.)
          'enableLocal': True,
      }]
  }

  operations = [{
      'operator': 'ADD',
      'operand': campaign
  }]

  return campaign_service.mutate(operations)['value'][0]

PHP

private static function createCampaign(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    $budgetId,
    $merchantId
) {
    $campaignService =
        $adWordsServices->get($session, CampaignService::class);

    // Create a campaign.
    $campaign = new Campaign();
    $campaign->setName('Shopping campaign #' . uniqid());
    // Dynamic remarketing campaigns are only available on the Google
    // Display Network.
    $campaign->setAdvertisingChannelType(AdvertisingChannelType::DISPLAY);

    // Recommendation: Set the campaign to PAUSED when creating it to
    // prevent the ads from immediately serving. Set to ENABLED once you've
    // added targeting and the ads are ready to serve.
    $campaign->setStatus(CampaignStatus::PAUSED);

    // Set shared budget (required).
    $budget = new Budget();
    $budget->setBudgetId($budgetId);
    $campaign->setBudget($budget);

    // This example uses a Manual CPC bidding strategy, but you should
    // select the strategy that best aligns with your sales goals. More
    // details here: https://support.google.com/adwords/answer/2472725.
    $biddingStrategyConfiguration = new BiddingStrategyConfiguration();
    $biddingStrategyConfiguration->setBiddingStrategyType(
        BiddingStrategyType::MANUAL_CPC
    );
    $campaign->setBiddingStrategyConfiguration(
        $biddingStrategyConfiguration
    );

    // All Shopping campaigns need a ShoppingSetting.
    $shoppingSetting = new ShoppingSetting();
    // Campaigns with numerically higher priorities take precedence over
    // those with lower priorities.
    $shoppingSetting->setCampaignPriority(0);

    // Set the Merchant Center account ID from which to source products.
    $shoppingSetting->setMerchantId($merchantId);

    // Display Network campaigns do not support partition by country. The
    // only supported value is "ZZ". This signals that products from all
    // countries are available in the campaign. The actual products which
    // serve are based on the products tagged in the user list entry.
    $shoppingSetting->setSalesCountry('ZZ');

    // Enable local inventory ads (items for sale in physical stores.)
    $shoppingSetting->setEnableLocal(true);

    $campaign->setSettings([$shoppingSetting]);

    // Creates operation.
    $campaignOperation = new CampaignOperation();
    $campaignOperation->setOperand($campaign);
    $campaignOperation->setOperator(Operator::ADD);

    // Makes the mutate request.
    $campaignAddResult = $campaignService->mutate([$campaignOperation]);
    $campaign = $campaignAddResult->getValue()[0];

    return $campaign;
}

Perl

sub _create_campaign {
  my ($client, $merchant_id, $budget_id) = @_;

  my $campaign = Google::Ads::AdWords::v201809::Campaign->new({
      name => sprintf("Shopping campaign #%s", uniqid()),
      # Dynamic remarketing campaigns are only available on the Google Display
      # Network.
      advertisingChannelType => "DISPLAY",
      status                 => "PAUSED",
      budget =>
        Google::Ads::AdWords::v201809::Budget->new({budgetId => $budget_id}),
      # This example uses a Manual CPC bidding strategy, but you should select
      # the strategy that best aligns with your sales goals. More details here:
      # https://support.google.com/adwords/answer/2472725
      biddingStrategyConfiguration =>
        Google::Ads::AdWords::v201809::BiddingStrategyConfiguration->new({
          biddingStrategyType => "MANUAL_CPC"
        }
        ),
      settings => [
        Google::Ads::AdWords::v201809::ShoppingSetting->new({
            # Campaigns with numerically higher priorities take precedence over
            # those with lower priorities.
            campaignPriority => 0,
            # Set the Merchant Center account ID from which to source products.
            merchantId => $merchant_id,
            # Display Network campaigns do not support partition by country.
            # The only supported value is "ZZ". This signals that products
            # from all countries are available in the campaign. The actual
            # products which serve are based on the products tagged in the user
            # list entry.
            salesCountry => "ZZ",
            # Optional: Enable local inventory ads (items for sale in physical
            # stores.)
            enableLocal => 1
          })
      ],
    });

  # Create operation.
  my $campaign_operation =
    Google::Ads::AdWords::v201809::CampaignOperation->new({
      operator => "ADD",
      operand  => $campaign
    });

  my $result =
    $client->CampaignService()->mutate({operations => [$campaign_operation]});
  return $result->get_value()->[0];
}

Ruby

def create_campaign(adwords, merchant_id, budget_id)
  campaign_srv = adwords.service(:CampaignService, API_VERSION)

  campaign = {
    :name => 'Shopping campaign #%d' % (Time.new.to_f * 1000).to_i,
    # Dynamic remarketing campaigns are only available on the Google Display
    # Network
    :advertising_channel_type => 'DISPLAY',
    :status => 'PAUSED',
    :budget => {
      :budget_id => budget_id
    },
    # This example uses a Manual CPC bidding strategy, but you should select the
    # strategy that best aligns with your sales goals. More details here:
    # https://support.google.com/adwords/answer/2472725
    :bidding_strategy_configuration => {
      :bidding_strategy_type => 'MANUAL_CPC'
    },
    :settings => [{
      :xsi_type => 'ShoppingSetting',
      # Campaigns with numerically higher priorities take precedence over those
      # with lower priorities.
      :campaign_priority => 0,
      # Set the Merchant Center account ID from which to source products.
      :merchant_id => merchant_id,
      # Display Network campaigns do not support partition by country. The only
      # supported value is "ZZ". This signals that products from all countries
      # are available in the campaign. The actual products which serve are based
      # on the products tagged in the user list entry.
      :sales_country => 'ZZ',
      # Optional: Enable local inventory ads (items for sale in physical
      # stores.)
      :enable_local => true
    }]
  }

  operation = {
    :operator => 'ADD',
    :operand => campaign
  }

  result = campaign_srv.mutate([operation])
  return result[:value].first
end

Code Example:

C#

private static AdGroup CreateAdGroup(AdWordsUser user, Campaign campaign)
{
    using (AdGroupService adGroupService =
        (AdGroupService) user.GetService(AdWordsService.v201809.AdGroupService))
    {
        AdGroup group = new AdGroup
        {
            name = "Dynamic remarketing ad group",
            campaignId = campaign.id,
            status = AdGroupStatus.ENABLED
        };

        AdGroupOperation op = new AdGroupOperation
        {
            operand = group,
            @operator = Operator.ADD
        };
        AdGroupReturnValue result = adGroupService.mutate(new AdGroupOperation[]
        {
            op
        });
        return result.value[0];
    }
}

Java

private static AdGroup createAdGroup(
    AdWordsServicesInterface services, AdWordsSession session, Campaign campaign)
    throws RemoteException {
  AdGroupServiceInterface adGroupService = services.get(session, AdGroupServiceInterface.class);

  AdGroup group = new AdGroup();
  group.setName("Dynamic remarketing ad group");
  group.setCampaignId(campaign.getId());
  group.setStatus(AdGroupStatus.ENABLED);

  AdGroupOperation op = new AdGroupOperation();
  op.setOperand(group);
  op.setOperator(Operator.ADD);
  AdGroupReturnValue result = adGroupService.mutate(new AdGroupOperation[] {op});
  return result.getValue(0);
}

Python

def CreateAdGroup(client, campaign_id):
  """Creates a dynamic remarketing campaign.

  Args:
    client: an AdWordsClient instance.
    campaign_id: an int campaign ID.

  Returns:
    The ad group that was successfully created.
  """
  ad_group_service = client.GetService('AdGroupService', 'v201809')

  ad_group = {
      'name': 'Dynamic remarketing ad group',
      'campaignId': campaign_id,
      'status': 'ENABLED'
  }

  operations = [{
      'operator': 'ADD',
      'operand': ad_group
  }]

  return ad_group_service.mutate(operations)['value'][0]

PHP

private static function createAdGroup(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    Campaign $campaign
) {
    $adGroupService =
        $adWordsServices->get($session, AdGroupService::class);

    // Creates ad group.
    $adGroup = new AdGroup();
    $adGroup->setCampaignId($campaign->getId());
    $adGroup->setName('Dynamic remarketing ad group #' . uniqid());
    $adGroup->setStatus(AdGroupStatus::ENABLED);

    // Creates operation.
    $adGroupOperation = new AdGroupOperation();
    $adGroupOperation->setOperand($adGroup);
    $adGroupOperation->setOperator(Operator::ADD);

    // Makes the mutate request.
    $adGroupAddResult = $adGroupService->mutate([$adGroupOperation]);
    $adGroup = $adGroupAddResult->getValue()[0];

    return $adGroup;
}

Perl

sub _create_ad_group {
  my ($client, $campaign) = @_;

  my $ad_group = Google::Ads::AdWords::v201809::AdGroup->new({
    name       => sprintf("Dynamic remarketing ad group"),
    campaignId => $campaign->get_id(),
    status     => "ENABLED"
  });

  my $ad_group_operation =
    Google::Ads::AdWords::v201809::AdGroupOperation->new({
      operator => "ADD",
      operand  => $ad_group
    });

  my $result =
    $client->AdGroupService()->mutate({operations => [$ad_group_operation]});
  return $result->get_value()->[0];
}

Ruby

def create_ad_group(adwords, campaign)
  ad_group_srv = adwords.service(:AdGroupService, API_VERSION)

  ad_group = {
    :name => 'Dynamic remarketing ad group',
    :campaign_id => campaign[:id],
    :status => 'ENABLED'
  }

  operation = {
    :operator => 'ADD',
    :operand => ad_group
  }

  result = ad_group_srv.mutate([operation])
  return result[:value].first
end

Step 3 – Create a responsive ad for display

Code Example:

C#

private static AdGroupAd CreateAd(AdWordsUser user, AdGroup adGroup)
{
    using (AdGroupAdService adService =
        (AdGroupAdService) user.GetService(AdWordsService.v201809.AdGroupAdService))
    {
        ResponsiveDisplayAd ad = new ResponsiveDisplayAd
        {
            // This ad format does not allow the creation of an image using the
            // Image.data field. An image must first be created using the MediaService,
            // and Image.mediaId must be populated when creating the ad.
            marketingImage = UploadImage(user, "https://goo.gl/3b9Wfh"),

            shortHeadline = "Travel",
            longHeadline = "Travel the World",
            description = "Take to the air!",
            businessName = "Interplanetary Cruises",
            finalUrls = new string[]
            {
                "http://www.example.com/"
            },

            // Optional: Call to action text.
            // Valid texts: https://support.google.com/adwords/answer/7005917
            callToActionText = "Apply Now",

            // Optional: Set dynamic display ad settings, composed of landscape logo
            // image, promotion text, and price prefix.
            dynamicDisplayAdSettings = CreateDynamicDisplayAdSettings(user),

            // Optional: Create a logo image and set it to the ad.
            logoImage = UploadImage(user, "https://goo.gl/mtt54n"),

            // Optional: Create a square marketing image and set it to the ad.
            squareMarketingImage = UploadImage(user, "https://goo.gl/mtt54n")
        };

        // Whitelisted accounts only: Set color settings using hexadecimal values.
        // Set allowFlexibleColor to false if you want your ads to render by always
        // using your colors strictly.
        // ad.mainColor = "#0000ff";
        // ad.accentColor = "#ffff00";
        // ad.allowFlexibleColor = false;

        // Whitelisted accounts only: Set the format setting that the ad will be
        // served in.
        // ad.formatSetting = DisplayAdFormatSetting.NON_NATIVE;

        AdGroupAd adGroupAd = new AdGroupAd
        {
            ad = ad,
            adGroupId = adGroup.id
        };

        AdGroupAdOperation op = new AdGroupAdOperation
        {
            operand = adGroupAd,
            @operator = Operator.ADD
        };

        AdGroupAdReturnValue result = adService.mutate(new AdGroupAdOperation[]
        {
            op
        });
        return result.value[0];
    }
}

Java

private static AdGroupAd createAd(
    AdWordsServicesInterface services, AdWordsSession session, AdGroup adGroup)
    throws IOException {
  AdGroupAdServiceInterface adService = services.get(session, AdGroupAdServiceInterface.class);

  ResponsiveDisplayAd ad = new ResponsiveDisplayAd();

  // This ad format does not allow the creation of an image using the
  // Image.data field. An image must first be created using the MediaService,
  // and Image.mediaId must be populated when creating the ad.
  ad.setMarketingImage(uploadImage(services, session, "https://goo.gl/3b9Wfh"));

  ad.setShortHeadline("Travel");
  ad.setLongHeadline("Travel the World");
  ad.setDescription("Take to the air!");
  ad.setBusinessName("Interplanetary Cruises");
  ad.setFinalUrls(new String[] {"http://www.example.com/"});

  // Optional: Call to action text.
  // Valid texts: https://support.google.com/adwords/answer/7005917
  ad.setCallToActionText("Apply Now");

  // Optional: Set dynamic display ad settings, composed of landscape logo
  // image, promotion text, and price prefix.
  DynamicSettings dynamicDisplayAdSettings = createDynamicDisplayAdSettings(services, session);
  ad.setDynamicDisplayAdSettings(dynamicDisplayAdSettings);

  Image optionalImage = uploadImage(services, session, "https://goo.gl/mtt54n");

  // Optional: Create a logo image and set it to the ad.
  ad.setLogoImage(optionalImage);

  // Optional: Create a square marketing image and set it to the ad.
  ad.setSquareMarketingImage(optionalImage);

  // Whitelisted accounts only: Set color settings using hexadecimal values.
  // Set allowFlexibleColor to false if you want your ads to render by always
  // using your colors strictly.
  /*
  ad.setMainColor("#0000ff");
  ad.setAccentColor("#ffff00");
  ad.setAllowFlexibleColor(false);
  */

  // Whitelisted accounts only: Set the format setting that the ad will be
  // served in.
  /*
  ad.setFormatSetting(
      com.google.api.ads.adwords.axis.v201809.cm.DisplayAdFormatSetting.NON_NATIVE);
  */

  AdGroupAd adGroupAd = new AdGroupAd();
  adGroupAd.setAd(ad);
  adGroupAd.setAdGroupId(adGroup.getId());

  AdGroupAdOperation op = new AdGroupAdOperation();
  op.setOperand(adGroupAd);
  op.setOperator(Operator.ADD);

  AdGroupAdReturnValue result = adService.mutate(new AdGroupAdOperation[] {op});
  return result.getValue(0);
}

Python

def CreateAd(client, opener, ad_group_id):
  """Creates a ResponsiveDisplayAd.

  Args:
    client: an AdWordsClient instance.
    opener: an OpenerDirector instance.
    ad_group_id: an int ad group ID.

  Returns:
    The ad group ad that was successfully created.
  """
  ad_group_ad_service = client.GetService('AdGroupAdService', 'v201809')
  media_service = client.GetService('MediaService', 'v201809')

  marketing_image_id = _CreateImage(
      media_service, opener, 'https://goo.gl/3b9Wfh')
  logo_image_id = _CreateImage(media_service, opener, 'https://goo.gl/mtt54n')

  ad = {
      'xsi_type': 'ResponsiveDisplayAd',
      # This ad format doesn't allow the creation of an image using the
      # Image.data field. An image must first be created using the MediaService,
      # and Image.mediaId must be populated when creating the ad.
      'marketingImage': {
          'xsi_type': 'Image',
          'mediaId': marketing_image_id
      },
      'shortHeadline': 'Travel',
      'longHeadline': 'Travel the World',
      'description': 'Take to the air!',
      'businessName': 'Interplanetary Cruises',
      'finalUrls': ['http://wwww.example.com'],
      # Optional: Call to action text.
      # Valid texts: https://support.google.com/adwords/answer/7005917
      'callToActionText': 'Apply Now',
      # Optional: Set dynamic display ad settings, composed of landscape logo
      # image, promotion text, and price prefix.
      'dynamicDisplayAdSettings': CreateDynamicDisplayAdSettings(
          client, opener),
      # Optional: Create a logo image and set it to the ad.
      'logoImage': {
          'xsi_type': 'Image',
          'mediaId': logo_image_id
      },
      # Optional: Create a square marketing image and set it to the ad.
      'squareMarketingImage': {
          'xsi_type': 'Image',
          'mediaId': logo_image_id
      },
      # Whitelisted accounts only: Set color settings using hexadecimal values.
      # Set allowFlexibleColor to False if you want your ads to render by always
      # using your colors strictly.
      # 'mainColor': '#000fff',
      # 'accentColor': '#fff000',
      # 'allowFlexibleColor': False,
      # Whitelisted accounts only: Set the format setting that the ad will be
      # served in.
      # 'formatSetting': 'NON_NATIVE'
  }

  ad_group_ad = {
      'ad': ad,
      'adGroupId': ad_group_id
  }

  operations = [{
      'operation': 'ADD',
      'operand': ad_group_ad
  }]

  return ad_group_ad_service.mutate(operations)['value'][0]

PHP

private static function createAd(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    AdGroup $adGroup
) {
    $adGroupAdService =
        $adWordsServices->get($session, AdGroupAdService::class);

    $responsiveDisplayAd = new ResponsiveDisplayAd();

    // This ad format does not allow the creation of an image using the
    // Image.data field. An image must first be created using the
    // MediaService and Image.mediaId must be populated when creating the
    // ad.
    $marketingImage = self::uploadImage(
        $adWordsServices,
        $session,
        'https://goo.gl/3b9Wfh'
    );
    $responsiveDisplayAd->setMarketingImage($marketingImage);

    $responsiveDisplayAd->setShortHeadline('Travel');
    $responsiveDisplayAd->setLongHeadline('Travel the World.');
    $responsiveDisplayAd->setDescription('Take to the air!');
    $responsiveDisplayAd->setBusinessName('Interplanetary Cruises');
    $responsiveDisplayAd->setFinalUrls(['http://www.example.com']);

    // Optional: Set the call-to-action text.
    // Valid texts: https://support.google.com/adwords/answer/7005917.
    $responsiveDisplayAd->setCallToActionText('Apply Now');

    // Optional: Set dynamic display ad settings, composed of landscape logo
    // image, promotion text, and price prefix.
    $dynamicDisplayAdSettings =
        self::createDynamicDisplayAdSettings($adWordsServices, $session);
    $responsiveDisplayAd->setDynamicDisplayAdSettings(
        $dynamicDisplayAdSettings
    );

    // Optional: Creates a square marketing image using MediaService, and
    // set it to the ad.
    $squareMarketingImage = self::uploadImage(
        $adWordsServices,
        $session,
        'https://goo.gl/mtt54n'
    );
    $responsiveDisplayAd->setSquareMarketingImage($squareMarketingImage);

    // Optional: Set the logo image.
    $logoImage = self::uploadImage(
        $adWordsServices,
        $session,
        'https://goo.gl/mtt54n'
    );
    $responsiveDisplayAd->setLogoImage($logoImage);

    // Whitelisted accounts only: Set color settings using hexadecimal
    // values. Set allowFlexibleColor to false if you want your ads to
    // render by always using your colors strictly.
    /*
    $responsiveDisplayAd->setMainColor('#0000ff');
    $responsiveDisplayAd->setAccentColor('#ffff00');
    $responsiveDisplayAd->setFlexibleColor(false);
    */

    // Whitelisted accounts only: Set the format setting that the ad will be
    // served in.
    /*
    $responsiveDisplayAd->setFormatSetting(
        GoogleAdsApiAdWordsv201809cmDisplayAdFormatSetting::NON_NATIVE
    );
    */

    // Creates ad group ad.
    $adGroupAd = new AdGroupAd();
    $adGroupAd->setAdGroupId($adGroup->getId());
    $adGroupAd->setAd($responsiveDisplayAd);

    // Create an ad group ad operation.
    $adGroupAdOperation = new AdGroupAdOperation();
    $adGroupAdOperation->setOperand($adGroupAd);
    $adGroupAdOperation->setOperator(Operator::ADD);

    // Creates an ad group ad on the server.
    $adGroupAdAddResult = $adGroupAdService->mutate([$adGroupAdOperation]);
    $adGroupAd = $adGroupAdAddResult->getValue()[0];

    return $adGroupAd;
}

Perl

sub _create_ad {
  my ($client, $ad_group) = @_;

  # This ad format does not allow the creation of an image using the
  # Image.data field. An image must first be created using the MediaService,
  # and Image.mediaId must be populated when creating the ad.
  my $ad_image = _upload_image($client, "https://goo.gl/3b9Wfh");
  my $marketing_image = Google::Ads::AdWords::v201809::Image->new(
    {mediaId => $ad_image->get_mediaId()});

  # Create the responsive display ad.
  my $responsive_display_ad =
    Google::Ads::AdWords::v201809::ResponsiveDisplayAd->new({
      marketingImage => $marketing_image,
      shortHeadline  => "Travel",
      longHeadline   => "Travel the World",
      description    => "Take to the air!",
      businessName   => "Interplanetary Cruises",
      finalUrls      => ["http://www.example.com/"]});

  # Optional: Call to action text.
  # Valid texts: https://support.google.com/adwords/answer/7005917
  $responsive_display_ad->set_callToActionText("Apply Now");

  # Optional: Set dynamic display ad settings, composed of landscape logo
  # image, promotion text, and price prefix.
  my $dynamic_settings = _create_dynamic_display_ad_settings($client);
  $responsive_display_ad->set_dynamicDisplayAdSettings($dynamic_settings);

  # Optional: Create a logo image and set it to the ad.
  my $logo_image = _upload_image($client, "https://goo.gl/mtt54n");
  my $logo_marketing_image = Google::Ads::AdWords::v201809::Image->new(
    {mediaId => $logo_image->get_mediaId()});
  $responsive_display_ad->set_logoImage($logo_marketing_image);

  # Optional: Create a square marketing image and set it to the ad.
  my $square_image = _upload_image($client, "https://goo.gl/mtt54n");
  my $square_marketing_image = Google::Ads::AdWords::v201809::Image->new(
    {mediaId => $square_image->get_mediaId()});
  $responsive_display_ad->set_squareMarketingImage($square_marketing_image);

  # Whitelisted accounts only: Set color settings using hexadecimal values.
  # Set allowFlexibleColor to false if you want your ads to render by always
  # using your colors strictly.
  # $responsiveDisplayAd->set_mainColor("#0000ff");
  # $responsiveDisplayAd->set_accentColor("#ffff00");
  # $responsiveDisplayAd->set_allowFlexibleColor(0);

  # Whitelisted accounts only: Set the format setting that the ad will be
  # served in.
  # $responsiveDisplayAd->set_formatSetting("NON_NATIVE");

  # Create ad group ad for the responsive display ad.
  my $responsive_display_ad_group_ad =
    Google::Ads::AdWords::v201809::AdGroupAd->new({
      adGroupId => $ad_group->get_id(),
      ad        => $responsive_display_ad
    });

  my $responsive_display_ad_group_ad_operation =
    Google::Ads::AdWords::v201809::AdGroupAdOperation->new({
      operator => "ADD",
      operand  => $responsive_display_ad_group_ad
    });

  my $result =
    $client->AdGroupAdService()
    ->mutate({operations => [$responsive_display_ad_group_ad_operation]});
  return $result->get_value()->[0];
}

Ruby

def create_ad(adwords, ad_group)
  ad_srv = adwords.service(:AdGroupAdService, API_VERSION)

  optional_media_id = upload_image(adwords, 'https://goo.gl/mtt54n')

  ad = {
    :xsi_type => 'ResponsiveDisplayAd',
    # This ad format does not allow the creation of an image using the
    # Image.data field. An image must first be created using the MediaService,
    # and Image.mediaId must be populated when creating the ad.
    :marketing_image => {
      :xsi_type => 'Image',
      :media_id => upload_image(adwords, 'https://goo.gl/3b9Wfh')
    },
    :short_headline => 'Travel',
    :long_headline => 'Travel the World',
    :description => 'Take to the air!',
    :business_name => 'Interplanetary Cruises',
    :final_urls => ['http://www.example.com'],
    # Optional: Call to action text.
    # Valid texts: https://support.google.com/adwords/answer/7005917
    :call_to_action_text => 'Apply Now',
    # Optional: Set dynamic display ad settings, composed of landscape logo
    # image, promotion text, and price prefix.
    :dynamic_display_ad_settings => create_dynamic_display_ad_settings(adwords),
    # Optional: Create a logo image and set it to the ad.
    :logo_image => {
      :xsi_type => 'Image',
      :media_id => optional_media_id
    },
    # Optional: Create a square marketing image and set it to the ad.
    :square_marketing_image => {
      :xsi_type => 'Image',
      :media_id => optional_media_id
    },
    # Whitelisted accounts only: Set color settings using hexadecimal values.
    # Set allowFlexibleColor to false if you want your ads to render by always
    # using your colors strictly.
    # :main_color => '#0000ff',
    # :accent_color => '#ffff00',
    # :allow_flexible_color => false,
    # Whitelisted accounts only: Set the format setting that the ad will be
    # served in.
    # :format_setting => 'NON_NATIVE'
  }

  ad_group_ad = {
    :ad => ad,
    :ad_group_id => ad_group[:id]
  }

  operation = {
    :operator => 'ADD',
    :operand => ad_group_ad
  }

  result = ad_srv.mutate([operation])
  return result[:value].first
end

Step 4 – Target a user list

Code Example:

C#

private static void AttachUserList(AdWordsUser user, AdGroup adGroup, long userListId)
{
    using (AdGroupCriterionService adGroupCriterionService =
        (AdGroupCriterionService) user.GetService(AdWordsService.v201809
            .AdGroupCriterionService))
    {
        CriterionUserList userList = new CriterionUserList
        {
            userListId = userListId
        };
        BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion
        {
            criterion = userList,
            adGroupId = adGroup.id
        };

        AdGroupCriterionOperation op = new AdGroupCriterionOperation
        {
            operand = adGroupCriterion,
            @operator = Operator.ADD
        };

        adGroupCriterionService.mutate(new AdGroupCriterionOperation[]
        {
            op
        });
    }
}

Java

private static void attachUserList(
    AdWordsServicesInterface services, AdWordsSession session, AdGroup adGroup, long userListId)
    throws RemoteException {
  AdGroupCriterionServiceInterface adGroupCriterionService =
      services.get(session, AdGroupCriterionServiceInterface.class);

  CriterionUserList userList = new CriterionUserList();
  userList.setUserListId(userListId);
  BiddableAdGroupCriterion adGroupCriterion = new BiddableAdGroupCriterion();
  adGroupCriterion.setCriterion(userList);
  adGroupCriterion.setAdGroupId(adGroup.getId());

  AdGroupCriterionOperation op = new AdGroupCriterionOperation();
  op.setOperand(adGroupCriterion);
  op.setOperator(Operator.ADD);

  adGroupCriterionService.mutate(new AdGroupCriterionOperation[] {op});
}

Python

def AttachUserList(client, ad_group_id, user_list_id):
  """Links the provided ad group and user list.

  Args:
    client: an AdWordsClient instance.
    ad_group_id: an int ad group ID.
    user_list_id: an int user list ID.

  Returns:
    The ad group criterion that was successfully created.
  """
  ad_group_criterion_service = client.GetService(
      'AdGroupCriterionService', 'v201809')

  user_list = {
      'xsi_type': 'CriterionUserList',
      'userListId': user_list_id
  }

  ad_group_criterion = {
      'xsi_type': 'BiddableAdGroupCriterion',
      'criterion': user_list,
      'adGroupId': ad_group_id
  }

  operations = [{
      'operator': 'ADD',
      'operand': ad_group_criterion
  }]

  return ad_group_criterion_service.mutate(operations)['value'][0]

PHP

private static function attachUserList(
    AdWordsServices $adWordsServices,
    AdWordsSession $session,
    AdGroup $adGroup,
    $userListId
) {
    $adGroupCriterionService =
        $adWordsServices->get($session, AdGroupCriterionService::class);

    // Creates criterion user list.
    $userList = new CriterionUserList();
    $userList->setUserListId($userListId);

    // Creates ad group criterion.
    $adGroupCriterion = new BiddableAdGroupCriterion();
    $adGroupCriterion->setCriterion($userList);
    $adGroupCriterion->setAdGroupId($adGroup->getId());

    // Creates operation.
    $adGroupCriterionOperation = new AdGroupCriterionOperation();
    $adGroupCriterionOperation->setOperand($adGroupCriterion);
    $adGroupCriterionOperation->setOperator(Operator::ADD);

    // Makes the mutate request.
    $adGroupCriterionAddResult =
        $adGroupCriterionService->mutate([$adGroupCriterionOperation]);
    $adGroupCriterion = $adGroupCriterionAddResult->getValue()[0];

    return $adGroupCriterion;
}

Perl

sub _attach_user_list {
  my ($client, $ad_group, $user_list_id) = @_;

  my $user_list = Google::Ads::AdWords::v201809::CriterionUserList->new({
    userListId => $user_list_id
  });

  my $ad_group_criterion =
    Google::Ads::AdWords::v201809::BiddableAdGroupCriterion->new({
      adGroupId => $ad_group->get_id(),
      criterion => $user_list
    });

  my $operation = Google::Ads::AdWords::v201809::AdGroupCriterionOperation->new(
    {
      operand  => $ad_group_criterion,
      operator => "ADD"
    });
  $client->AdGroupCriterionService()->mutate({operations => [$operation]});
}

Ruby

def attach_user_list(adwords, ad_group, user_list_id)
  ad_group_criterion_srv = adwords.service(:AdGroupCriterionService,
      API_VERSION)

  user_list = {
    :xsi_type => 'CriterionUserList',
    :user_list_id => user_list_id
  }

  ad_group_criterion = {
    :xsi_type => 'BiddableAdGroupCriterion',
    :criterion => user_list,
    :ad_group_id => ad_group[:id]
  }

  operation = {
    :operator => 'ADD',
    :operand => ad_group_criterion
  }

  result = ad_group_criterion_srv.mutate([operation])
end

Once you have the dynamic remarketing campaign setup for your Merchant Center
feeds, you can use the Ad Preview
tool from your Google Ads account to see the contents pulled from your Merchant
Center feeds.

Reporting

To gather performance statistics for your Dynamic Remarketing ads, use the same
reports you would use for any other Display Network campaign.

Further information

This guide covers examples for real estate, flights and retail. If your Dynamic
Remarketing ads target a different vertical, check out the complete list of
Dynamic Remarketing placeholder types

to get the appropriate placeholder type ID and placeholder field IDs.

And as described in the
Feed Services guide
,
you should only associate dynamic remarketing feeds at the campaign level via
CampaignFeedService.
Adding an association at the customer or ad group level will succeed, but the
association will be ignored.

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button
Close