Dynamic Creative

Automatically deliver different variations of an ad's creative. This helps you find the best ad creative combination per impression by taking your ad's images, titles, descriptions, and other assets, then learning from outcomes of how these combinations perform across audiences.

Build and display the best creatives for groups of people in your broader target audience. This improves your ability to efficiently explore numerous creative combinations and audiences. Dynamic Creative can improve ads ROI by:

  • Automating workflow used to test creative
  • Choosing the effective combination of creative assets through learning across audiences

Dynamic creative supports the following Campaign Objectives:

High-Level Steps

To use this API:

  1. Create an ad campaign.
  2. Create an ad set with dynamic_creative set to true.
  3. Provide ad creative and specify an asset_feed_spec. The asset_feed_spec refers to all the different creative assets you will deliver via dynamic creative.
  4. Reference the ad creative ID in your ad.

Create a Campaign

Create a Dynamic Creative ad campaign which at the same endpoint you use to create a standard campaign. Dynamic Creative supports seven different objectives:

  • objective — Must be either CONVERSIONS, APP_INSTALLS, LINK_CLICKS, BRAND_AWARENESS, LEAD_GENERATION, REACH, or VIDEO_VIEWS.
  • buying_type — Must be the default, which is AUCTION, or left blank.

For example, to create an ad campaign with the objective of CONVERSIONS:

curl 
-F "name=Dynamic Creative Sample Campaign"
-F "objective=CONVERSIONS"
-F "access_token=ACCESS_TOKEN" 
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/campaigns    

On success, you get a new campaign ID:

{"id":"23842500259110001"}

Create an Ad Set

Create an ad set for Dynamic Creative at the same endpoint you use to create a standard ad set. You can use all optimization_goals, billing_events, targeting, and promoted_objects which work with the parent ad campaign's objective as you would with a standard ad set. For more information see Validation

To enable Dynamic Creative, you should set is_dynamic_creative to true. For example, to create an ad set in a campaign with the optimization_goal set to conversions:

curl -X POST \
  -F 'name=Dynamic Creative Ad Set' \
  -F 'campaign_id=<AD_CAMPAIGN_ID>' \
  -F 'optimization_goal=OFFSITE_CONVERSIONS' \
  -F 'is_dynamic_creative=true' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'is_autobid=true' \
  -F 'promoted_object={"pixel_id":"<PIXEL_ID>","custom_event_type":"PURCHASE"}' \
  -F 'lifetime_budget=500000' \
  -F 'start_time=2018-08-15T14:49:42-0700' \
  -F 'end_time=2018-08-22T14:49:42-0700' \
  -F 'targeting={"geo_locations":{"countries":["US"]},"publisher_platforms":["facebook","audience_network"],"custom_audiences":[{"id":"<CUSTOM_AUDIENCE_ID>"}]}' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/API_VERSION/act_<AD_ACCOUNT_ID>/adsets

This returns a new ad set ID:

{"id":"23842500259260001"}

Note that if you are using Dynamic Creative with an ad set optimized for APP_INSTALLS, you should specify link_url in asset_feed_spec, such as http://www.abc.com, and link_url should be the same as object_store_url in promoted_object. You should provide only one link_url parameter in asset_feed_spec. For example:

curl 
-F "name=Dynamic Creative AdSet"
-F "campaign_id=CAMPAIGN_ID"
-F "optimization_goal=APP_INSTALLS"
-F 'is_dynamic_creative=true'
-F "billing_event=IMPRESSIONS"
-F "is_autobid=true"
-F "promoted_object={'object_store_url':'https://itunes.apple.com/us/app/facebook/id284882215','application_id':ADVERTISED_APP_ID}"  // object_store_url must match what is provided in asset feed's link_urls 
-F "lifetime_budget=20000"
-F "end_time=1461974400"
-F "targeting={
     'geo_locations':{'countries':['US']},
     'age_min':18,
     'age_max':24,
     'publisher_platforms':['facebook', 'audience_network'],
     'user_os':['ios']
   }"
-F "access_token=ACCESS_TOKEN" 
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adsets

Or for instance, create an ad set optimized for LINK_CLICKS:

curl 
-F "name=Dynamic Creative Ad Set"
-F "campaign_id=CAMPAIGN_ID"
-F "optimization_goal=LINK_CLICKS"
-F 'is_dynamic_creative=true'
-F "billing_event=IMPRESSIONS"
-F "is_autobid=true"
-F "lifetime_budget=500000"
-F "end_time=1461974400"
-F "targeting={
     'geo_locations':{'countries':['US']},
     'publisher_platforms':['facebook', 'audience_network', 'instagram']
   }"
-F "tracking_specs=[
    {
      'action.type': [
        'offsite_conversion'
      ],
      'fb_pixel': [
        'PIXEL_ID'
      ]
    }
]"
-F "access_token=ACCESS_TOKEN" 
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adsets

Provide Ad Creative

