Dynamic Ads for Destinations - Catalogs & Feeds

To promote destinations on Facebook, you have to share information about them with Facebook. You do this by creating a destinations catalog and then filling it with destinations.

You can create and manage your destinations catalog in your catalog manager. If you want to use the API to manage your catalog, take the following steps:

  1. Create a destination catalog
  2. Upload your feed to Facebook
  3. Create product sets out of your destination catalog
  4. Associate the catalog to your event sources

Destination Feed - Uploading your destinations to Facebook

A destination feed is a file with the destinations you want to promote. Every line or item in the file represents a single destination. You can use one or more destination feeds, as long as all feeds together contain all destinations you want to promote.

Supported Destination Feed Formats

File FormatSample & Description

CSV

  1. The first row must list the chosen field names in the order the values will be given. Subsequent rows then supply the corresponding values for each destination.
  2. Fields containing whitespace or commas should be enclosed in "double quotes".
    1. Nested or multi-value fields such as address, neighborhood or image can be represented using JSON-encoded values or by a set of "flattened" plain-text columns labeled using JSON-path syntax, such as address.city, neighborhood[0], image[0].url, image[0].tag[0], image[0].tag[1]. Both conventions can be used interchangeably in the same file.

XML

  1. A root <listings> XML node encloses a set of <listing> nodes, each of which represents a destination.
  2. The file must begin with a valid <?xml declaration tag.

The feed parser automatically detects UTF8, UTF16 or UTF32 text-encodings, and defaults to to LATIN1 if it encounters an unexpected byte sequences. You can provide text in field values in any language, however field names must be given exactly as below, in English.

Destination Feed Fields

Field Name and TypeDescription

destination_id

type: string

Required.

Max length: 100

Your unique identifier for the destination within the catalog. This will be matched with any content_ids provided in your destination app and pixel events.

address

type: object

Required.

A complete address for the destination that must be resolvable to its location

See Address Object Parameters

image

type: object

Required.

Max items: 20

Image data for this destination. You can provide up to 20 images for the destination. Each image contains two fields: url and tag. You can have multiple tags associated with an image. You must provide at least one image. Each image can be up to 4MB in size.

See Image Object Parameters

url

type: string

Required.

Link to the external site where you can view the destination page. You can specify a URL on ad level too using template_url_spec. URLs on ad level take precedence over URLs in the feed.

type

type: string

Required.

Max items: 20

The type of destination, such as beach, city, food, sightseeing, culture, history, shopping, museum, tranquility, scenery, nature, architecture, business, friendly people, relaxation, night market, mountain, temple, hiking, snorkeling, and so on. There can be multiple types associated with a destination; meaning a destination can have multiple attributes such as beach and sightseeing.

name

type: string

The most common name of the destination.

neighborhood

type: string

Max items: 20

One or more neighborhood(s) for the destination.

Examples:

  • Soho
  • Las Vegas Strip

latitude

type: float

The latitude of the destination.

Example: 37.484100

longitude

type: float

The longitude of the destination.

Example: -122.148252

description

type: string

Max size: 5000

A short paragraph describing the destination.

price

type: string

Can be lowest or average price for this destination. You must specify the value with currency.

Example: 99.99 USD

price_change

type: int

Specify the price change:

  • 0: No price change
  • -10: 10% price drop
  • 20: 20% price increase

This can be used for building product sets and in the ad creative ("average price dropped by X")

applink

type: element

Deep link straight to the destination details page in your mobile app using App Links. You can specify deep links in order of precedence, highest to lowest:

  1. on ad level using template_url_spec
  2. here in the feed using an Applink Object
  3. by adding App Link meta tags to your website.

Image Object Parameters

Field Name and TypeDescription

url

type: string

Required.

The url of the destination image. If you want to use carousel ads, provide a square 1:1 aspect ratio images of at least 600x600px. To show single image ads use images with a 1.91:1 aspect ratio image of at least 1200x630px.

tag

type: string

A string that represents what's in the image. There can be multiple tags associated with an image.

Examples:

  • Fitness Center
  • Swimming Pool

Address Object Parameters

Field Name and TypeDescription

addr1

type: string

Street address of destination.

Example: 675 El Camino Real

city

type: string

Required.

City where destination is located.

Example: Palo Alto

region

type: string

Required.

State, county, region or province for destination.

Example: California

postal_code

type: string

Postal or zip-code of the destination. Required unless country does not have a postal-code system.

Examples:

  • 94125
  • NW1 3FG

country

type: string

Required.

Country of the destination.

Example: United States

city_id

type: string

Value to use in deep link URL (template_url) in ad creative.

If you have separate apps for iPhone and iPad, specify iPhone and iPad specific information. Otherwise specify only iOS information.

Field Name and TypeDescription

ios_url

type: string

A custom scheme for the iOS app.

Example: example-ios://electronic

ios_app_store_id

type: string

The app ID for the App Store.

Example: 1234

ios_app_name

type: string

The name of the app (suitable for display).

