Marketing API Version

Dynamic Audiences - Building Audiences

Dynamic Ads enables you to show people ads based on their cross-device purchasing intent. You can collect signals of user intent from mobile apps and websites then use this data to build an audience to target prospective customers.

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

Step 1: Setup User Signals for Events

To collect user signals from your mobile app or website, use App Events or Facebook Pixel:

For MobileFor Websites


Even if you are only running ads on desktops, you should still install Facebook SDK if you have an app to capture signals and expand your target audience.

For Mobile using App Events

You must add the following events to your app through Facebook SDK for iOS and Android:

EventsiOS EventAndroid Event

Search

FBSDKAppEventNameSearched

EVENT_NAME_SEARCHED

View Content

FBSDKAppEventNameViewedContent

EVENT_NAME_VIEWED_CONTENT

Add To Cart

FBSDKAppEventNameAddedToCart

EVENT_NAME_ADDED_TO_CART

Purchase

// Send through logPurchase

[FBSDKAppEvents logPurchase:(double) currency:<#(NSString *)#> parameters:<#(NSDictionary *)#>];

EVENT_NAME_PURCHASED

All of these events should include a content type and a content id or JSON array of content ids.

Unlike the Facebook pixel, App Events has no product_catalog_id parameter. Therefore you must make an association between your catalog and app with the external_event_sources endpoint below

Below is a sample add to cart event on iOS:

[FBSDKAppEvents logEvent:FBSDKAppEventNameAddedToCart
  valueToSum:54.23
  parameters:@{
    FBSDKAppEventParameterNameCurrency    : @"USD",
    FBSDKAppEventParameterNameContentType : @"product",
    FBSDKAppEventParameterNameContentID   : @"123456789"
  }
];

An example purchase event on iOS with two items purchased:

[FBSDKAppEvents logPurchase:54.23 
  currency:@"USD" 
  parameters:@{
    FBSDKAppEventParameterNameContentID   : @"[\"1234\",\"5678\"]",
    FBSDKAppEventParameterNameContentType : @"product"
  }
];

An example purchase event on Android with two items purchased:

Bundle parameters = new Bundle();
parameters.putString(AppEventsConstants.EVENT_PARAM_CURRENCY, "USD");
parameters.putString(AppEventsConstants.EVENT_PARAM_CONTENT_TYPE, "product");
parameters.putString(AppEventsConstants.EVENT_PARAM_CONTENT_ID, "[\"1234\",\"5678\"]");

logger.logEvent(
  AppEventsConstants.EVENT_NAME_PURCHASED,
  54.23,
  parameters
);

Using a Mobile Measurement Partner

To use Dynamic Ads with a mobile measurement partner (MMP), you should trigger required separate events as someone uses your app. The key interaction points you should track are when someone searches for products, views a product, adds something to a cart and purchases items. You should select the events at your MMP that correspond to the following standard Dynamic Ads events:

Event nameDescription

fb_mobile_search

Someone searches for products.

fb_mobile_content_view

When a person views a product.

fb_mobile_add_to_cart

Someone ads an item to the cart.

fb_mobile_purchase

Person purchases one or more items.

Also, you need two additional parameters for each of the events events to be registered successfully as a valid Dynamic Ads event. These two parameters represent the id of the item being viewed, added to cart or purchased and whether the id is a product or a product group id. The additional parameters available are:

Field NameDescriptionTypeRequired

fb_content_id

The retailer's product or product group id(s). This should be a string containing a JSON encoded array of ids. Use product ids if possible for more accurate targeting.

string

yes

fb_content_type

either 'product' or 'product_group', which needs to sync with the type of ids used as fb_content_id

string

yes

_valueToSum

The value of the product of purchase amount

string

no

fb_currency

The currency of the product or purchase amount

string

no

It is advisable to send the _valueToSum and fb_currency parameters when a purchase is made.

For Websites using Facebook Pixel

The following events must be added to your website if applicable:

  • Search
  • ViewCategory
  • ViewContent
  • AddToCart
  • Purchase

These events should be sent with the following data parameters:

Field NameDescriptionTypeRequired

content_ids

The retailer's product or product group id(s). Use product ids if possible for more accurate targeting.

string or string[]

yes

content_type

either 'product' or 'product_group', which needs to sync with the type of ids used as content_ids

string

yes

product_catalog_id

A product catalog to be used. If this is supplied this will be the only catalog pixel fires will be associated with.

string

no

It's important that the content_type matches the type of id(s) included in the content_ids parameter.

More details on specifying events and parameters are under Remarketing Events, see Tag API documentation.

An example of Search standard event is shown below. We recommend providing 5 to 10 items in content_ids from your top search results.

<!-- 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', 'PageView');

fbq('track', 'Search', { 
  search_string: 'leather sandals',
  content_ids: ['1234', '2424', '1318', '6832'], // top 5-10 search results
  content_type: 'product'
});
</script>
<!-- End Facebook Pixel Code -->

An example of ViewCategory event is shown below. We recommend providing 5 to 10 items in content_ids from your top results.

<!-- 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', 'PageView');

fbq('track', 'ViewCategory', {
  content_name: 'Really Fast Running Shoes',
  content_category: 'Apparel & Accessories > Shoes',
  content_ids: ['1234', '2424', '1318', '6832'], // top 5-10 results
  content_type: 'product'
});
</script>
<!-- End Facebook Pixel Code -->

An example of ViewContent standard event is shown below. More details on pixel setup, see Facebook Pixel.

<!-- 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', 'PageView');

fbq('track', 'ViewContent', {
  content_ids: ['1234'],
  content_type: 'product',
  value: 0.50,
  currency: 'USD'
});
</script>
<!-- End Facebook Pixel Code -->

An example of AddToCart standard event depends on how your eCommerce platform handles adding an item to a cart. If it is done dynamically this should be placed in an onclick event handler so it is triggered on the button click. If a separate page is loaded then the pixel event can be fired like normal.

<!-- 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', 'PageView');

// If you have a separate add to cart page that is loaded.
fbq('track', 'AddToCart', {
  content_ids: ['1234', '1853', '9386'],
  content_type: 'product',
  value: 3.50,
  currency: 'USD'
});
</script>
<!-- End Facebook Pixel Code -->

If the event needs to be fired on button click and there is no separate page that loads:


<!-- The below method uses jQuery, but that is not required --> <button id="addToCartButton">Add To Cart</button> <!-- Add event to the button's click handler --> <script type="text/javascript"> $( '#addToCartButton' ).click(function() { fbq('track', 'AddToCart', { content_ids: ['1234'], content_type: 'product', value: 2.99, currency: 'USD' }); }); </script>

An example of Purchase standard event:

<!-- 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', 'PageView');

fbq('track', 'Purchase', {
  content_ids: ['1234', '4642', '35838'],
  content_type: 'product',
  value: 247.35,
  currency: 'USD'
});
</script>

<!-- End Facebook Pixel Code -->

Step 2: Associate User Signals to Product Catalog

You next need to associate your event sources with each of your product catalogs so that Facebook can get this data and display the correct product in an ad. You can do this by visiting your Business Manager's Catalog Page and clicking the 'Associate Event Source' button. Make sure to select the app and pixel that will be receiving the Dynamic Ads events. Alternatively, you can make a HTTP POST call to:

use FacebookAds\Object\ProductCatalog;

$product_catalog = new ProductCatalog(<PRODUCT_CATALOG_ID>);
$product_catalog->createExternalEventSource(array(), 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 '0=<PIXEL_ID>' \
  -F '1=<APP_ID>' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/<PRODUCT_CATALOG_ID>/external_event_sources

You need to have permissions on the catalog, the pixel, and the app as well as the business.

When you make the API call, specify the following parameters:

Field NameDescriptionTypeRequired

external_event_sources

App and Pixel IDs to associate

An array of App and Pixel IDs to add

yes

Step 3: Create Product Audience

You build a Product Audience from signals through mobile apps and website. You can choose what events to use for building the audience. Facebook aggregates events for each Product ID.

You can create one Product Audience and later target ads based on events taken for an individual Product ID.

For standard app events, the audience will be aggregated under the Ads Pixel event names:

  • Search
    • iOS: FBSDKAppEventNameSearched
    • Android: EVENT_NAME_SEARCHED
  • ViewContent
    • iOS: FBSDKAppEventNameViewedContent
    • Android: EVENT_NAME_VIEWED_CONTENT
  • AddToCart
    • iOS: FBSDKAppEventNameAddedToCart
    • Android: EVENT_NAME_ADDED_TO_CART
  • Purchase
    • iOS: N/A
    • Android: EVENT_NAME_PURCHASED

Use these event names in your audience rules. For purchase events on iOS, Facebook aggregates an audience when your app makes a logPurchase call.

Create a Product Audience by making an HTTP POST call to:

https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/product_audiences

Specify the following parameters:

Field NameDescriptionTypeRequired

name

The name of the audience

string

Yes

description

A description of the audience

string

No

product_set_id

The Product Set to target with this audience

numeric string

Yes

inclusions

A set of events to target. At least one inclusion is required. Each inclusion should have exactly one event

JSON object

Yes

retention_seconds

The number of seconds to keep the person in the audience

int

Yes

rule

Website Custom Audience Rule referencing one event

object[]

Yes

exclusions

Events for which a person should be excluded from targeting. For exclusions, a person with these events will be excluded from targeting if the event has happened on any product in the same product group i.e products that have the same item_group_id in the product feed. E.g. Product audience is set to include ViewContent and exclude Purchase events. A person views product A and B and purchases product B. If product A and product B belong to the same product group then that person will be excluded from the product audience because A and B are just variants. If product A and B are not in the same product group, the person will continue to remain in the audience because he still has a ViewContent event for product A.

JSON object

No

retention_seconds

The number seconds to retain the exclusion

int

Yes if exclusion is specified

rule

Website Custom Audience Rule referencing one event

object[]

Yes if exclusion is specified

Please note that each rule must include event with operator eq either as a top-level rule or as part of a top-level and rule.

Please note that if the same event is used in both inclusions and exclusions, any additional parameter checks must be exactly the same.

For example, to target people that viewed or added products to a cart, but didn't purchase them, create the following audience:

use FacebookAds\Object\Fields\ProductAudienceFields;
use FacebookAds\Object\ProductAudience;

$product_audience = new ProductAudience(null, 'act_<AD_ACCOUNT_ID>');
$product_audience->setData(array(
  ProductAudienceFields::NAME => 'Product audience',
  ProductAudienceFields::PRODUCT_SET_ID => <PRODUCT_SET_ID>,
  ProductAudienceFields::INCLUSIONS => array(
    array(
      'retention_seconds' => 86400,
      'rule' => array(
        'event' => array('eq' => 'AddToCart'),
      ),
    ),
    array(
      'retention_seconds' => 72000,
      'rule' => array(
        'event' => array('eq' => 'ViewContent'),
      ),
    ),
  ),
  ProductAudienceFields::EXCLUSIONS => array(
    array(
      'retention_seconds' => 172800,
      'rule' => array(
        'event' => array('eq' => 'Purchase'),
      ),
    ),
  ),
));
$product_audience->create();
from facebookads.objects import ProductAudience

product_audience = ProductAudience(parent_id='act_<AD_ACCOUNT_ID>')
product_audience.update({
    ProductAudience.Field.name: 'Product Audience',
    ProductAudience.Field.product_set_id: <PRODUCT_SET_ID>,
    ProductAudience.Field.inclusions: [
        {
            'retention_seconds': 86400,
            'rule': {
                'event': {'eq': 'AddToCart'},
            },
        },
        {
            'retention_seconds': 72000,
            'rule': {
                'event': {'eq': 'ViewContent'},
            },
        },
    ],
    ProductAudience.Field.exclusions: [
        {
            'retention_seconds': 172800,
            'rule': {
                'event': {'eq': 'Purchase'},
            },
        },
    ],
})
product_audience.remote_create()
CustomAudience customAudience = new AdAccount(act_<AD_ACCOUNT_ID>, context).createProductAudience()
  .setName("Product audience")
  .setProductSetId(<PRODUCT_SET_ID>)
  .setInclusions("[{\"retention_seconds\":\"86400\",\"rule\":{\"event\":{\"eq\":\"AddToCart\"}}},{\"retention_seconds\":\"72000\",\"rule\":{\"event\":{\"eq\":\"ViewContent\"}}}]")
  .setExclusions("[{\"retention_seconds\":\"172800\",\"rule\":{\"event\":{\"eq\":\"Purchase\"}}}]")
  .execute();
curl \
  -F 'name=Product audience' \
  -F 'product_set_id=<PRODUCT_SET_ID>' \
  -F 'inclusions=[ 
    {"retention_seconds":86400,"rule":{"event":{"eq":"AddToCart"}}}, 
    {"retention_seconds":72000,"rule":{"event":{"eq":"ViewContent"}}} 
  ]' \
  -F 'exclusions=[{"retention_seconds":172800,"rule":{"event":{"eq":"Purchase"}}}]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/product_audiences

If you want target people that viewed a product on the web with iPhone, but haven't purchased on any device, create the following audience below.

This assumes that you include a userAgent parameter in your Facebook pixel:

use FacebookAds\Object\Fields\ProductAudienceFields;
use FacebookAds\Object\ProductAudience;

$product_audience = new ProductAudience(null, 'act_<AD_ACCOUNT_ID>');
$product_audience->setData(array(
  ProductAudienceFields::NAME => 'Product audience',
  ProductAudienceFields::PRODUCT_SET_ID => <PRODUCT_SET_ID>,
  ProductAudienceFields::INCLUSIONS => array(
    array(
      'retention_seconds' => 86400,
      'rule' => array(
        'and' => array(
          array(
            'event' => array('eq' => 'AddToCart'),
          ),
          array(
            'userAgent' => array('i_contains' => 'iPhone'),
          ),
        ),
      ),
    ),
  ),
  ProductAudienceFields::EXCLUSIONS => array(
    array(
      'retention_seconds' => 172800,
      'rule' => array(
        'event' => array('eq' => 'Purchase'),
      ),
    ),
  ),
));
$product_audience->create();
from facebookads.objects import ProductAudience

product_audience = ProductAudience(parent_id='act_<AD_ACCOUNT_ID>')
product_audience.update({
    ProductAudience.Field.name: 'Product Audience',
    ProductAudience.Field.product_set_id: <PRODUCT_SET_ID>,
    ProductAudience.Field.inclusions: [
        {
            'retention_seconds': 86400,
            'rule': {
                'and': [
                    {
                        'event': {'eq': 'AddToCart'},
                    },
                    {
                        'userAgent': {'i_contains': 'iPhone'},
                    },
                ],
            },
        },
    ],
    ProductAudience.Field.exclusions: [
        {
            'retention_seconds': 172800,
            'rule': {
                'event': {'eq': 'Purchase'},
            },
        },
    ],
})
product_audience.remote_create()
CustomAudience customAudience = new AdAccount(act_<AD_ACCOUNT_ID>, context).createProductAudience()
  .setName("Product audience")
  .setProductSetId(<PRODUCT_SET_ID>)
  .setInclusions("[{\"retention_seconds\":\"86400\",\"rule\":{\"and\":[{\"event\":{\"eq\":\"AddToCart\"}},{\"userAgent\":{\"i_contains\":\"iPhone\"}}]}}]")
  .setExclusions("[{\"retention_seconds\":\"172800\",\"rule\":{\"event\":{\"eq\":\"Purchase\"}}}]")
  .execute();
curl \
  -F 'name=Product audience' \
  -F 'product_set_id=<PRODUCT_SET_ID>' \
  -F 'inclusions=[ 
    { 
      "retention_seconds": 86400, 
      "rule": { 
        "and": [{"event":{"eq":"AddToCart"}},{"userAgent":{"i_contains":"iPhone"}}] 
      } 
    } 
  ]' \
  -F 'exclusions=[{"retention_seconds":172800,"rule":{"event":{"eq":"Purchase"}}}]' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/product_audiences