When you provide your ad creative, specify asset_feed_spec, page_id, and instagram_actor_id if applicable. With asset_feed_spec, you can specify multiple assets per type in the ad creative.

asset_feed_id is only supported in Marketing API v3.1 and earlier. You should use asset_feed_spec instead.

For example, provide ad creative with asset_feed_spec:

curl -X POST \ -F 'name="Dynamic Ad Creative with Asset Feed Spec Sample"' \ -F 'object_story_spec={ "page_id": "<PAGE_ID>" }' \ -F 'asset_feed_spec={ "images": [ { "hash": "<IMAGE_HASH>" } ], "bodies": [ { "text": "Begin Your Adventure" }, { "text": "Once a Trainer, always a Trainer." } ], "titles": [ { "text": "Level Up" }, { "text": "Swipe to evolve" } ], "descriptions": [ { "text": "First Dynamic Ad Creative Sample" } ], "ad_formats": [ "SINGLE_IMAGE" ], "call_to_action_types": [ "SHOP_NOW" ], "link_urls": [ { "website_url": "https://www.example.com/" } ], "videos": [] }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.2/act_<AD_ACCOUNT_ID>/adcreatives
const adsSdk = require('facebook-nodejs-ads-sdk'); const AdAccount = adsSdk.AdAccount; const AdCreative = adsSdk.AdCreative; 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' : 'Dynamic Ad Creative with Asset Feed Spec Sample', 'object_story_spec' : {'page_id':'<pageID>'}, 'asset_feed_spec' : {'images':[{'hash':'<imageHash>'}],'bodies':[{'text':'Begin Your Adventure'},{'text':'Once a Trainer, always a Trainer.'}],'titles':[{'text':'Level Up'},{'text':'Swipe to evolve'}],'descriptions':[{'text':'First Dynamic Ad Creative Sample'}],'ad_formats':['SINGLE_IMAGE'],'call_to_action_types':['SHOP_NOW'],'link_urls':[{'website_url':'https://www.example.com/'}],'videos':[]}, }; let adcreatives = (new AdAccount(id)).createAdCreative( fields, params ); logApiCallResult('adcreatives api call complete.', adcreatives);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\AdCreative; 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' => 'Dynamic Ad Creative with Asset Feed Spec Sample', 'object_story_spec' => array('page_id' => '<pageID>'), 'asset_feed_spec' => array('images' => array(array('hash' => '<imageHash>')),'bodies' => array(array('text' => 'Begin Your Adventure'),array('text' => 'Once a Trainer, always a Trainer.')),'titles' => array(array('text' => 'Level Up'),array('text' => 'Swipe to evolve')),'descriptions' => array(array('text' => 'First Dynamic Ad Creative Sample')),'ad_formats' => array('SINGLE_IMAGE'),'call_to_action_types' => array('SHOP_NOW'),'link_urls' => array(array('website_url' => 'https://www.example.com/')),'videos' => array()), ); echo json_encode((new AdAccount($id))->createAdCreative( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebookads.adobjects.adaccount import AdAccount from facebookads.adobjects.adcreative import AdCreative 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': 'Dynamic Ad Creative with Asset Feed Spec Sample', 'object_story_spec': {'page_id':'<pageID>'}, 'asset_feed_spec': {'images':[{'hash':'<imageHash>'}],'bodies':[{'text':'Begin Your Adventure'},{'text':'Once a Trainer, always a Trainer.'}],'titles':[{'text':'Level Up'},{'text':'Swipe to evolve'}],'descriptions':[{'text':'First Dynamic Ad Creative Sample'}],'ad_formats':['SINGLE_IMAGE'],'call_to_action_types':['SHOP_NOW'],'link_urls':[{'website_url':'https://www.example.com/'}],'videos':[]}, } print AdAccount(id).create_ad_creative( 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 AdAccount(id, context).createAdCreative() .setName(\"Dynamic Ad Creative with Asset Feed Spec Sample\") .setObjectStorySpec( new AdCreativeObjectStorySpec() .setFieldPageId(\"<pageID>\") ) .setParam(\"asset_feed_spec\", \"{\\"images\\":[{\\"hash\\":\\"<imageHash>\\"}],\\"bodies\\":[{\\"text\\":\\"Begin Your Adventure\\"},{\\"text\\":\\"Once a Trainer, always a Trainer.\\"}],\\"titles\\":[{\\"text\\":\\"Level Up\\"},{\\"text\\":\\"Swipe to evolve\\"}],\\"descriptions\\":[{\\"text\\":\\"First Dynamic Ad Creative Sample\\"}],\\"ad_formats\\":[\\"SINGLE_IMAGE\\"],\\"call_to_action_types\\":[\\"SHOP_NOW\\"],\\"link_urls\\":[{\\"website_url\\":\\"https://www.example.com/\\"}],\\"videos\\":[]}\") .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 ad_account = FacebookAds::AdAccount.get(id) adcreatives = ad_account.adcreatives.create({ name: 'Dynamic Ad Creative with Asset Feed Spec Sample', object_story_spec: {'page_id':'<pageID>'}, asset_feed_spec: {'images':[{'hash':'<imageHash>'}],'bodies':[{'text':'Begin Your Adventure'},{'text':'Once a Trainer, always a Trainer.'}],'titles':[{'text':'Level Up'},{'text':'Swipe to evolve'}],'descriptions':[{'text':'First Dynamic Ad Creative Sample'}],'ad_formats':['SINGLE_IMAGE'],'call_to_action_types':['SHOP_NOW'],'link_urls':[{'website_url':'https://www.example.com/'}],'videos':[]}, })

