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.
Business Type | Technologies required | Feed configuration |
---|---|---|
Retail | Merchant Center, Google Ads | ShoppingSetting |
Non-retail | Google Ads | Feed, FeedMapping, FeedItem |
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:
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
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
<head></head>
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.
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: Thedynx_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.
Feed Based Dynamic 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:
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:
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<Integer, Long> 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<Integer, Long> 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:
- Get the mapping from placeholder field ID to feed attribute ID using the utility method.
- For each attribute of the listing (listing ID, listing name, image URL,
etc.), create a
FeedItemAttributeValue
with itsfeedAttributeId
set to the ID found in the mapping for the corresponding placeholder field. - On the
FeedItemAttributeValue
, set the appropriate value field for the attribute's placeholder field. For example, for listing ID, set thestringValue
field because theLISTING_ID
field has a data type ofSTRING
. - Once you have all of the
FeedItemAttributeValue
objects, create a newFeedItem
and set itsfeedId
to the ID of yourFeed
, and itsattributeValues
to the collection ofFeedItemAttributeValue
objects. - Create a new
FeedItemOperation
where theoperator
is set toADD
and theoperand
is set to theFeedItem
.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE"); List<FeedItemOperation> 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<Integer, Long> 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:
- Create a new
FeedItem
and set itsfeedId
to the ID of yourFeed
, and itsfeedItemId
to the listing's item ID. - Create a new
FeedItemOperation
where theoperator
is set toREMOVE
and theoperand
is set to theFeedItem
.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE"); List<Long> feedItemIds = Lists.newArrayList( // feed item ID 1, // feed item ID 2, // ... ); List<FeedItemOperation> 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
FeedItemOperation
s
you created above to
FeedItemService.mutate()
.
// Get the FeedItemService FeedItemServiceInterface feedItemService = adWordsServices.get(session, FeedItemServiceInterface.class); // Combine the lists of operations. List<FeedItemOperation> 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 FeedItem
s, 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:
- Get the mapping from placeholder field ID to feed attribute ID using the utility method.
- For each attribute of the flight (sale price, flight price, etc.), create a
FeedItemAttributeValue
with itsfeedAttributeId
set to the ID found in the mapping for the corresponding placeholder field. - On the
FeedItemAttributeValue
, set the appropriate value field for the attribute's placeholder field. - Once you have all of the
FeedItemAttributeValue
s, create a newFeedItem
and set itsfeedId
to the ID of yourFeed
, itsfeedItemId
to the ID of the flight's feed item ID, and itsattributeValues
to the collection ofFeedItemAttributeValue
s. - Create a new
FeedItemOperation
where theoperator
is set toSET
and theoperand
is set to theFeedItem
.
Long feedId = Long.valueOf("INSERT_FEED_ID_HERE"); List<FeedItemOperation> 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<Integer, Long> 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
FeedItemOperation
s
you created above to
FeedItemService.mutate()
.
Merchant center-based dynamic remarketing
To implement merchant center-based dynamic remarketing, you need the following:
- Merchant Center account linked to a Google Ads account.
- Approved products in your Merchant Center feed.
- 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.
Example: Creating a dynamic remarketing campaign with Google Merchant Center
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:
- Remarketing List.
- Merchant Center account.
- Product Feed from Merchant Center.
- 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:
- Create a new campaign, setting the
AdvertisingChannelType
toDISPLAY
. - Set the
Budget
for the campaign. This can be a newly created budget or a shared budget. - Set the
BiddingStrategyConfiguration
for the campaign. The different types of strategies available for Dynamic Remarketing campaigns can be found here. Set the
ShoppingSetting
for the campaign. Note: CampaignService is used here, rather than AdGroupService, since the feed must be attached at campaign level.- First set the
merchantId
to that of the Merchant Center account associated with the Google Ads account. This Merchant Center account must already be linked to Google Ads as described in this article. - Then set the
campaignPriority
as described here. - Setting the
enableLocal
to "true" will include local inventory ads.
- First set the
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
Step 2 - Create an ad group for the remarketing campaign
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( \Google\AdsApi\AdWords\v201809\cm\DisplayAdFormatSetting::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.