Asset Feed Setup

For Dynamic Creative, you should specify an asset_feed_spec to provide creative options for your ads. In this field, you can add multiple creative assets for each asset type. Some examples of asset types are images, videos, headlines and link descriptions.

asset_feed_spec provides creative for Dynamic Creative, Placement Asset Customization and Segment Asset Customization. The spec's format is different for each solution.

Create Asset Feed

Use asset_feed_spec to provide multiple creative assets. For Dynamic Creative, this field should not have customization rules.

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/v5.0/act_<AD_ACCOUNT_ID>/adcreatives
'use strict'; const bizSdk = require('facebook-nodejs-business-sdk'); const AdAccount = bizSdk.AdAccount; const AdCreative = bizSdk.AdCreative; const access_token = '<ACCESS_TOKEN>'; const app_secret = '<APP_SECRET>'; const app_id = '<APP_ID>'; const id = '<AD_ACCOUNT_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 = [ ]; 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':[]}, }; const 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 = '<AD_ACCOUNT_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 facebook_business.adobjects.adaccount import AdAccount 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 = '<AD_ACCOUNT_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 = \"<AD_ACCOUNT_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>\") ) .setAssetFeedSpec(\"{\\"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 = '<AD_ACCOUNT_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':[]}, })

You can create an 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

See all available options for Asset Feed Spec.

Read Asset Feed

To check your creative, read asset_feed_spec:

curl -X GET \ -d 'fields="asset_feed_spec"' \ -d 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v5.0/<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 = '<AD_CREATIVE_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 = '<AD_CREATIVE_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 = '<AD_CREATIVE_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 = \"<AD_CREATIVE_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 = '<AD_CREATIVE_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')

If your feed has multiple images and bodies, 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>",
}

If your feed has multiple videos, bodies, and titles, the response looks like this:

{  
   "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>",
}

Editing your creative

Add, replace or remove any of the creative's assets. To do so, provide another creative with the new asset_feed_spec.

You can:

  • Add assets.
  • Remove existing assets.
  • Replace assets with completely new ones.

You cannot:

  • Change ad formats, such as from SINGLE IMAGE to VIDEO.
  • Update an Asset Feed based creative ad to be a non-Dynamic Creative ad, which has no asset_feed_spec.
curl 
  -F 'access_token=<ACCESS_TOKEN>' 
  -F 'creative={
      "creative_id": <CREATIVE_ID>,
   }' 
https://graph.facebook.com/<API-VERSION>/<AD_ID>

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

Carousel Ads

Dynamic Creative delivers the best combination of assets in carousel ad format. If your feed has less than 10 images, the number of carousel cards is the same as the number of images. If you are using more than 10 images, we display a carousel with 10 cards. We recommend square sizes for images

If you are using carousel with Dynamic Creative, you cannot use these features from carousel ads:

  • BODY_LABEL
  • CALL_TO_ACTION_TYPE_LABEL
  • LINK_URL_LABEL
  • CAPTION_LABEL
  • AD_FORMAT_LABEL

In the asset insights breakdown, we aggregate impression based metrics for in-card assets for all cards to the assets in the first card. In-card assets include images, title, and description

For background information, see Carousel ads.

Image Cropping

Dynamic creative supports image cropping. Specify the image cropping parameter in your image spec. You can provide only one crop per image. We apply your crops to all placements of your image.

See Marketing API, Image Cropping.