To verify this, read asset_feed_spec from the ad creative:

curl -X GET \ -d 'fields="asset_feed_spec"' \ -d 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v3.2/<CREATIVE_ID>/
'use strict'; const bizSdk = require('facebook-nodejs-business-sdk'); const AdCreative = bizSdk.AdCreative; const access_token = '<ACCESS_TOKEN>'; const app_secret = '<APP_SECRET>'; const app_id = '<APP_ID>'; const id = '<ID>'; const api = bizSdk.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 = [ 'asset_feed_spec', ]; params = { }; const sample_code = (new AdCreative(id)).get( fields, params ); logApiCallResult('sample_code api call complete.', sample_code);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdCreative; 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( 'asset_feed_spec', ); $params = array( ); echo json_encode((new AdCreative($id))->getSelf( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebook_business.adobjects.adcreative import AdCreative from facebook_business.api import FacebookAdsApi access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<ID>' FacebookAdsApi.init(access_token=access_token) fields = [ 'asset_feed_spec', ] params = { } print AdCreative(id).get( 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 AdCreative(id, context).get() .requestAssetFeedSpecField() .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 ad_creative = FacebookAds::AdCreative.get(id ,'asset_feed_spec')

Available Options for asset_feed_spec

You can use the following parameters to represent creative assets that display in your Dynamic Creative ad. Facebook explores combinations of these assets across eligible ad formats and optimizes delivery of the best combination and best format for each viewer. See also Reference, Asset Feed Spec.

The API for using multiple link_urls is under limited availability. Please contact your Facebook Representative to access it.

Property Name Description Type Required

images

Array of eligible images. Images provided in this array should be included in the ad account's image library

array of list of {"url": "{IMAGE_URL}", "hash": "{IMAGE_HASH}", "url_tags": "{TAG}"}
where either url or hash is required

Required for SINGLE_IMAGE and CAROUSEL_IMAGE format

videos

Array of video_ids. video_ids provided in this array should belong to the ad account

array of list of {"video_id": "{VIDEO_ID}", "thumbnail_url": "{THUMBNAIL_URL}", "url_tags": "{TAG}"}

Required for SINGLE_VIDEO format

bodies

Array of bodies. The primary message or copy of the ad.

array of list of {"text": "{BODY_TEXT}", "url_tags": "{TAG}"}

No

call_to_action_types

Array of call-to-action-type values

array of list of {"{CALL_TO_ACTION}"}. You can provide multiple values up to 5 values.

Required for all objectives except REACH and BRAND AWARENESS

titles

Array of titles. A short headline in the ad, generally shown next to a link, image or video.

array of list of {"text": "{TITLE}", "url_tags": "{TAG}"}

No

descriptions

Array of secondary description text, displayed less prominently than bodies or titles. Generally appears next to a link, image or video. If not specified, Facebook scrapes the link you provide to generate a description just as we do for link ads. Use empty string with single space for blank description if you do not want to use the scraped text.

array of list of {"text": "{DESCRIPTION}", "url_tags": "{TAG}"}

No

link_urls

Array of link URLs

array of list of {"website_url": "{URL}"}

Required. Typically you can provide only one URL. Those with access to the API enabling multiple link_urls can use up to five.

ad_formats

Array of Facebook ad formats we should create the ads in. Supported formats are: SINGLE_IMAGE, CAROUSEL_IMAGE, SINGLE_VIDEO

array of strings ["{AD_FORMAT}"]

Yes

asset_feed_spec Restrictions

Ad Formats

  • Three ad_formats are supported: SINGLE_IMAGE, CAROUSEL_IMAGE, and SINGLE_VIDEO.
  • Only one ad_format is allowed in one asset feed.
  • ad_format counts as one asset in an asset feed.

Number of Assets:

  • Maximum of 30 total assets. 10 images + 5 bodies + 5 titles + 5 descriptions + 1 ad_format + 1 link_url + 1 call_to_action_types = 28 assets
  • Total number of images: < 10
  • Total number of videos: < 10. If you use Instagram as your placement, only square videos or landscape videos allowed.
  • Total number of bodies: <5
  • Total number of call-to-actions: < 5
  • Total number of titles: < 5
  • Total number of links: < 1. Those with access to the API which enables multiple link_urls can use up to five. This API is under limited availability. Contact your Facebook representative for access
  • Total number of descriptions: <5.

Image requirements:

  • Recommended image specs: 1.9:1
  • Recommended image size: 1,200 x 628 pixels
  • For CAROUSEL_IMAGE format, you must provide at least 2 images.
  • If you use Instagram as your placement, you should use square images for better performance

Text requirements:

  • Title and description text maximum length of 255 characters.
  • Body text maximum length of 1024 characters.
  • If you do not specify any description, we scrape the link you provide to retrieve a description as we do for standard link ads
  • For CAROUSEL_IMAGE, titles are optional.

url_tags are optional and only available for IMAGES, VIDEOS, BODIES, DESCRIPTIONS, and TITLES. Facebook appends url_tags to the link URL as parameters for each asset in an ad.

deeplink_url is also optional. If you do use deeplinks, you can only provide one deeplink_url per asset_feed_spec.

For example, a valid asset feed combination setup for SINGLE_IMAGE format is:

  • 5 images
  • 3 bodies
  • 3 titles
  • 3 descriptions
  • 1 format: SINGLE_IMAGE
  • 2 links, for those with access to the API enabling multiple link_urls
"link_urls=[{'website_url':'WEBSITE_URL'}, {'website_url':'WEBSITE_URL'}]" 

Examples

Provide ad creative using an asset_feed_spec with two alternate images, bodies, and titles:

curl 
-F 'object_story_spec={
       "page_id": "YOUR_PAGE_ID"
       "instagram_actor_id" : "INSTAGRAM_ACTOR_ID",
    }' 
-F "asset_feed_spec={'images': [{'hash':'785095162a2034666e0d0cc4ea1faf89'}, {'hash':'3a24122c13923569599be35567ce4e9e'}], 'bodies': [{'text':'Begin Your Adventure'}, {'text':'Once a Trainer, always a Trainer.'}], 'titles': [{'text':'Level Up'}, {'text':'Swipe to evolve'}], 'descriptions': [{'text':'Begin Your Adventure'}], 'ad_formats': ['SINGLE_IMAGE'], 'link_urls': [{'website_url':'<WEBSITE_URL>'}]}"
-F 'access_token=<ACCESS_TOKEN>'  
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adcreatives

To verify you can read asset_feed_spec from the ad creative:

curl -G 
-d "access_token=ACCESS_TOKEN"
-d "fields=asset_feed_spec" 
https://graph.facebook.com/API_VERSION/AD_CREATIVE_ID

The response looks like this:

{  
   "asset_feed_spec":{  
      "images":[  
         {  
            "url_tags":"image=image1",
            "hash":"785095162a2034666e0d0cc4ea1faf89"
         },
         {  
            "url_tags":"image=image2",
            "hash":"3a24122c13923569599be35567ce4e9e"
         }
      ],
      "bodies":[  
         {  
            "text":"Begin Your Adventure"
         },
         {  
            "text":"Once a Trainer, always a Trainer."
         }
      ],
      "call_to_action_types":[  
         "LEARN_MORE"
      ],
      "call_to_actions":[  
         {  
            "type":"LEARN_MORE"
         }
      ],
      "descriptions":[  
         {  
            "text":"Begin Your Adventure"
         }
      ],
      "link_urls":[  
         {  
            "website_url":"<WEBSITE_URL>"
         }
      ],
      "titles":[  
         {  
            "text":"Swipe to evolve"
         },
         {  
            "text":"Level Up"
         }
      ],
      "ad_formats":[  
         "SINGLE_IMAGE"
      ],
      "optimization_type":"REGULAR"
   },
   "id":"<AD_CREATIVE_ID>",
}

Or for example, create asset_feed_spec with two alternate videos, bodies, and titles:

curl 
-F 'object_story_spec={
       "page_id": "YOUR_PAGE_ID"
       "instagram_actor_id" : "INSTAGRAM_ACTOR_ID",
    }' 
