Dynamic Ads For Travel - Building Audiences

Dynamic Ads for travel enable you to show people ads based on their cross-device travel intent. User intent is collected from website and mobile apps into a travel audience which will then be used to target your customers.

In this document we will walk you through how to create a travel audience:

Step 1: Setup User Signals for Travel Events

Standard events are a set of predefined event names you can send from your website or app that allow you to both measure the performance of your campaigns and to capture intent from your audiences.

Dynamic Ads for travel requires the following standard events to be sent from your website pixel and app:

EventApp eventHotelFlightDestinationDescription

Search

fb_mobile_search

Required

Required

Required

When someone has made a travel-related search

ViewContent

fb_mobile_content_view

Required

Required

Required

When someone has viewed details of a specific travel entity, e.g. a hotel or a destination

InitiateCheckout

fb_mobile_initiated_checkout

Required

Required

When someone has begun the booking process

Purchase

fb_mobile_purchase

Required

Required

When someone has completed their travel booking

For example, to report a Search event for a hotel-listing using your FB pixel or the FB App SDK you would place the following code on your search-results page:

<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','//connect.facebook.net/en_US/fbevents.js');

// Insert Your Facebook Pixel ID below. 
fbq('init', '<FB_PIXEL_ID>');

fbq('track', 'Search', { 
  content_type: 'hotel', 
  content_ids: ['1234', '2345', '3456', '4567'], // Top search results
  checkin_date: '2016-02-12', 
  checkout_date: '2016-02-19', 
  city: 'New York City', //Required for Search event
  region: 'New York', // region is the state for the US. Required for Search event
  country: 'US', //Required for Search event
} );
</script>
<!-- End Facebook Pixel Code -->
Bundle parameters = new Bundle();
parameters.putString(AppEventsConstants.EVENT_PARAM_CONTENT_TYPE, "hotel");
parameters.putString(AppEventsConstants.EVENT_PARAM_CONTENT_ID, "[\"1234\", \"2345\", \"3456\", \"4567\"]"); // top search results

// we must prefix all travel-specific parameters with fb_
parameters.putString("fb_checkin_date", "2016-02-12");
parameters.putString("fb_checkout_date", "2016-02-19");
parameters.putString("fb_city", "New York City"); // Required for Search event
parameters.putString("fb_region", "New York"); // region is the state for the US. Required for Search event
parameters.putString("fb_country", "US"); // Required for Search event

logger.logEvent(
  AppEventsConstants.EVENT_NAME_SEARCHED,
  parameters
);
[FBSDKAppEvents logEvent:FBSDKAppEventNameSearched
  parameters:@{
    FBSDKAppEventParameterNameContentType : @"hotel",
      FBSDKAppEventParameterNameContentID : @"[\"1234\", \"2345\", \"3456\", \"4567\"]", // top search results

// we must prefix all travel-specific parameters with fb_

                       @"fb_checkin_date" : @"2016-02-12",
                      @"fb_checkout_date" : @"2016-02-19",
                               @"fb_city" : @"New York City", //Required for Search event
                             @"fb_region" : @"New York", // region is the state for the US. Required for Search event
                            @"fb_country" : @"US", // Required for Search event
  }
];

For more details on pixel setup, see Facebook Pixel Setup.

Once you have determined which events should be fired where, the next step is to fill out the parameters.

Parameters

The parameters sent depend on the type of the travel being represented e.g. hotel, flight (route), destination (and/or travel packages).

In the parameters table below:

  • 'Recommended' indicates the recommended parameter. These parameters aren't strictly required but allow us to make better recommendations in your ads. Try to provide as many as possible.
  • 'blank': Not applicable.
Param nameMobile app paramHotelFlightDestination

content_type

fb_content_type

This should be set to hotel

This should be set to flight

This should be set to destination

content_ids

fb_content_id

Required

Required

checkin_date

fb_checkin_date