Example: Electronic Example iOS

iphone_url

type: string

A custom scheme for the iPhone app.

Example: example-iphone://electronic

iphone_app_store_id

type: string

The app ID for the App Store.

Example: 5678

iphone_app_name

type:string

The name of the app (suitable for display).

Example: Electronic Example iPhone

ipad_url

type: string

A custom scheme for the iPhone app.

Example: example-ipad://electronic

ipad_app_store_id

type: string

The app ID for the App Store.

Example: 9010

ipad_app_name

type: string

The name of the app (suitable for display).

Example: Electronic Example iPad

android_url

type: string

A custom scheme for the Android app.

Example: example-android://electronic

android_package

type: string

A fully-qualified package name for intent generation.

Exammple: com.electronic

android_class

type: string

A fully-qualified Activity class name for intent generation.

Example: com.electronic.Example

android_app_name

type: string

The name of the app (suitable for display).

Example: Electronic Example Android

The following sections are only relevant if you want to manage your catalogs using this API.

Create a Destination Catalog using the API

A destination catalog is a container for the destinations you want to promote. To use the catalog API, make sure you have the appropriate Marketing API Access Level and that you have accepted the Terms of Service by creating your first catalog through Business Manager.

To create a destination catalog for Dynamic Ads for Destinations, set vertical to destinations:

curl -X POST \ -F 'name="Test Destination Catalog"' \ -F 'vertical="destinations"' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.1/{business-id}/owned_product_catalogs
const adsSdk = require('facebook-nodejs-ads-sdk'); const Business = adsSdk.Business; const ProductCatalog = adsSdk.ProductCatalog; let access_token = '<ACCESS_TOKEN>'; let app_secret = '<APP_SECRET>'; let app_id = '<APP_ID>'; let id = '<ID>'; const api = adsSdk.FacebookAdsApi.init(access_token); const showDebugingInfo = true; // Setting this to true shows more debugging info. if (showDebugingInfo) { api.setDebug(true); } const logApiCallResult = (apiCallName, data) => { console.log(apiCallName); if (showDebugingInfo) { console.log('Data:' + JSON.stringify(data)); } }; let fields, params; fields = [ ]; params = { 'name' : 'Test Destination Catalog', 'vertical' : 'destinations', }; let owned_product_catalogs = (new Business(id)).createOwnedProductCatalog( fields, params ); logApiCallResult('owned_product_catalogs api call complete.', owned_product_catalogs);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\Business; use FacebookAds\Object\ProductCatalog; use FacebookAds\Api; use FacebookAds\Logger\CurlLogger; $access_token = '<ACCESS_TOKEN>'; $app_secret = '<APP_SECRET>'; $app_id = '<APP_ID>'; $id = '<ID>'; $api = Api::init($app_id, $app_secret, $access_token); $api->setLogger(new CurlLogger()); $fields = array( ); $params = array( 'name' => 'Test Destination Catalog', 'vertical' => 'destinations', ); echo json_encode((new Business($id))->createOwnedProductCatalog( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebookads.adobjects.business import Business from facebookads.adobjects.productcatalog import ProductCatalog from facebookads.api import FacebookAdsApi access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAdsApi.init(access_token=access_token) fields = [ ] params = { 'name': 'Test Destination Catalog', 'vertical': 'destinations', } print Business(id).create_owned_product_catalog( fields=fields, params=params, )
import com.facebook.ads.sdk.*; import java.io.File; import java.util.Arrays; public class SAMPLE_CODE_EXAMPLE { public static void main (String args[]) throws APIException { String access_token = \"<ACCESS_TOKEN>\"; String app_secret = \"<APP_SECRET>\"; String app_id = \"<APP_ID>\"; String id = \"<ID>\"; APIContext context = new APIContext(access_token).enableDebug(true); new Business(id, context).createOwnedProductCatalog() .setName(\"Test Destination Catalog\") .setVertical(ProductCatalog.EnumVertical.VALUE_DESTINATIONS) .execute(); } }
require 'facebook_ads' access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAds.configure do |config| config.access_token = access_token config.app_secret = app_secret end business = FacebookAds::Business.get(id) owned_product_catalogs = business.owned_product_catalogs.create({ name: 'Test Destination Catalog', vertical: 'destinations', })

Upload your destination feeds through the API

Once you have created the catalog, you have to upload your destination feed(s) to Facebook. Use the API to create a feed object for every feed you want to upload. We support scheduled and direct uploads.

For scheduled uploads, specify a schedule when you create the feed. For non scheduled uploads, don't specify a schedule.

use FacebookAds\Object\ProductFeed;
use FacebookAds\Object\Fields\ProductFeedFields;
use FacebookAds\Object\Fields\ProductFeedScheduleFields;

$product_feed = new ProductFeed(null, <PRODUCT_CATALOG_ID>);

$product_feed->setData(array(
  ProductFeedFields::NAME => 'Test Feed',
  ProductFeedFields::SCHEDULE => array(
    ProductFeedScheduleFields::INTERVAL => 'DAILY',
    ProductFeedScheduleFields::URL =>'http://www.example.com/sample_feed.tsv',
    ProductFeedScheduleFields::HOUR => 22,
  ),
));

$product_feed->create();
from facebookads.adobjects.productfeed import ProductFeed

product_feed = ProductFeed(parent_id=<PRODUCT_CATALOG_ID>)

product_feed[ProductFeed.Field.name] = 'Test Feed'
product_feed[ProductFeed.Field.schedule] = {
    'interval': 'DAILY',
    'url': 'http://www.example.com/sample_feed.tsv',
    'hour': 22,
}

product_feed.remote_create()
ProductFeed productFeed = new ProductCatalog(<PRODUCT_CATALOG_ID>, context).createProductFeed()
  .setName("Test Feed")
  .setSchedule("{\"interval\":\"DAILY\",\"url\":\"http://www.example.com/sample_feed.tsv\",\"hour\":\"22\"}")
  .execute();
String product_feed_id = productFeed.getId();
curl \
  -F 'name=Test Feed' \
  -F 'schedule={ 
    "interval": "DAILY", 
    "url": "http:\/\/www.example.com\/sample_feed.tsv", 
    "hour": 22 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PRODUCT_CATALOG_ID>/product_feeds

In either case, the response is:

{ "id" : <PRODUCT_FEED_ID> }

Once you have created the feed (with or without schedule), you can do a one time upload of your feed using the PRODUCT_FEED_ID:

curl \
-F "url=http://www.example.com/sample_feed.xml" \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<API_VERSION>/<PRODUCT_FEED_ID>/uploads

Filter Destination Catalog to Destination Sets

Reference Docs

A destination set is a subset of your catalog. To setup Dynamic Ads for Destinations, you need a destination set. Therefore, you have to create at least one.

Destination sets are defined by filters that are applied to the destination catalog. For example, you can create a destination set with all destinations that had a large price drop. Do note you can also create a destination set without any filters. In that case, the destination set will contain all destinations in your catalog.

use FacebookAds\Object\ProductSet;
use FacebookAds\Object\Fields\ProductSetFields;

$destination_set = new ProductSet(null, <PRODUCT_CATALOG_ID>);

$destination_set->setData(array(
  ProductSetFields::NAME => 'Test Destination Set',
  ProductSetFields::FILTER => array(
    'price_change' => array(
      'lt' => -20,
    ),
  ),
));

$destination_set->create();
from facebookads.adobjects.productset import ProductSet

destination_set = ProductSet(None, <PRODUCT_CATALOG_ID>)

destination_set[ProductSet.Field.name] = 'Test Destination Set'
destination_set[ProductSet.Field.filter] = {
    'price_change': {
        'lt': -20,
    },
}

destination_set.remote_create()
curl \
  -F 'name=Test Destination Set' \
  -F 'filter={"price_change":{"lt":-20}}' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/<PRODUCT_CATALOG_ID>/product_sets

The filter parameter is made up of the following operators and data:

OperatorsThe type of filter

i_contains

Contains substring. Operator is case insensitive.

i_not_contains

Does not contain substring. Operator is case insensitive.

contains

Contains substring. Operator is case insensitive.

not_contains

Does not contain substring. Operator is case insensitive.

eq

Equal to. Operator is case insensitive.

neq

Not equal to. Operator is case insensitive.

lt

Less than. For numeric fields only.

lte

Less than or equal to. For numeric fields only.

gt

Greater than. For numeric fields only.

gte

Greater than or equal to. For numeric fields only.

DataThe data being filtered

country

Country of the destination.

price

Price for this destination. The price is in cents.

currency

Currency.

price_change

Price drop or increase.

city

City of the destination.

description

Description for this destination.

name

Name for this destination.

destination_set_id

Your unique identifier for the destination within the catalog.

Associate the catalog to your event sources

To map the data from your event sources (your pixels and app events) to your catalog, every catalog must be associated with these event sources. You can do this by visiting your business manager's catalog page and clicking the 'Associate Sources' button. Make sure to select the app and pixel that are receiving the travel events. Alternatively, you can use the API.

use FacebookAds\Object\ProductCatalog;

$product_catalog = new ProductCatalog(<PRODUCT_CATALOG_ID>);
$product_catalog->createExternalEventSource(array(), array(
  'external_event_sources' => array(
    <PIXEL_ID>,
    <APP_ID>,
  ),
));
from facebookads.adobjects.productcatalog import ProductCatalog

product_catalog = ProductCatalog(<PRODUCT_CATALOG_ID>)
product_catalog.add_external_event_sources([
    <PIXEL_ID>,
    <APP_ID>,
])
curl \
  -F 'external_event_sources=["<PIXEL_ID>","<APP_ID>"]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/<PRODUCT_CATALOG_ID>/external_event_sources

When making the API call, specify the following parameters:

Parameter Name & TypeDescription

external_event_sources

type: int[]

A list of Pixel and App IDs to associate with the catalog.