-F "asset_feed_spec={'videos': [{'video_id':'2053108854721025', 'thumbnail_url':'<thumnail_url>', 'url_tags':'video=video1'},{'video_id':'2104406249780616', 'thumbnail_url':'<thumnail_url>','url_tags':'video=video2'}], 'bodies': [{'text':'Begin Your Adventure'}, {'text':'Once a Trainer, always a Trainer.'}], 'titles': [{'text':'Level Up'}, {'text':'Swipe to evolve'}], 'descriptions': [{'text':'Begin Your Adventure'}], 'ad_formats': ['SINGLE_IMAGE'], 'link_urls': [{'website_url':'<WEBSITE_URL>'}]}"
-F 'access_token=<ACCESS_TOKEN>'  
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adcreatives

To verify you can use the asset_feed_spec, read it:

curl -G 
-d "access_token=ACCESS_TOKEN"
-d "fields=asset_feed_spec" 
https://graph.facebook.com/API_VERSION/AD_CREATIVE_ID

The response contains:

{  
   "asset_feed_spec":{  
      "videos":[  
         {  
            "url_tags":"video=video1",
            "video_id":"2053108854721025",
            "thumbnail_url":"<thumnail_url>",
            "thumbnail_hash":"<thumnail_hash>"
         },
         {  
            "url_tags":"video=video2",
            "video_id":"2104406249780616",
            "thumbnail_url":"<thumnail_url>",
            "thumbnail_hash":"<thumnail_hash>"
         }
      ],
      "bodies":[  
         {  
            "text":"Begin Your Adventure"
         },
         {  
            "text":"Once a Trainer, always a Trainer."
         }
      ],
      "call_to_action_types":[  
         "LEARN_MORE"
      ],
      "call_to_actions":[  
         {  
            "type":"LEARN_MORE"
         }
      ],
      "descriptions":[  
         {  
            "text":"Begin Your Adventure"
         }
      ],
      "link_urls":[  
         {  
            "website_url":"<WEBSITE_URL>"
         }
      ],
      "titles":[  
         {  
            "text":"Swipe to evolve"
         },
         {  
            "text":"Level Up"
         }
      ],
      "ad_formats":[  
         "SINGLE_VIDEO"
      ],
      "optimization_type":"REGULAR"
   },
   "id":"<AD_CREATIVE_ID>",
}