Recommended. (We'll use default date if not provided)

checkout_date

fb_checkout_date

Recommended. (We'll use default date if not provided)

departing_departure_date

fb_departing_departure_date

Required

returning_departure_date

fb_returning_departure_date

Required if you have return journey

origin_airport

fb_origin_airport

Required

destination_airport

fb_destination_airport

Required

value

_valueToSum

Required for Purchase event

Required for Purchase event

currency

fb_currency

Required for Purchase event

Required for Purchase event

destination_ids (where available)

fb_destination_ids

Recommended

Recommended

city

fb_city

Required for Search event. Recommended otherwise.

Required for Search event. Recommended otherwise.

region

fb_region

Required for Search event. Recommended otherwise.

Required for Search event. Recommended otherwise.

country

fb_country

Required for Search event. Recommended otherwise.

Required for Search event. Recommended otherwise.

departing_arrival_date

fb_departing_arrival_date

Recommended

returning_arrival_date

fb_returning_arrival_date

Recommended

suggested_destinations

fb_suggested_destinations

Recommended

travel_start

fb_travel_start

Recommended

travel_end

fb_travel_end

Recommended

num_adults

fb_num_adults

Recommended

Recommended

num_children

fb_num_children

Recommended

Recommended

num_infants

fb_num_infants

Recommended

travel_class

fb_travel_class

Recommended

suggested_hotels

fb_suggested_hotels

Recommended

user_score

fb_user_score

Recommended

Recommended

hotel_score

fb_hotel_score

Recommended

purchase_value

fb_purchase_value

Recommended

Recommended

purchase_currency

fb_purchase_currency

Recommended

Recommended

preferred_star_ratings

fb_preferred_star_ratings

Recommended for Search event

preferred_price_range

fb_preferred_price_range

Recommended for Search event

preferred_neighborhoods

fb_preferred_neighborhoods

Recommended for Search event

preferred_num_stops

fb_preferred_num_stops

Recommended.(Default to 0 if not specified)

Parameter Details

Parameter NameDescription

checkin_date

Type: string.

The date the user is wanting to check-in to the hotel in the hotel's time-zone. We accept the following date-formats:

  • YYYYMMDD e.g. 20170623
  • YYYY-MM-DD e.g. 2017-06-23
  • YYYY-MM-DDThh:mmTZD e.g. 2017-06-23T15:30GMT
  • YYYY-MM-DDThh:mm:ssTZD e.g. 2017-06-23T15:30:00GMT

checkout_date

Type: string.

The date the user is wanting to check-out from the hotel in the hotel's time-zone. We accept the same date formats as listed for checkin_date.

city

Type: string.

Provide the city of the location from user intent, e.g. Auckland.

content_ids (where available)

Type: string or string[].

Any relevant ID(s) as listed in your travel catalog, e.g. for ViewContent event you might send the ID of the item presented, or for Search event you might send an array of IDs for the top search results.

content_type

Type: enum {hotel, flight, destination}.

country

Type: string.

Provide the country of the location from user intent, e.g. New Zealand.

currency

Type: string.

Currency for the value. Specified using ISO 4217 currency format, e.g. USD.

departing_arrival_date

Type: string.

The date (and time) of arrival at the destination. We accept the same date formats as listed for checkin_date.

departing_departure_date

Type: string.

The date (and time) of the start of the outbound journey. We accept the same date formats as listed for checkin_date.

destination_airport

Type: string.

Destination airport using IATA code.

destination_ids (where available)

Type: string or string[].

If you have a destination catalog, you can associate one or more destinations in your destination catalog with a specific hotel pixel event. For instance, a particular hotel may be linked to a nearby museum and a nearby beach, both of which are destinations in the destination catalog.

hotel_score

Type: float.

An indicator representing the relative value of this hotel to the advertiser compared to its other hotels.

num_adults

Type: int.

Number of adults that will be staying, e.g. 2.

num_children

Type: int.

Number of children that will be staying, e.g. 1.

num_infants

Type: int.

Number of infants travelling on this journey.

origin_airport

Type: string.

Origin airport using IATA code.

preferred_neighborhoods

Type: string[].

A list of preferred neighborhoods that a user is filtering for.

preferred_num_stops

Type: int.

Set to 0 if the user is only looking for direct flights, 1 for up to one stop-over, etc.

preferred_price_range

Type [int (min), int (max)].

A tuple of minimum and maximum room rates that a user is filtering for.

preferred_star_ratings

Type [int (min), int (max)].

A tuple of minimum and maximum hotel star rating that a user is filtering for.

purchase_value

Type: float.

The purchase price of the booking for ViewContent, InitiateCheckout and Purchase events. This will be the lowest price among the search results for Search event.

purchase_currency

Type: string.

Currency for the purchase_value. Specified using ISO 4217 currency format, e.g. USD.

region

Type: string.

Provide the state/district/region of the location from user intent, e.g. North Island.

returning_arrival_date

Type: string.

The date (and time) when we have completed the return journey. We accept the same date formats as listed for checkin_date.

returning_departure_date

Type: string.

The date (and time) of the start of the return journey. This is required if you have return journey. We accept the same date-formats as listed for departing_departure_date.

suggested_destinations

Type: string[].

A list of IDs representing destination suggestions for this user.

This parameter is NOT applicable for the Search event.

suggested_hotels

Type: string[].

A list of IDs representing hotel suggestions for this user.

This parameter is NOT applicable for the Search event.

travel_class

Type: enum { economy, premium, business, first }. Class of travel.

travel_end

Type: string.

The end date of user's trip. We accept the same date-formats listed for checkin_date

travel_start

Type: string.

The start date of user's trip. We accept the same date formats as listed for checkin_date.

user_score

Type: float.

An indicator representing the relative value of this user to the advertiser.

value

Type: float.

A number that quantifies the value of this event to the advertiser.

Step 2: Associate User Signals to the Travel Catalog(s)

You next need to associate your event sources with each of your travel catalogs that will be consuming this data. You can do this by visiting your Business Manager's Catalog Page and clicking the 'Associate Sources' button. Make sure to select the pixel and app that will be receiving the DAT events. Alternatively, you can make a HTTP POST call to:

use FacebookAds\Object\ProductCatalog;

$product_catalog = new ProductCatalog(<PRODUCT_CATALOG_ID>);
$product_catalog->setExternalEventSources(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.8/<PRODUCT_CATALOG_ID>/external_event_sources

When making the API call, specify the following parameters:

Field NameData TypeDescription

external_event_sources (required)

int[]

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

Step 3: Create And Share Out A Travel Event Source Group

In order to build a travel audience, an admin for your business must create an event source group to group all of your sources for travel intent signal together. You do this by making an HTTP POST call to:

use FacebookAds\Object\EventSourceGroup;
use FacebookAds\Object\Fields\EventSourceGroupFields;

$event_source_group = new EventSourceGroup(null, <BUSINESS_ID>);
$event_source_group->setData(array(
  EventSourceGroupFields::NAME => 'My Travel Company Events',
  EventSourceGroupFields::EVENT_SOURCES => array(
    <PIXEL_ID>,
    <APP_ID>,
  ),
));

$event_source_group->create();
from facebookads.adobjects.eventsourcegroup import EventSourceGroup

event_source_group = EventSourceGroup(parent_id=<BUSINESS_ID>)
event_source_group[EventSourceGroup.Field.name] = 'My Travel Company Events'
event_source_group[EventSourceGroup.Field.event_sources] = [
    <PIXEL_ID>,
    <APP_ID>,
]

event_source_group.remote_create()
curl \
  -F 'name=My Travel Company Events' \
  -F 'event_sources=["<PIXEL_ID>","<APP_ID>"]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/<BUSINESS_ID>/event_source_groups

You must then share this event source group out to any ad accounts that wish to create an audience backed by it. Again, this is done by making an HTTP POST call:

use FacebookAds\Object\EventSourceGroup;

$event_source_group = new EventSourceGroup(<EVENT_SOURCE_GROUP_ID>);
// ad account id without 'act_'
$event_source_group->createSharedAccount(array(), array(
  'accounts' => array(
    '<ACCOUNT_ID_WITHOUT_ACT>',
  ),
));
from facebookads.adobjects.eventsourcegroup import EventSourceGroup

event_source_group = EventSourceGroup(<EVENT_SOURCE_GROUP_ID>)
# ad account id without 'act_'
response = event_source_group.create_shared_account(
    params={
        'accounts': ['<ACCOUNT_ID_WITHOUT_ACT>'],
    },
)
print(response)
curl \
  -F 'accounts=["<ACCOUNT_ID_WITHOUT_ACT>"]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/<EVENT_SOURCE_GROUP_ID>/shared_accounts

Step 4: Create Travel Audiences

At this point you should have your user signal (i.e. pixel and/or app events) set-up and associated with an event source group and your travel catalog(s).

To retarget people who have shown explicit traveler intent, you must create a dynamic travel audience of people who you would like to serve the ad to. You include/exclude people from the audience based on the set of traveler intent signals that they have demonstrated through sources such as your app or pixel event fires. You can also apply additional rule-based filters on top of the events like with Website Custom Audiences.

To set-up a new travel audience, make an HTTP POST to /act_<AD_ACCOUNT_ID>/customaudiences.

Required Parameters

Field NameData TypeDescription

name

string

A name given to identify the audience.

subtype

enum {CLAIM}

The type of custom audience.

Must be set to CLAIM for Dynamic Ads for travel.

claim_objective

enum {TRAVEL}

The objective of the audience when the subtype is CLAIM.

Must be set to TRAVEL for Dynamic Ads for travel.

content_type

enum {HOTEL, FLIGHT, DESTINATION}

Specify the type of signal that should be used to build this audience.

event_source_group

id

Specify the event source group whose events will back the audience.

inclusions

object[]

An array of JSON objects listing each intent signal that would make a person eligible for this audience.

event

(required)

enum {

Search,

ViewContent,

InitiateCheckout,

Purchase

}

The event name of a signal you want to consider for inclusion, e.g. {"event": "Search", …}.

retention

(required)

object

The minimum/maximum amount of time since the event was received for it to be considered for purposes of inclusion, e.g. {…, "retention": {"min_seconds": 0, "max_seconds": 259200}, …}. The retention window must be at least 4 hours.

booking_window

object

The minimum/maximum amount of time between the event being received and the desired check-in date, e.g. {"booking_window": {"min_seconds": 0, "max_seconds": 259200}}. You can also use this to target people whose checkin_date has already passed, e.g. {"booking_window": {"max_seconds": 0}}.

count

JSON operators

The number of times that the event has been fired. You can use both equality and numeric comparison operators here, e.g. {…"count": {"lte": 3}, …}.

Optional Parameters

Field NameData TypeDescription

description

string

A further description of the audience.

exclusions

object[]

An array of JSON objects listing each intent signal that would exclude an eligible person from this audience.

event

(required)

enum {

Search

ViewContent

InitiateCheckout

Purchase

}

The event name of a signal you want to be considered for exclusion, e.g. {"event": "Purchase", …}.

retention

(required)

object

The minimum/maximum amount of time since the event was received for it to be considered for the purposes of exclusion, e.g. {…, "retention": {"min_seconds": 0, "max_seconds": 259200}, …}. The retention window must be at least 4 hours.

rule

object

A classical audience rule to be applied to the event stream before any inclusions and exclusions are processed.

Expand for the list of DAT-specific fields that are available for which you can use with any of the standard JSON operators.

hotel_set_id

int

The ID of hotel sets that contain hotels that match with the event's content_ids parameter, e.g. {…, "hotel_set_id": {"eq": 123456789}, …}.

length_of_stay

int

Number of nights spent during the trip, e.g. {… "length_of_stay": {"eq": 1}, …}.

number_of_weekends

int

Number of weekends between the start and end date, e.g. {…, "number_of_weekends": {"gte": 5}, …}.

num_travelers

int

Total number of travelers, e.g. {…, "num_travelers": {"gt": 1}, …}.

  • For a content_type of hotel this is num_adults + num_children.
  • For a content_type of flight this is num_adults + num_infants + num_children.

Date fields: e.g.

  • checkin_date
  • checkout_date
  • departing_departure_date
  • departing_arrival_date
  • returning_departure_date
  • returning_arrival_date
  • travel_start
  • travel_end

string

Depending on the content_type, The appropriate date fields can be used to create travel audience, e.g. {"checkin_date": {"gte": "2016-09-01"}}.

itinerary_contains_date

string

The trip contains a specific date, e.g. {"itinerary_contains_date": {"eq": "2016-12-25"}}.

For example, here we create a travel audience that targets lone travelers who have searched at least 3 times in the last 5 days but haven't booked yet:

use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Fields\CustomAudienceFields;
use FacebookAds\Object\Values\CustomAudienceSubtypeValues;
use FacebookAds\Object\Values\CustomAudienceClaimObjectiveValues;
use FacebookAds\Object\Values\CustomAudienceContentTypeValues;

$custom_audience = new CustomAudience(null, 'act_<AD_ACCOUNT_ID>');
$custom_audience->setData(array(
  CustomAudienceFields::NAME => 'Travel Audience',
  CustomAudienceFields::SUBTYPE => CustomAudienceSubtypeValues::CLAIM,
  CustomAudienceFields::CLAIM_OBJECTIVE =>
    CustomAudienceClaimObjectiveValues::TRAVEL,
  CustomAudienceFields::CONTENT_TYPE => CustomAudienceContentTypeValues::HOTEL,
  CustomAudienceFields::EVENT_SOURCE_GROUP => <EVENT_SOURCE_GROUP_ID>,
  CustomAudienceFields::RULE => array(
    'num_travelers' => array('eq' => 1),
  ),
  'inclusions' => array(
    array(
      'event' => 'Search',
      'count' => array('gt' => 3),
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 432000),
    ),
  ),
  'exclusions' => array(
    array(
      'event' => 'Purchase',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
));
$custom_audience->create();
from facebookads.adobjects.customaudience import CustomAudience

audience = CustomAudience(parent_id='act_<AD_ACCOUNT_ID>')
audience[CustomAudience.Field.name] = 'Travel Audience'
audience[CustomAudience.Field.subtype] = CustomAudience.Subtype.claim
audience[CustomAudience.Field.claim_objective] = \
    CustomAudience.ClaimObjective.travel
audience[CustomAudience.Field.content_type] = CustomAudience.ContentType.hotel
audience[CustomAudience.Field.event_source_group] = <EVENT_SOURCE_GROUP_ID>
audience[CustomAudience.Field.rule] = {
    'num_travelers': {'eq': 1},
}
audience['inclusions'] = [
    {
        'event': 'Search',
        'count': {'gt': 3},
        'retention': {'min_seconds': 0, 'max_seconds': 432000},
    },
]
audience['exclusions'] = [
    {
        'event': 'Purchase',
        'retention': {'min_seconds': 0, 'max_seconds': 432000},
    },
]

audience.remote_create()
curl \
  -F 'name=Travel Audience' \
  -F 'subtype=CLAIM' \
  -F 'claim_objective=TRAVEL' \
  -F 'content_type=HOTEL' \
  -F 'event_source_group=<EVENT_SOURCE_GROUP_ID>' \
  -F 'rule={"num_travelers":{"eq":1}}' \
  -F 'inclusions=[ 
    { 
      "event": "Search", 
      "count": {"gt":3}, 
      "retention": {"min_seconds":0,"max_seconds":432000} 
    } 
  ]' \
  -F 'exclusions=[{"event":"Purchase","retention":{"min_seconds":0,"max_seconds":172800}}]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customaudiences

And in this example, we create a travel audience that targets people who viewed or started booking a hotel in a hotel set in the last 2 days but never completed their booking:

use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Fields\CustomAudienceFields;
use FacebookAds\Object\Values\CustomAudienceSubtypeValues;
use FacebookAds\Object\Values\CustomAudienceClaimObjectiveValues;
use FacebookAds\Object\Values\CustomAudienceContentTypeValues;

$custom_audience = new CustomAudience(null, 'act_<AD_ACCOUNT_ID>');
$custom_audience->setData(array(
  CustomAudienceFields::NAME => 'Travel Audience',
  CustomAudienceFields::SUBTYPE => CustomAudienceSubtypeValues::CLAIM,
  CustomAudienceFields::CLAIM_OBJECTIVE =>
    CustomAudienceClaimObjectiveValues::TRAVEL,
  CustomAudienceFields::CONTENT_TYPE => CustomAudienceContentTypeValues::HOTEL,
  CustomAudienceFields::EVENT_SOURCE_GROUP => <EVENT_SOURCE_GROUP_ID>,
  CustomAudienceFields::RULE => array(
    'hotel_set_id' => array('eq' => <HOTEL_SET_ID>),
  ),
  'inclusions' => array(
    array(
      'event' => 'ViewContent',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
    array(
      'event' => 'InitiateCheckout',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
  'exclusions' => array(
    array(
      'event' => 'Purchase',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
));
$custom_audience->create();
from facebookads.adobjects.customaudience import CustomAudience

audience = CustomAudience(parent_id='act_<AD_ACCOUNT_ID>')
audience[CustomAudience.Field.name] = 'Travel Audience'
audience[CustomAudience.Field.subtype] = CustomAudience.Subtype.claim
audience[CustomAudience.Field.claim_objective] = \
    CustomAudience.ClaimObjective.travel
audience[CustomAudience.Field.content_type] = CustomAudience.ContentType.hotel
audience[CustomAudience.Field.event_source_group] = <EVENT_SOURCE_GROUP_ID>
audience[CustomAudience.Field.rule] = {
    'hotel_set_id': {'eq': <HOTEL_SET_ID>},
}
audience['inclusions'] = [
    {
        'event': 'ViewContent',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
    {
        'event': 'InitiateCheckout',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]
audience['exclusions'] = [
    {
        'event': 'Purchase',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]

audience.remote_create()
curl \
  -F 'name=Travel Audience' \
  -F 'subtype=CLAIM' \
  -F 'claim_objective=TRAVEL' \
  -F 'content_type=HOTEL' \
  -F 'event_source_group=<EVENT_SOURCE_GROUP_ID>' \
  -F 'rule={"hotel_set_id":{"eq":"<HOTEL_SET_ID>"}}' \
  -F 'inclusions=[ 
    {"event":"ViewContent","retention":{"min_seconds":0,"max_seconds":172800}}, 
    { 
      "event": "InitiateCheckout", 
      "retention": {"min_seconds":0,"max_seconds":172800} 
    } 
  ]' \
  -F 'exclusions=[{"event":"Purchase","retention":{"min_seconds":0,"max_seconds":172800}}]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customaudiences

In this example, we create a travel audience that targets people who have initiated check out or purchased the flight tickets in the last 5 days and their flight booking window is between 2 to 7 days:

use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Fields\CustomAudienceFields;
use FacebookAds\Object\Values\CustomAudienceSubtypeValues;
use FacebookAds\Object\Values\CustomAudienceClaimObjectiveValues;
use FacebookAds\Object\Values\CustomAudienceContentTypeValues;

$custom_audience = new CustomAudience(null, 'act_<AD_ACCOUNT_ID>');
$custom_audience->setData(array(
  CustomAudienceFields::NAME => 'Travel Audience',
  CustomAudienceFields::SUBTYPE => CustomAudienceSubtypeValues::CLAIM,
  CustomAudienceFields::CLAIM_OBJECTIVE =>
    CustomAudienceClaimObjectiveValues::TRAVEL,
  CustomAudienceFields::CONTENT_TYPE => CustomAudienceContentTypeValues::FLIGHT,
  CustomAudienceFields::EVENT_SOURCE_GROUP => <EVENT_SOURCE_GROUP_ID>,
  'inclusions' => array(
    array(
      'event' => 'InitiateCheckout',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 432000),
      'booking_window' => array('min_seconds'=> 172800, 'max_seconds'=> 604800),
    ),
    array(
      'event' => 'Purchase',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 432000),
      'booking_window' => array('min_seconds'=> 172800, 'max_seconds'=> 604800),
    ),
  ),
));
$custom_audience->create();
from facebookads.adobjects.customaudience import CustomAudience

audience = CustomAudience(parent_id='act_<AD_ACCOUNT_ID>')
audience[CustomAudience.Field.name] = 'Travel Audience'
audience[CustomAudience.Field.subtype] = CustomAudience.Subtype.claim
audience[CustomAudience.Field.claim_objective] = \
    CustomAudience.ClaimObjective.travel
audience[CustomAudience.Field.content_type] = CustomAudience.ContentType.flight
audience[CustomAudience.Field.event_source_group] = <EVENT_SOURCE_GROUP_ID>
audience['inclusions'] = [
    {
        "event": "InitiateCheckout",
        "retention": {"min_seconds": 0, "max_seconds": 432000},
        "booking_window": {"min_seconds": 172800, "max_seconds": 604800},
    },
    {
        "event": "Purchase",
        "retention": {"min_seconds": 0, "max_seconds": 432000},
        "booking_window": {"min_seconds": 172800, "max_seconds": 604800},
    },
]

audience.remote_create()
curl \
  -F 'name=Travel Audience' \
  -F 'subtype=CLAIM' \
  -F 'claim_objective=TRAVEL' \
  -F 'content_type=FLIGHT' \
  -F 'event_source_group=<EVENT_SOURCE_GROUP_ID>' \
  -F 'inclusions=[ 
    { 
      "event": "InitiateCheckout", 
      "retention": {"min_seconds":0,"max_seconds":432000}, 
      "booking_window": {"min_seconds":172800,"max_seconds":604800} 
    }, 
    { 
      "event": "Purchase", 
      "retention": {"min_seconds":0,"max_seconds":432000}, 
      "booking_window": {"min_seconds":172800,"max_seconds":604800} 
    } 
  ]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customaudiences

In this example, we create a travel audience that targets people who have searched hotels in 'New York City' more than 3 times in the past 2 days but haven't booked yet:

use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Fields\CustomAudienceFields;
use FacebookAds\Object\Values\CustomAudienceSubtypeValues;
use FacebookAds\Object\Values\CustomAudienceClaimObjectiveValues;
use FacebookAds\Object\Values\CustomAudienceContentTypeValues;

$custom_audience = new CustomAudience(null, 'act_<AD_ACCOUNT_ID>');
$custom_audience->setData(array(
  CustomAudienceFields::NAME => 'Travel Audience',
  CustomAudienceFields::SUBTYPE => CustomAudienceSubtypeValues::CLAIM,
  CustomAudienceFields::CLAIM_OBJECTIVE =>
    CustomAudienceClaimObjectiveValues::TRAVEL,
  CustomAudienceFields::CONTENT_TYPE => CustomAudienceContentTypeValues::HOTEL,
  CustomAudienceFields::EVENT_SOURCE_GROUP => <EVENT_SOURCE_GROUP_ID>,
  CustomAudienceFields::RULE => array(
    'destination' => array('i_contains' => 'New York City'),
  ),
  'inclusions' => array(
    array(
      'event' => 'Search',
      'count' => array('gt' => 3),
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
  'exclusions' => array(
    array(
      'event' => 'Purchase',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
));
$custom_audience->create();
from facebookads.adobjects.customaudience import CustomAudience

audience = CustomAudience(parent_id='act_<AD_ACCOUNT_ID>')
audience[CustomAudience.Field.name] = 'Travel Audience'
audience[CustomAudience.Field.subtype] = CustomAudience.Subtype.claim
audience[CustomAudience.Field.claim_objective] = \
    CustomAudience.ClaimObjective.travel
audience[CustomAudience.Field.content_type] = CustomAudience.ContentType.hotel
audience[CustomAudience.Field.event_source_group] = <EVENT_SOURCE_GROUP_ID>
audience[CustomAudience.Field.rule] = {
    'destination': {'i_contains': 'New York City'},
}
audience['inclusions'] = [
    {
        'event': 'Search',
        'count': {'gt': 3},
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]
audience['exclusions'] = [
    {
        'event': 'Purchase',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]

audience.remote_create()
curl \
  -F 'name=Travel Audience' \
  -F 'subtype=CLAIM' \
  -F 'claim_objective=TRAVEL' \
  -F 'content_type=HOTEL' \
  -F 'event_source_group=<EVENT_SOURCE_GROUP_ID>' \
  -F 'rule={"destination":{"i_contains":"New York City"}}' \
  -F 'inclusions=[ 
    { 
      "event": "Search", 
      "count": {"gt":3}, 
      "retention": {"min_seconds":0,"max_seconds":172800} 
    } 
  ]' \
  -F 'exclusions=[{"event":"Purchase","retention":{"min_seconds":0,"max_seconds":172800}}]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customaudiences

In this example, we create a travel audience that targets people who have searched hotels between specific checkin_date and checkout_date in the past 2 days but haven't booked yet:

use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Fields\CustomAudienceFields;
use FacebookAds\Object\Values\CustomAudienceSubtypeValues;
use FacebookAds\Object\Values\CustomAudienceClaimObjectiveValues;
use FacebookAds\Object\Values\CustomAudienceContentTypeValues;

$custom_audience = new CustomAudience(null, 'act_<AD_ACCOUNT_ID>');
$custom_audience->setData(array(
  CustomAudienceFields::NAME => 'Travel Audience',
  CustomAudienceFields::SUBTYPE => CustomAudienceSubtypeValues::CLAIM,
  CustomAudienceFields::CLAIM_OBJECTIVE =>
    CustomAudienceClaimObjectiveValues::TRAVEL,
  CustomAudienceFields::CONTENT_TYPE => CustomAudienceContentTypeValues::HOTEL,
  CustomAudienceFields::EVENT_SOURCE_GROUP => <EVENT_SOURCE_GROUP_ID>,
  CustomAudienceFields::RULE => array(
    'and' => array(
      array(
        'checkin_date' => array(
          'gte' => (new \DateTime("+3 day"))->format('Y-m-d')
        ),
      ),
      array(
        'checkout_date' => array(
          'lte' => (new \DateTime("+6 day"))->format('Y-m-d')
        ),
      ),
    ),
  ),
  'inclusions' => array(
    array(
      'event' => 'Search',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
  'exclusions' => array(
    array(
      'event' => 'Purchase',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
));
$custom_audience->create();
from facebookads.adobjects.customaudience import CustomAudience
import datetime

audience = CustomAudience(parent_id='act_<AD_ACCOUNT_ID>')
audience[CustomAudience.Field.name] = 'Travel Audience'
audience[CustomAudience.Field.subtype] = CustomAudience.Subtype.claim
audience[CustomAudience.Field.claim_objective] = \
    CustomAudience.ClaimObjective.travel
audience[CustomAudience.Field.content_type] = CustomAudience.ContentType.hotel
audience[CustomAudience.Field.event_source_group] = <EVENT_SOURCE_GROUP_ID>
audience[CustomAudience.Field.rule] = {
    'and': [
        {
            "checkin_date": {
                "gte": str(datetime.date.today() + datetime.timedelta(days=3)),
            },
        },
        {
            "checkout_date": {
                "gte": str(datetime.date.today() + datetime.timedelta(days=6)),
            },
        },
    ],
}
audience['inclusions'] = [
    {
        'event': 'Search',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]
audience['exclusions'] = [
    {
        'event': 'Purchase',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]

audience.remote_create()
curl \
  -F 'name=Travel Audience' \
  -F 'subtype=CLAIM' \
  -F 'claim_objective=TRAVEL' \
  -F 'content_type=HOTEL' \
  -F 'event_source_group=<EVENT_SOURCE_GROUP_ID>' \
  -F 'rule={ 
    "and": [ 
      {"checkin_date":{"gte":"2016-12-17"}}, 
      {"checkout_date":{"lte":"2016-12-20"}} 
    ] 
  }' \
  -F 'inclusions=[{"event":"Search","retention":{"min_seconds":0,"max_seconds":172800}}]' \
  -F 'exclusions=[{"event":"Purchase","retention":{"min_seconds":0,"max_seconds":172800}}]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customaudiences

In this example, we create a travel audience that targets people who have searched hotel stays containing a specific date (e.g. Christmas) in the past 2 days but haven't booked yet:

use FacebookAds\Object\CustomAudience;
use FacebookAds\Object\Fields\CustomAudienceFields;
use FacebookAds\Object\Values\CustomAudienceSubtypeValues;
use FacebookAds\Object\Values\CustomAudienceClaimObjectiveValues;
use FacebookAds\Object\Values\CustomAudienceContentTypeValues;

$custom_audience = new CustomAudience(null, 'act_<AD_ACCOUNT_ID>');
$custom_audience->setData(array(
  CustomAudienceFields::NAME => 'Travel Audience',
  CustomAudienceFields::SUBTYPE => CustomAudienceSubtypeValues::CLAIM,
  CustomAudienceFields::CLAIM_OBJECTIVE =>
    CustomAudienceClaimObjectiveValues::TRAVEL,
  CustomAudienceFields::CONTENT_TYPE => CustomAudienceContentTypeValues::HOTEL,
  CustomAudienceFields::EVENT_SOURCE_GROUP => <EVENT_SOURCE_GROUP_ID>,
  CustomAudienceFields::RULE => array(
    'itinerary_contains_date' => array(
      'eq' => (new \DateTime())->setDate(Date('Y'), 12, 25)->format('Y-m-d')
    ),
  ),
  'inclusions' => array(
    array(
      'event' => 'Search',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
  'exclusions' => array(
    array(
      'event' => 'Purchase',
      'retention' => array('min_seconds'=> 0, 'max_seconds'=> 172800),
    ),
  ),
));
$custom_audience->create();
from facebookads.adobjects.customaudience import CustomAudience
import datetime

audience = CustomAudience(parent_id='act_<AD_ACCOUNT_ID>')
audience[CustomAudience.Field.name] = 'Travel Audience'
audience[CustomAudience.Field.subtype] = CustomAudience.Subtype.claim
audience[CustomAudience.Field.claim_objective] = \
    CustomAudience.ClaimObjective.travel
audience[CustomAudience.Field.content_type] = CustomAudience.ContentType.hotel
audience[CustomAudience.Field.event_source_group] = <EVENT_SOURCE_GROUP_ID>
audience[CustomAudience.Field.rule] = {
    "itinerary_contains_date": {
        "eq": str(datetime.date(datetime.date.today().year, 12, 25)),
    },
}
audience['inclusions'] = [
    {
        'event': 'Search',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]
audience['exclusions'] = [
    {
        'event': 'Purchase',
        'retention': {'min_seconds': 0, 'max_seconds': 172800},
    },
]

audience.remote_create()
curl \
  -F 'name=Travel Audience' \
  -F 'subtype=CLAIM' \
  -F 'claim_objective=TRAVEL' \
  -F 'content_type=HOTEL' \
  -F 'event_source_group=<EVENT_SOURCE_GROUP_ID>' \
  -F 'rule={"itinerary_contains_date":{"eq":"2016-12-25"}}' \
  -F 'inclusions=[{"event":"Search","retention":{"min_seconds":0,"max_seconds":172800}}]' \
  -F 'exclusions=[{"event":"Purchase","retention":{"min_seconds":0,"max_seconds":172800}}]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customaudiences

Once you have created your audience(s), they can then be added to the targeting spec in your Dynamic Ads for travel campaign.

For Dynamic Ads for Travel, you do not need to provide hotel_set_id to create an audience. If hotel_set_id is specified, it can also be different from the one you specified in the ad set and ad creative.

This enables the following use cases:

  • Create a travel audience of people who searched, viewed or purchased any hotels from an entire catalog, and show them hotels from a specific hotel set.
  • Create a travel audience of people who searched, viewed or purchased flight tickets where there is no hotel set, and show them hotels from a specific hotel set.