Placement Targeting

Deliver ads on specific placements, such as desktop News Feed only, or mobile News Feed plus Audience Network Rewarded Video. You can only use certain placement options depending on your campaign objective. See Validation.

You can use device_platforms, publisher_platforms, facebook_positions, audience_network_positions, instagram_positions and messenger_positions, see Device, Publisher and Positions.

curl -X POST \ -F 'name="My AdSet"' \ -F 'optimization_goal="REACH"' \ -F 'billing_event="IMPRESSIONS"' \ -F 'bid_amount=2' \ -F 'daily_budget=1000' \ -F 'campaign_id="<AD_CAMPAIGN_ID>"' \ -F 'targeting={ "geo_locations": { "countries": [ "US" ] }, "publisher_platforms": [ "facebook" ], "facebook_positions": [ "feed" ] }' \ -F 'promoted_object={ "page_id": "<PAGE_ID>" }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v8.0/act_<AD_ACCOUNT_ID>/adsets
'use strict'; const bizSdk = require('facebook-nodejs-business-sdk'); const AdAccount = bizSdk.AdAccount; const AdSet = bizSdk.AdSet; 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' : 'My AdSet', 'optimization_goal' : 'REACH', 'billing_event' : 'IMPRESSIONS', 'bid_amount' : '2', 'daily_budget' : '1000', 'campaign_id' : '<adCampaignLinkClicksID>', 'targeting' : {'geo_locations':{'countries':['US']},'publisher_platforms':['facebook'],'facebook_positions':['feed']}, 'promoted_object' : {'page_id':'<pageID>'}, }; const adsets = (new AdAccount(id)).createAdSet( fields, params ); logApiCallResult('adsets api call complete.', adsets);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\AdSet; 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' => 'My AdSet', 'optimization_goal' => 'REACH', 'billing_event' => 'IMPRESSIONS', 'bid_amount' => '2', 'daily_budget' => '1000', 'campaign_id' => '<adCampaignLinkClicksID>', 'targeting' => array('geo_locations' => array('countries' => array('US')),'publisher_platforms' => array('facebook'),'facebook_positions' => array('feed')), 'promoted_object' => array('page_id' => '<pageID>'), ); echo json_encode((new AdAccount($id))->createAdSet( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebook_business.adobjects.adaccount import AdAccount from facebook_business.adobjects.adset import AdSet 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': 'My AdSet', 'optimization_goal': 'REACH', 'billing_event': 'IMPRESSIONS', 'bid_amount': '2', 'daily_budget': '1000', 'campaign_id': '<adCampaignLinkClicksID>', 'targeting': {'geo_locations':{'countries':['US']},'publisher_platforms':['facebook'],'facebook_positions':['feed']}, 'promoted_object': {'page_id':'<pageID>'}, } print AdAccount(id).create_ad_set( 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).createAdSet() .setName(\"My AdSet\") .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH) .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS) .setBidAmount(2L) .setDailyBudget(1000L) .setCampaignId(\"<adCampaignLinkClicksID>\") .setTargeting( new Targeting() .setFieldFacebookPositions(Arrays.asList(\"feed\")) .setFieldGeoLocations( new TargetingGeoLocation() .setFieldCountries(Arrays.asList(\"US\")) ) .setFieldPublisherPlatforms(Arrays.asList(\"facebook\")) ) .setPromotedObject(\"{\\"page_id\\":\\"<pageID>\\"}\") .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) adsets = ad_account.adsets.create({ name: 'My AdSet', optimization_goal: 'REACH', billing_event: 'IMPRESSIONS', bid_amount: '2', daily_budget: '1000', campaign_id: '<adCampaignLinkClicksID>', targeting: {'geo_locations':{'countries':['US']},'publisher_platforms':['facebook'],'facebook_positions':['feed']}, promoted_object: {'page_id':'<pageID>'}, })

If you do not specify anything for a particular placement field, Facebook considers all possible default positions for that field. For example, if you select facebook in publisher_platforms, but select nothing for facebook_positions, Facebook consider all default Facebook positions such as feed, right_hand_column, and so on. Or, if you do not select any publisher_platforms, Facebook considers all default publisher_platforms. Facebook may also automatically consider new positions or platforms as they become available.

On Audience Network, you can limit which publishers display your ads. Exclude publishers by category, or create a custom list of app store URLs or domain URLs to exclude.

You cannot use only right_hand_column alone as a placement for video, collection or canvas ads.

Inventory Filter helps you control whether your ads display next to different types content in Facebook Instant Articles, Facebook In-Stream and Audience Network. To learn more about these content categories, see Ads Help Center, Inventory Filter. You can choose one value for Facebook Instant Articles and Facebook In-Stream combined and one value for Audience Network. Options include: Full, Standard and Limited. For details, see brand_safety_content_filter_levels below:

Name Description

brand_safety_content_filter_levels

type: Array of strings values.

For Facebook Instant Articles and Facebook In-Stream, we allow these values:


  • FULL: FACEBOOK_RELAXED
  • STANDARD: FACEBOOK_STANDARD
  • LIMITED: FACEBOOK_STRICT

For Audience Network, we allow these values:


  • FULL: AN_RELAXED
  • STANDARD: AN_STANDARD
  • LIMITED: AN_STRICT

For example: "brand_safety_content_filter_levels":["FACEBOOK_STRICT", "AN_RELAXED"]

excluded_publisher_categories

type: Array of strings values

Includes: dating and gambling

excluded_publisher_list_ids

type: Array of numeric strings

Each string is a list ID for exclusions. Create custom lists in Ads Manager or Marketing API, Publisher Block List
Example: "excluded_publisher_list_ids":["{block_list_id_1}","{block_list_id_2}"]

For example, to use brand_safety_content_filter_levels:

curl \
  -F 'name=My AdSet' \
  -F 'optimization_goal=REACH' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'bid_amount=2' \
  -F 'daily_budget=1000' \
  -F 'campaign_id=CAMPAIGN_ID' \
  -F 'targeting= { "geo_locations":{"countries":["US"]}, "brand_safety_content_filter_levels":["FACEBOOK_STRICT","AN_STANDARD"]}' \
  -F 'status=ACTIVE' \
  -F 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/VERSION/AD_ACCOUNT_ID/adsets

For In-Stream video, you can also exclude publishers by category:

Name Description

excluded_publisher_categories

type: Array of string values

Includes:

  • debated_social_issues
  • mature_audiences
  • tragedy_and_conflict

Example: "excluded_publisher_categories": ["debated_social_issues", "mature_audiences"]

Device, Publisher, and Positions

Use these targeting specs subfields: device_platforms, publisher_platforms, facebook_positions, audience_network_positions and instagram_positions. device_platforms are device types someone has who sees your ad. Use publisher_platforms for publishing channel such as Instagram. xxxxxx_positions are positions on a certain publishing channel if there are multiple:

Name: Options Comments

device_platforms: mobile, desktop

Optional.

Default: All.

publisher_platforms: facebook, instagram, messenger, audience_network

Optional.

Default: Facebook, Instagram, Audience Network, Messenger

facebook_positions: feed, right_hand_column, instant_article, marketplace,video_feeds, story, search.

Optional.

Default: All.

Notes:

  • If provided, publisher_platforms must include facebook or do not provide to default to All.
  • feed includes News Feed for Desktop and Mobile.
  • If you select instant_article, you must use feed and for device_platforms, you must use mobile because Instant Articles is mobile-only.
  • For campaigns targeting the United States (US), United Kingdom (GB), France (FR), Spain (ES), Germany (DE), Mexico (MX), India (IN) and Thailand (TH), you can use instream_video without feed for Video View and Post Engagement objectives. For the CONVERSIONS objective, instream_video is not supported.
  • If you select story, you must use Facebook feed or Instagram story and for device_platforms, you must use mobile since Facebook Stories is mobile-only.
  • If you select marketplace or search, you must use feed.
  • As of v3.0, right_hand_column is only available for single image, single video, and carousel formats for the TRAFFIC, CONVERSIONS, and PRODUCT_CATALOG_SALES objectives.

instagram_positions: stream, story , explore

Optional.

Default: All.

You can target Instagram carousel ads for Instagram stream or story. If you are using unprompted carousel creative in stories, you cannot select both options for the same ad set.

audience_network_positions: classic, instream_video, rewarded_video

Optional.

Default: All.

By default, we don't return effective_audience_network_positions when you read the targeting spec for an ad set. This may differ from your configured audience_network_positions. If you specify a position that is not supported for a given objective, it appears in the list of configured positions, but not in the list of effective positions.

messenger_positions: messenger_home, sponsored_messages, story

Optional.

Default: messenger_home, story.

Notes:

  • If you select messenger_home, you must also select Facebook publisher_platform and feed in facebook_positions.
  • messenger_home is available for single image and carousel in LINK_CLICKS, CONVERSIONS, MESSAGES, APP_INSTALLS and PRODUCT_CATALOG_SALES objectives for ads driving traffic to websites, apps, and Messenger.
  • If you select story, you must use Facebook feed or Instagram story.
  • For device_platforms, you must use mobile because Messenger Stories is mobile-only. You can use story for single image and video formats in ad campaigns with CONVERSIONS, TRAFFIC, REACH, BRAND_AWARENESS, and APP_INSTALLS objectives for ads driving traffic to websites and apps.
  • You cannot use sponsored_messages with the other placements, including messenger_home and Facebook placements.

The logic for options in the same parameter is “OR”. For example, publisher_platforms=['facebook','instagram'] means deliver ads on Facebook and Instagram. The logic between parameters is “AND”. For example, publisher_platforms=['facebook']&device_platforms=['mobile'] means deliver these ads to Facebook Mobile only. If the logic results in targeting no one, such as publisher_platforms=['instagram']& device_platforms=['desktop'], you see an error.

All Facebook validations apply. For example, you cannot use Audience Network alone.

Examples

Stories

To use Facebook Stories as your placement:

curl \
  -F 'name=My Ad Set' 
  -F 'optimization_goal=CONVERSIONS' 
  -F 'billing_event=IMPRESSIONS' 
  -F 'bid_amount=2' 
  -F 'daily_budget=1000' 
  -F 'campaign_id=<AD_CAMPAIGN_ID>' 
  -F 'targeting={"geo_locations":{"countries":["US"]}, "publisher_platforms":["messenger", "facebook"], "facebook_positions":["story"], "messenger_positions":["story"]}' 
  -F 'status=ACTIVE'
  -F 'access_token=<ACCESS_TOKEN>' 
  https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adsets

Instream Video

To create an ad set with only instream_video placement that targets a supported country listed above:

curl \
  -F 'name=My AdSet' \
  -F 'optimization_goal=REACH' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'bid_amount=2' \
  -F 'daily_budget=1000' \
  -F 'campaign_id=CAMPAIGN_ID' \
  -F 'targeting={"geo_locations":{"countries":["US"]},"publisher_platforms":["facebook"], "facebook_positions":["instream_video"]}' \
  -F 'status=ACTIVE' \
  -F 'access_token=ACCESS_TOKEN' \
  https://graph.facebook.com/API_VERSION/act_AD_ACCOUNT_ID/adsets

Instant Articles

To use Instant Articles as your placement:

curl \
  -F 'name=My Ad Set' \
  -F 'optimization_goal=REACH' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'bid_amount=2' \
  -F 'daily_budget=1000' \
  -F 'campaign_id=<AD_CAMPAIGN_ID>' \
  -F 'targeting={"geo_locations":{"countries":["US"]}, "facebook_positions":["feed", "instant_article"]}' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/<APIVERSION>/act<AD_ACCOUNT_ID>/adsets

Audience Network

To target the Audience Network Rewarded Video placement:

curl \
  -F 'name=My Ad Set' \
  -F 'optimization_goal=OFFSITE_CONVERSIONS' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'is_autobid=true' \
  -F 'daily_budget=40000' \
  -F 'campaign_id=<AD_CAMPAIGN_ID>' \
  -F 'targeting={"app_install_state": "not_installed","geo_locations":{"countries":["US"]},"facebook_positions":["feed"],"device_platforms": ["mobile"],"audience_network_positions": ["classic","rewarded_video"],"user_device": ["Android_Smartphone","Android_Tablet"],"user_os": ["Android_ver_4.4_and_above"]}' \
  -F 'promoted_object={"application_id": "<APPLICATION_ID>","custom_event_type": "PURCHASE","object_store_url": "<OBJECT_STORE_URL>"}' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/<APIVERSION>/<AD_ACCOUNT_ID>/adsets

This returns:

{
  "targeting": {
    "audience_network_positions": [
      "classic",
      "rewarded_video"
    ],
    "effective_audience_network_positions": [
      "classic",
      "rewarded_video"
    ]
  },
  "id": "<AD_SET_ID>"
}

Effective Placement with Targeting

You create ad sets with placements in target spec, however you did not always know if Facebook delivered your ad to the placements specified. This is because your selected placement may not apply to your chosen advertising objective. With the effective placements API for targeting, you can now determine which placements your ad will deliver to, given your targeting options, and receive validation messages to understand why some placements are filtered out. If you do not provide targeting, you can still determine the effective placement based on ad set and ad campaign settings, see Effective Placements.

To read an effective placement based on your targeting, simply put effective_ before the placement fields. For example:

curl -G \
  -d     "fields=targeting{effective_publisher_platforms,effective_facebook_positions,effective_device_platforms,effective_audience_network_positions,effective_instagram_positions}" \
  -d "access_token=<access_token>" \
  https://graph.facebook.com/<VERSION>/<AD_SET_ID>

To see why some placements got filtered out, in the recommendation field, get a filtering message:

curl -G \
  -d "fields=recommendations" \
  -d "access_token=<access_token>" \
  https://graph.facebook.com/<VERSION>/23842573364570019