Use Deep Links

You can use deeplinks in Dynamic Creative with the APP_INSTALLS, CONVERSIONS and LINK_CLICKS objectives. Add deeplink_url in link_urls when you create your asset_feed_spec. You must only specify one deeplink_url in asset_feed_spec.

curl 
-F 'object_story_spec={
       "page_id": "YOUR_PAGE_ID"
       "instagram_actor_id" : "INSTAGRAM_ACTOR_ID",
    }' 
-F "asset_feed_spec={'images': [{'hash':'image_hash'}], 'bodies': [{'text':'Body 1'}, {'text':'Body 2'}], 'titles': [{'text':'Title 1'}, {'text':'Title 2'}], 'descriptions': [{'text':' '}], 'ad_formats': ['SINGLE_IMAGE'], 'link_urls': [{'website_url':'App's object store URL','deeplink_url':'deeplink URL'}]}"
-F 'access_token=<ACCESS_TOKEN>'  
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adcreatives

Edit Ad Creative

You can edit the ad creative to add, replace, or remove any of the assets. To do so, provide a new creative with your new asset feed spec, and we deliver the new assets. Then for the same type of asset in asset_feed_spec, such as image hashes, we report how the assets perform as original ones.

When you create a new ad creative to replace an old one, you must still fulfill all restrictions which apply.

curl 
  -F 'access_token=ACCESS_TOKEN' 
  -F 'creative={
      "creative_id": CREATIVE_ID,
   }' 
https://graph.facebook.com/VERSION/AD_ID

On success, you get the following response:

{"success": true}

When you create your Dynamic Creative ad, the ad set must be empty, and you can only create one ad. You can however create additional Dynamic Creative ads in another, new ad set. Once you create an ad for Dynamic Creative, you cannot delete or archive it. Instead, you should delete or archive the parent ad set.

curl 
  -F 'name=Dynamic Creative Ad' 
  -F 'adset_id=ADSET_ID' 
  -F 'access_token=<ACCESS_TOKEN>' 
  -F 'creative={
      "creative_id": CREATIVE_ID,
   }' 
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/ads

On success:

Check Review Status

After you create your campaign, ad set, and ad, check your ad review status:

curl -G 
-d "access_token=ACCESS_TOKEN" 
-d 'fields=review_feedback' 
https://graph.facebook.com/API_VERSION/ADSET_ID

The result includes Dynamic Creative ad review feedback:

{
  "review_feedback":"[]",
  "id":"ADSET_ID"
}

An empty array means your ad passed review and displays when your ad set reaches its start date. Otherwise, if one of your creative assets does not meet review, you see:

{
  "review_feedback": {
    {"id":23842500258220001,"text":"Body 1","reason":["ALCOHOL"]},
    {"id":23842500258160001,"text":"Title 1","reason":["ALCOHOL"]},
    {"id":23842500258170001,"text":"Title 2","reason":["ALCOHOL"]}
  }",
  "id": "AD_ID"  
}

Insights

You can read Insights for Dynamic Creative ad set and related ad objects. In Ads Manager, you can view your asset level breakdowns. Using the API, you can get the following breakdowns:

  • body_asset
  • description_asset
  • image_asset
  • title_asset
  • call_to_action_asset
  • link_url_asset

You can combine these breakdowns in your results with these breakdowns:

  • age
  • gender
  • age, gender

Get the following fields in your query:

Field Description

actions

Number of actions taken on your ad, grouped by action type.

clicks

Total number of clicks on your ad.

impressions

Number of times your ad was served.

Facebook supports different values derived from the fields above. For example you can also retrieve ctr, actions_per_impressions, and so on.

For example, to retrieve insights for a Dynamic Creative ad with the body_asset breakdown:

curl -G 
-d "breakdowns=body_asset" 
-d "fields=impressions" 
-d "access_token=ACCESS_TOKEN" 
https://graph.facebook.com/API_VERSION/AD_ID/insights

A sample response looks like this:

{
  "data": [
    {
      "impressions": "8801",
      "date_start": "2016-04-29",
      "date_stop": "2016-05-13",
      "body_asset": {
        "text": "Test text",
        "id": "6051732675652"
      }
    },
    {
      "impressions": "7558",
      "date_start": "2016-04-29",
      "date_stop": "2016-05-13",
      "body_asset": {
        "text": "Test ext new",
        "id": "6051732676452"
      }
    },
  ],
  "paging": {
    "cursors": {
      "before": "MAZDZD",
      "after": "MgZDZD"
    }
  }}

To retrieve insights for a Dynamic Creative ad set broken down by image_asset and age:

curl -G 
-d "breakdowns=image_asset,age" 
-d "fields=impressions" 
-d "access_token=ACCESS_TOKEN" 
https://graph.facebook.com/API_VERSION/ADSET_ID/insights

A sample response from this call looks like this:

{
  "data": [
    {
      "impressions": "5497",
      "date_start": "2016-04-29",
      "date_stop": "2016-05-13",
      "image_asset": {
        "hash": "<REDACTED>",
        "url": "<REDACTED>",
        "id": "6051732672052"
      }
    },
    {
      "impressions": "5962",
      "date_start": "2016-04-29",
      "date_stop": "2016-05-13",
      "image_asset": {
        "hash": "<REDACTED>",
        "url": "<REDACTED>",
        "id": "6051732672652"
      }
    },
  ],
  "paging": {
    "cursors": {
      "before": "MAZDZD",
      "after": "MwZDZD"
    }

Customize Assets

You can customize the images, videos, text, or body delivered by Facebook for different groups of people. This gives you the benefits of broad targeting, such as cost efficiency, delivery at scale, fewer delivery issues, and ease of setup, yet still deliver more personalized ad creatives.

Customize Based on Placement

Customize and deliver creative assets for different placements with one ad. You can take advantage of placement optimization yet also provide different media for different placements. Follow the same steps as you do with any Dynamic Creative ad, see High-Level Steps.

When you create your asset_feed_spec, provide rules as described below.

Asset Rules

Create an asset_feed_spec with rules for custom assets by specifying asset_customization_rules. You can provide asset customization rules for an asset feed. For each rule, you need to specify the customization_spec and the asset labels. You should provide conditions in customization_spec for a single rule.

Property Name Description Type Required

customization_spec

Assets in the rule display in these placements.

See table below for allowed fields.

Required.

image_label

Label attached the image assets in asset_feed_spec which displays.

{"name": "{LABEL_NAME}"}`

Required for SINGLE_IMAGE format.

video_label

Label attached the video assets in asset_feed_spec which displays.

{"name": "{LABEL_NAME}"}`

Required for SINGLE_VIDEO format.

Fields allowed in customization_spec:

Property Name Options Required

publisher_platforms

facebook, instagram, audience_network

Required.

facebook_positions

feed

Not required.

instagram_positions

stream, story

Not required.

audience_network_positions

classic

Not required.

device_platforms

mobile, desktop

Not required.

For example:

curl 
  -F 'object_story_spec={
       "page_id": "PAGE-ID",
       "instagram_actor_id": "INSTAGRAM-ID",
     }' 
  -F 'asset_feed_spec={
    "videos": [
      {
        "adlabels": [
          {
            "name": "labelfb",
          }
        ],
        "video_id": "10154618295707554"
      },
      {
        "adlabels": [
          {
            "name": "labelig",
          }
        ],
        "video_id": "10154618298562554"
      }
    ],
    "bodies": [
      {
        "text": "Begin Your Adventure"
      }
    ],
    "link_urls": [
      {
        "website_url": "WEBSITE_URL",
        "display_url": "DISPLAY_URL"
      }
    ],
    "titles": [
      {
        "text": "Level Up"
      }
    ],
    "ad_formats": [
      "SINGLE_VIDEO"
    ],
    "call_to_action_types": [
      "WATCH_MORE"
    ],
    "descriptions": [
      {
        "text": ""
      }
    ],
    "asset_customization_rules": [
      {
        "customization_spec": {          
          "publisher_platforms": [
            "facebook"
          ],          
          "facebook_positions": [
            "feed",
            "instream_video"
          ]
        },
        "video_label": {
          "name": "labelfb",
        }
      },
      {
        "customization_spec": {          
          "publisher_platforms": [
            "instagram"
          ],          
          "instagram_positions": [
            "stream"           
          ]
        },
        "video_label": {
          "name": "labelig",
        }
      }
    ]
  }' 
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adcreatives

To verify this, read asset_feed_spec from ad creative:

curl -G 
-d "access_token=ACCESS_TOKEN"
-d "fields=asset_feed_spec" 
https://graph.facebook.com/API_VERSION/AD_CREATIVE_ID

