Dynamic Remarketing

Dynamic Remarketing ads are display ads customized for each impression, showing products related to a user's previous visits to the advertiser's website. Using the AdWords API, you can maintain the Feeds, FeedMappings and FeedItems that drive your Dynamic Remarketing ads on the Display Network. This guide will walk through two examples that use feeds to update Dynamic Remarketing ads.

Prerequisites

This guide assumes that you've already set up your Dynamic Display Ad feeds through the AdWords user interface, and 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.

Use case 1: 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:

  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 FeedItemAttributeValues, create a new FeedItem and set its feedId to the ID of your Feed, and its attributeValues to the collection of FeedItemAttributeValues.
  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<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.

Tip: If you don't have the feedItemId for the sold listings, you can use FeedItemService.get to retrieve your FeedItems containing feedItemIds.

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<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 FeedItemOperations 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);

Use case 2: 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<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 FeedItemOperations you created above to FeedItemService.mutate.

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 and flights. 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.

Send feedback about...

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