Retrieve Product Audiences

Once you create a product audience, you can retrieve it with Custom Audiences API with subtype as CLAIM. See Custom Audience Creating. You can get the original parameters used for audience creation with the data_source parameter.

Product audience is a specific type of Custom Audience that's dynamically generated from product events. The act_<AD_ACCOUNT_ID>/product_audiences endpoint is a special POST endpoint to construct these audiences.

Example to retrieve custom audience:

use FacebookAds\Object\AdAccount;
use FacebookAds\Object\Fields\CustomAudienceFields;

$account = new AdAccount('act_<AD_ACCOUNT_ID>');
$audiences = $account->getCustomAudiences(array(
  CustomAudienceFields::DATA_SOURCE,
  CustomAudienceFields::SUBTYPE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.customaudience import CustomAudience

ad_account = AdAccount('act_<AD_ACCOUNT_ID>')
custom_audiences = ad_account.get_custom_audiences(fields=[
    CustomAudience.Field.data_source,
    CustomAudience.Field.subtype,
])
APINodeList<CustomAudience> customAudiences = new AdAccount(act_<AD_ACCOUNT_ID>, context).getCustomAudiences()
  .requestField("data_source")
  .requestField("subtype")
  .execute();
curl -G \
  -d 'fields=data_source,subtype' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/customaudiences

Example to retrieve specific product audience:

use FacebookAds\Object\ProductAudience;

$product_audience = new ProductAudience(<PRODUCT_AUDIENCE_ID>);
$product_audience->read();
from facebookads.objects import ProductAudience

product_audience = ProductAudience(<PRODUCT_AUDIENCE_ID>)
product_audience.remote_read()
CustomAudience customAudience2 = new CustomAudience(<PRODUCT_AUDIENCE_ID>, context).get()
  .execute();
curl -G \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/<PRODUCT_AUDIENCE_ID>

Troubleshooting

The video below walks through common issues when setting up the pixel, app events, and catalog, and walks you through tools you can use to debug.

%FB(devsite:video { id: 1316864561761273, title: "Debugging Product catalog and signals" })