Asset Customizations

Beyound customization based on ad placements, you can also customize assets based on other targeting types in a single ad.

Asset Customization API is currently in beta. Please contact your Facebook Representative for access.

Provide different creatives at the ad set level for each unique audience. Specify rules to define each of these audiences and their associated creative. The supported customization types, based on usefulness are:

The format you should use to specify a rule is similar to the format for core targeting, see Targeting.

Rule Priority

When you set up rules, you can specify a priority for each rule. If you do not set a priority for each rule, we give each rule a priority number based on its position in the rules as provided. For example, the first rule on the list is assigned 1 and the last one gets priority number equal to the total number of rules.

Default Rule

Individual rules combined typically result in targeting at the ad set level which avoids delivering a random combination of assets to people who do not match any rules.

However, to actively prevent this scenario, you should also set up a default rule. We evaluate each rule in the ascending order of priority assigned to match a given user. To set up a default:

  • Create an empty customization_spec, with only opening and closing curly braces at the end of your rules, {}.
  • Assign this rule the lowest priority, which is the highest number, such as 101 if you already have 100 rules.

The default rule matches a creative asset to people who do not satisfy any preceding rules. This enables Facebook to deliver a sufficient number of your Dynamic Creative ads.

In general, you should set up rules so that a high percentage of your targeted audience also matches your non-default rules.

To run Dynamic Creative ads with asset customization rules:

  • Follow the same steps you do for all other Dynamic Creative ads, see High-Level Steps.
  • Create your feed with customization rules as described below.

Create asset_feed_spec with Customization Rules

Create an asset_feed_spec with asset customization rules by specifying asset_customization_rules fields in API spec. You can provide up to 50 multiple asset customization rules. For each rule, you need to specify the customization_spec, priority and the asset labels. You should provide no more than 50 conditions in customization_spec for a single rule.

curl
-F 'object_story_spec={
       "page_id": "YOUR_PAGE_ID"
       "instagram_actor_id" : "INSTAGRAM_ACTOR_ID",
    }'
-F "asset_feed_spec={
 'images': [
   {'hash':'e112c41fe807944dea195220e975f766', 'adlabels':[{'name':'image1'}]}, 
   {'hash':'7df15c5f50ec5d90b3094c5eab3fcc16', 'adlabels':[{'name':'image2'}]}, 
   {'hash':'785095162a2034666e0d0cc4ea1faf89', 'adlabels':[{'name':'image3'}]}
 ], 
 'bodies': [
   {'text':'Motor City Mission Corps', 'adlabels':[{'name':'body1'}]}
 ], 
 'titles': [
   {'text':'Link title 1 goes here', <b>'adlabels':[{'name':'title1'}]}, 
   {'text':'Link title 2 goes here', <b>'adlabels':[{'name':'title2'}]</b>},
   {'text':'Link title 3 goes here', <b>'adlabels':[{'name':'title3'}]</b>},
 ], 
 'call_to_action_types':[
   'LEARN_MORE'
 ],
 'descriptions': [
   {'text':'Begin Your Adventure'}
 ], 
 'ad_formats': [
   'SINGLE_IMAGE'
 ], 
 'link_urls': [
   {'website_url':'https://www.yourwebsite.com/'}
 ],
 'asset_cuatomization_rules': [
  { 
     'customization_spec': {
         'age_min': 18,
         'age_max': 24
     },
    'image_label': {'name': 'image1'},
    'title_label': {'name': 'title1'},
    'priority': 1
  },
  {
     'customization_spec': {
        'age_min': 25,
        'age_max': 34
     }, 
     'image_label': {'name': 'image2'},
     'title_label': {'name': 'title2'},
     'priority': 2
  },
  {
     'customization_spec': {
         'publisher_platforms': ['facebook']
     }, 
     'image_label': {'name': 'image3'},
     'title_label': {'name': 'title3'},
     'priority': 3
  },
  {
     'customization_spec': {}, 
     'image_label': {'name':'image4'},
     'title_label': {'name':'title4'},
     'priority': 4
  }]}"
-F 'access_token=<ACCESS_TOKEN>'  
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adcreatives

Then create an ad with the ad creative.

curl \
-F "name=Asset Customization Rules Test" \
-F "adset_id=XXXXXXXXX" \
-F "creative={\"creative_id\":\"&lt;Adcreative ID from above&gt;\"}" \
-F "access_token=XXXXXXXXX" \
https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/ads

Create an ad with the ad creative.

curl \
-F "name=Asset Customization Rules Test" \
-F "adset_id=XXXXXXXXX" \
-F "creative={\"creative_id\":\"&lt;Adcreative ID from above&gt;\"}" \
-F "access_token=XXXXXXXXX" \
https://graph.facebook.com/v2.11/act_1516221108450274/ads

Restrictions

