We recently announced the release of dynamic product ads, which change the way advertisers can promote products on Facebook. We are happy to announce that dynamic product ads are available to all users of the Marketing API, and are fully supported in our PHP and Python Marketing API SDKs.
Until now, effectively promoting your entire product catalog to drive conversions has been a difficult challenge. With the release of dynamic product ads, it is now possible to advertise your entire catalog of products on Facebook. You can do this across all devices and at large scale, using the latest ad units such as the Multi-Product Ad.
How does it work?
Let's walk through the process!
Your Product Catalog will contain data about the products you sell. This will include fields such title
, description
, availability
, and price
. The catalog can contain all of your products, of which you can choose specific Product Sets to advertise.
You can create and upload a Product Catalog through Business Manager or via the Marketing API. The full documentation for the feed format and APIs to create and upload it are here.
First, make your feed available on an HTTP or FTP server:
<?xml version="1.0"?> <rss xmlns:g="http://base.google.com/ns/1.0" version="2.0"> <channel> <title>Jasper's Market</title> <link>http://www.jaspers-market.com</link> <description>Jasper's Market Items</description> <item> <g:id>item_1</g:id> <g:title>Set of 5 White Ceramic White Bowls</g:title> <g:link>http://www.jaspers-market.com/item_1.html</g:link> ... <g:price>9.99 USD</g:price> </item> <item> <g:id>item_2</g:id> <g:title>White Ceramic Mortar and Pestle</g:title> <g:link>http://www.jaspers-market.com/item_2.html</g:link> ... <g:price>12.99 USD</g:price> </item> </channel> </rss>
Then, create a Product Catalog and upload your Feed. You can set up an upload schedule, or initiate the upload on demand:
use FacebookAds\Object\ProductCatalog;
use FacebookAds\Object\Fields\ProductCatalogFields;
use FacebookAds\Object\ProductFeed;
use FacebookAds\Object\Fields\ProductFeedFields;
use FacebookAds\Object\Fields\ProductFeedScheduleFields;
use FacebookAds\Object\ProductSet;
use FacebookAds\Object\Fields\ProductSetFields;
// Step 1: Create a Product Catalog
$catalog = new ProductCatalog(null, '<BUSINESS_ID>');
$catalog->setData(array(
ProductCatalogFields::NAME => 'My Catalog',
));
$catalog->save();
// Step 2: Schedule the Feed
$feed = new ProductFeed(null, $catalog->id);
$feed->setData(array(
ProductFeedFields::NAME => 'My Daily Feed',
ProductFeedFields::FILE_NAME => 'products.xml',
ProductFeedFields::SCHEDULE => array(
ProductFeedScheduleFields::INTERVAL => 'DAILY',
ProductFeedScheduleFields::URL =>
'http://www.jaspers-market.com/products.xml',
ProductFeedScheduleFields::HOUR => 22
)
));
$feed->save();
// Step 3: Create a Product Set (a set of products to advertise)
$product_set = new ProductSet(null, $catalog->id);
$product_set->setData(array(
ProductSetFields::NAME => 'All Products',
ProductSetFields::FILTER => array()
));
$product_set->save();
// Step 4: Associate the catalog with a Website Custom Audience Pixel
$catalog->setExternalEventSources(array('<PIXEL_ID>'));
When people interact with your products on your website, include the corresponding Product ID's from your catalog in those events. At a minimum, make sure to implement ViewContent
, AddToCart
and Purchase
events on your website. Below is an example event, and you can find the complete documentation here
window._fbq = window._fbq || []; window._fbq.push(['track', 'AddToCart', { content_ids: ['item_1'], content_type: 'product' }]);
After your pixel is sending product-specific events, you can create a Product Audience (full documentation here). For example, to reach people that have viewed a product but not yet purchased it:
use FacebookAds\Object\Fields\ProductAudienceFields;
use FacebookAds\Object\ProductAudience;
$audience = new ProductAudience(null, 'act_<ACCOUNT_ID>');
$audience->setData(array(
ProductAudienceFields::NAME => 'Product Audience',
ProductAudienceFields::PRODUCT_SET_ID => '<PRODUCT_SET_ID>',
ProductAudienceFields::PIXEL_ID => '<PIXEL_ID>',
ProductAudienceFields::INCLUSIONS => array(array(
ProductAudienceFields::RETENTION_SECONDS => 86400,
ProductAudienceFields::RULE => array(
'event'=>array('eq'=>'ViewContent')
)
)),
ProductAudienceFields::EXCLUSIONS => array(array(
ProductAudienceFields::RETENTION_SECONDS => 172800,
ProductAudienceFields::RULE => array(
'event' => array('eq'=>'Purchase')
)
))
));
$audience->save();
Product Audiences will start populating from the moment they are created. Make sure to check your Product Audience size to confirm that it is set up and populating correctly.
Dynamic product ads use the PRODUCT_CATALOG_SALES
objective. Create a new campaign and ad set using this objective:
New Fields in ad campaign and ad set: *
PROMOTED_OBJECT
for ad campaign which specifies a
product_catalog_id
product_set_id
specified in the ad set's
PROMOTED_OBJECT
DYNAMIC_AUDIENCE_IDS
in the
TargetingSpecs
use FacebookAds\Object\AdCampaign;
use FacebookAds\Object\Fields\AdCampaignFields;
use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdObjectives;
use FacebookAds\Object\Values\BidTypes;
use FacebookAds\Object\Fields\AdGroupBidInfoFields;
use FacebookAds\Object\TargetingSpecs;
use FacebookAds\Object\Fields\TargetingSpecsFields;
// Ad Campaign with the Product Catalog as the promoted object
$campaign = new AdCampaign(null, 'act_<ACCOUNT_ID>');
$campaign->setData(array(
AdCampaignFields::NAME => 'DPA Campaign',
AdCampaignFields::OBJECTIVE => AdObjectives::PRODUCT_CATALOG_SALES,
AdCampaignFields::PROMOTED_OBJECT =>
array('product_catalog_id' => '<PRODUCT_CATALOG_ID>')
));
$campaign->save();
// Targeting Spec using our Dynamic Audience
$targeting = new TargetingSpecs();
$targeting->{TargetingSpecsFields::GEO_LOCATIONS} =
array('countries' => array('US'));
$targeting->{TargetingSpecsFields::DYNAMIC_AUDIENCE_IDS} =
array('<DYNAMIC_AUDIENCE_ID>');
// Ad Set with a Product Set as promoted object
$adset = new AdSet(null, 'act_<ACCOUNT_ID>');
$adset->setData(array(
AdSetFields::NAME => 'DPA Ad Set',
AdSetFields::BID_TYPE => BidTypes::BID_TYPE_CPC,
AdSetFields::BID_INFO =>
array(AdGroupBidInfoFields::CLICKS => 150),
AdSetFields::DAILY_BUDGET => 2000,
AdSetFields::CAMPAIGN_GROUP_ID => $campaign->id,
AdSetFields::TARGETING => $targeting,
AdsetFields::PROMOTED_OBJECT =>
array('product_set_id' => '<PRODUCT_SET_ID>')
));
$adset->save();
use FacebookAds\Object\AdCreative;
use FacebookAds\Object\ObjectStory\TemplateData;
use FacebookAds\Object\ObjectStorySpec;
use FacebookAds\Object\Values\CallToActionTypes;
use FacebookAds\Object\Fields\ObjectStory\TemplateDataFields;
use FacebookAds\Object\Fields\AdCreativeFields;
use FacebookAds\Object\Fields\ObjectStorySpecFields;
use FacebookAds\Object\AdGroup;
use FacebookAds\Object\Fields\AdGroupFields;
use FacebookAds\Object\Values\AdObjectives;
// Creative template to be dynamically rendered with product data
$template = new TemplateData();
$template->setData(array(
TemplateDataFields::DESCRIPTION => '{{product.description}}',
TemplateDataFields::LINK => 'http://jaspers-market.com/',
TemplateDataFields::MESSAGE => 'Jasper\'s is more than just groceries. You can now find all of your cooking tools and utensils on our website',
TemplateDataFields::NAME => '{{product.name | titleize}}',
TemplateDataFields::MAX_PRODUCT_COUNT => 3, // enable Multi-Product Ads
TemplateDataFields::CALL_TO_ACTION => array(
'type' => CallToActionTypes::SHOP_NOW
)
));
$story = new ObjectStorySpec();
$story->setData(array(
ObjectStorySpecFields::PAGE_ID => '<PAGE_ID>',
ObjectStorySpecFields::TEMPLATE_DATA => $template,
));
// Ad creative is tied to a specific Product Set
$creative = new AdCreative(null, 'act_<ACCOUNT_ID>');
$creative->setData(array(
AdCreativeFields::NAME => 'DPA Creative 1',
AdCreativeFields::OBJECT_STORY_SPEC => $story,
AdCreativeFields::PRODUCT_SET_ID => '<PRODUCT_SET_ID>'
));
$creative->save();
// Ad Group using the PRODUCT_CATALOG_SALES objective
$adgroup = new AdGroup(null, 'act_<ACCOUNT_ID>');
$adgroup->setData(array(
AdGroupFields::NAME => 'DPA Ad 1',
AdGroupFields::CAMPAIGN_ID => '<AD_SET_ID>', // $adset->id from earlier
AdGroupFields::CREATIVE =>
array('creative_id' => $creative->id),
AdGroupFields::OBJECTIVE => AdObjectives::PRODUCT_CATALOG_SALES
));
$adgroup->save();
The above sample will create a templated ad:
After the setup above, your Dynamic Product Ad can run "Always On" and will automatically show the right product to the right person, according to your audience rules. The ad will always be rendered at the time of the impression with the latest data from your product feed. Below is an example of the above templated ad rendered with three of the sample products:
Once your dynamic product ads are running, you can learn how individual products are performing by calling Ad Report Stats with a breakdown by Product ID.
The complete set of documentation is available here. Enjoy!