ObjectivesBRAND_AWARENESS, REACH, LINK_CLICKS, APP_INSTALLS, CONVERSIONS, and VIDEO_VIEWS. For LINK_CLICKS and CONVERSIONS, app engagement is unsupported.

Placements — Facebook Feed; Instagram Feed; Instagram Story; Audience Network Native, Banner and Interstitial; Audience Network Rewarded Video; Audience Network In-stream Video.

Buying typeReach and frequency or AUCTION.

asset_feed_spec restrictions - Are the same as those for Dynamic Creative ads without customization rules, except for the following:

  • Each image or video must have a label attached.
  • Only one image or video should be eligible for display per individual asset_customization_rule.
  • Ad Formats — Two ad_formats are supported: SINGLE_IMAGE and SINGLE_VIDEO. Only one ad_format is allowed in one asset feed.
  • You can only provide one item in call_to_actions_types.
  • For each placement setting in an ad set's targeting, you should provide at least one asset_customization_rule for it.

Troubleshooting

The following scenario can cause issues with Dynamic Creative ads:

Creating a Dynamic Creative with 10% budget and compare with baseline. Instead you should try to compare click-through-rates and cost-per-actions. This can occur because:

  • Budget needs to be equal between the two ad sets.
  • Both campaigns need similar number of delivered impressions for comparison.

FAQs

Q: Is ads delivery optimization different for Dynamic Creative ads and standard ads? If we adjusted image and title ourselves and created regular ads with possible combinations, would the outcome be any different?

A: Yes, the optimization is different between Dynamic Creative and the ads in our current system. If you create various image-title combinations today, our delivery system picks the best performing, fully-formed ad and puts the majority of spend behind that ad. Creative optimization is happening at a fixed, and fully formed ad within the ad set. With Dynamic Creative, provide creative optimization for each individual, creative asset such as image, title, body, and then converge on the best creative asset combination per impression.

For insights on Dynamic Creative, you can retrieve creative-asset level insights, and then group data by age range and gender.

Q: How should I use dynamic creative? As a testing tool for figuring out the best creative concepts, or do we replace regular campaigns with them?

A: Dynamic Creative is a workflow to run actual ad campaigns and determine the best performing creatives. It is ideal for new, ongoing campaigns, or campaigns that run longer than 5 days. We recommend that you perform split testing of your Dynamic Creative ads with your existing campaigns to see which approach performs better for your needs.

Dynamic Creative optimizes with more advertiser data over time. So you should be able to consistently get higher ROI using Dynamic Creative compared to the standard ads delivery system.

Q: Can I view insights on the full, delivered ad? What about creative asset level breakdowns?

Currently, we only show creative-asset level breakdowns such as metrics by image, title, body, and so on. These metrics are available in Ads Manager under By Delivery.

Q: For regular ads we create a mix of single, carousel, image, or video ads under a single ad set. How can I do that with Dynamic Creative?

A: We currently only support a single-media format. Your selected format can be a single image, video or carousel image. We are working on multiple format support in one ad set.

Q: Can we use a daily budget, or it has to be lifetime only?

A: You can use both daily and lifetime budget.

Q: Does ads Insights API work the same way for fields for Dynamic Creative as they do for non-Dynamic Creative fields?

A: Dynamic Creative does not support the ad-level specific insights field: relevance_score.

Q: How does Dynamic Creative work for CAROUSEL_IMAGE ad format?

A: Dynamic Creative delivers the best combination of assets in carousel ad format. The number of cards is the number of images in the asset feed if less than 10, otherwise we display 10. In asset insights breakdown, for in-card assets, such as image, title, and description, we aggregate metrics when the asset is in the first card. We recommend square sizes for images.

If you are using the carousel ads format, you cannot use these features from carousel ads:

  • BODY_LABEL
  • CALL_TO_ACTION_TYPE_LABEL
  • LINK_URL_LABEL
  • CAPTION_LABEL
  • AD_FORMAT_LABEL

For background information, see Carousel ads.

Q: Can I edit my creative?

A: You can edit ad creative by providing it with a new asset_feed_spec. If you send the same spec, we report results for new assets under the older, existing asset name.

We reuse assets based on asset value and type. For example, if you have two asset_feed_specs with the same image hash, and you update one asset_feed_spec with another in your ad, you see combined impressions for that asset in the asset breakdowns.

You can add new assets, remove existing assets and replace assets with completely new ones. However, you cannot change formats such as changing SINGLE IMAGE to VIDEO. You also cannot update a Dynamic creative ad to be a non-Dynamic Creative ad which has no asset_feed_spec in the ad creative.

Q: What placements does Dynamic Creative support?

A: Dynamic Creative supports all placements except sponsored_messages on Messenger. The other restrictions that are in place for standard ads, also apply for Dynamic Creative ads. See Placement and Validation, Objective and Placement.

Q: Can I crop my images in Dynamic Creative?

A: Dynamic creative supports image cropping. Specify cropping for your image definition in images. You can provide only one crop per image. We apply your crops to all placements of your image. See Marketing API, Image Cropping.