Advanced Targeting and Placement

Targeting Specs are ad set attributes that define who sees an ad.

The week of September 10, 2017, we removed more than 3 million self-reported terms related to education and employment as targeting options in our ads interfaces. We did this after discovering a small percentage of people had entered offensive responses, in violation of our policies. After a thorough review, we are making additional changes to improve our policies, enforcement practices, and also adding back ~5,000 commonly used targeting terms that meet our Community Standards. For more information see Ads Developer Blog, Update to Self-Reported Profile Targeting Options.

Use these advanced options, your own in Custom Audiences and Lookalikes, or 3rd party Partner Categories. Use any combination of targeting; by default Facebook ORs combinations together. For "core", or basic targeting, see Targeting. Advanced targeting includes:

If you use flexible_spec, you must also provide one of the following under targeting:

  • geo_locations: geographical targeting field from country, region, city or zip
  • custom_audiences
  • product_audience_specs
  • dynamic_audience_ids

See Limits and Examples

Mobile

This is useful for Mobile App Install ads.

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::USER_DEVICE => array(
      'Galaxy S6',
      'One m9',
    ),
    TargetingFields::USER_OS => array('android'),
  )),
));

$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'user_device': [
            'galaxy s6',
            'one m9',
        ],
        'user_os': ['android'],
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
      .setFieldUserDevice(Arrays.asList("Galaxy S6", "One m9"))
      .setFieldUserOs(Arrays.asList("android"))
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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"]}, 
    "user_device": ["Galaxy S6","One m9"], 
    "user_os": ["android"] 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

You can combine categories such as iPod OR iPad OR iPhone. Between targeting spec fields and BCTs, Facebook calculates the intersection of all groups.

These categories are not mutually exclusive. If you select iOS you target all devices running iOS, including iPhone and iPod, without specifing user_device.**

For Brand Awareness Objective ads, you can't target based on mobile device type such as feature phones or Samsung, or based on iOS version number. You can only choose Android or iOS or all mobile phones.

Name Type Description Mobile app ad

user_os

array

One or more values from OS option table below. Possible values are at Targeting Search API with type=adTargetingCategory and class=user_os. You cannot target the minimum version of one platform with the other platform. However you can target both platforms without specifying minimal versions of either.
Valid:
- ['iOS', 'Android']
- ['iOS']
- ['Android_ver_4.2_and_above']
- ['iOS_ver_8.0_to_9.0']
Invalid:
- ['Android', 'iOS_ver_8.0_and_above']
- ['iOS', 'Android_ver_4.0_and_above']

Required

user_device

array

Devices must match the value in user_os. Get possible values at Targeting Search API with type=adTargetingCategory and class=user_device.

Optional

excluded_user_device

array

Devices to exclude. Devices must match the value in user_os. Get possible values at Targeting Search API with type=adTargetingCategory and class=user_device.

Not Required

wireless_carrier

array

Allowed value is Wifi. Target mobile users currently on wifi networks.

Optional


OS option Type Description

iOS

string

iOS devices, including iPhone, iPad, and iPod

iOS_ver_x.x_and_above

string

iOS devices running OS version x.x and above. Options: 2.0, 3.0, 4.0, 4.3, 5.0, 6.0, 7.0, 8.0, 9.0. e.g. iOS_ver_4.0_and_above

iOS_ver_x.x_to y.y

string

iOS devices running OS versions x.x to y.y. Options: 2.0, 3.0, 4.0, 4.3, 5.0, 6.0, 7.0, 8.0, 9.0. x.x must be less than y.y such as iOS_ver_8.0_to_9.0

Android

string

Android devices

Android_ver_x.x_and_above

string

Android devices running version x.x and above. Options: 2.0, 2.1, 2.2, 2.3, 3.0, 3.1, 3.2, 4.0, 4.1, 4.2., 4.3, 4.4, 5.0, 5.1, 6.0, 7.0, 7.1, and 8.0. e.g. Android_ver_4.0_and_above

Android_ver_x.x_to y.y

string

Android devices running versions x.x to y.y. Values are: 2.0, 2.1, 2.2, 2.3, 3.0, 3.1, 3.2, 4.0, 4.1, 4.2., 4.3, 4.4, 5.0, 5.1, 6.0, 7.0, 7.1, and 8.0. x.x must be less than y.y, such as Android_ver_4.2_to_8.0

Placement

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 and instagram_positions, see Device, Publisher and Positions.

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::PUBLISHER_PLATFORMS => array(
      'facebook',
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        Targeting.Field.publisher_platforms: ['facebook'],
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
      .setFieldPublisherPlatforms(Arrays.asList("facebook"))
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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"]}' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

If you do not specify anything for a particular placement field, Facebook considers all possible positions for that field. For example, if you select facebook in publisher_platforms, but select nothing for facebook_positions, Facebook consider all Facebook positions such as feed, right_hand_column, and so on. Or if you do not select any publisher_platforms, Facebook considers all available publisher_platforms. Facebook may also automatically consider new positions 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.

Name Type Description

excluded_publisher_categories

array

Array of strings values, including: dating and gambling

excluded_publisher_list_ids

array

Array of numeric strings. Each string is a list ID for exclusions. Create custom lists in Power Editor or Marketing API, Publisher Block List
Example "excluded_publisher_list_ids":["{block_list_id_1}","{block_list_id_2}"]

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

Name Type Description

excluded_publisher_categories

array

String values, including:
debated_social_issues
mature_audiences
tragedy_and_conflict
Example "excluded_publisher_categories": ["debated_social_issues", "mature_audiences"]

Device, Publisher, and Positions

After 2.7, 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:

Options Required? Default Comments

device_platforms

mobile, desktop

No

All

publisher_platforms

facebook, instagram, messenger, audience_network

No

facebook, audience_network, messenger

facebook_positions

feed, right_hand_column, instant_article, instream_video, suggested_video

No

All

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 since Instant Articles is mobile only. instream_video must be used with feed and is only available for Video View, Brand Awareness, and Post Engagement objectives. suggested_video must be used with feed and is only available for Video View, Brand Awareness, Post Engagement and Mobile App Install objectives.

instagram_positions

stream, story

No

stream

story cannot be used with the other placements, including stream and Facebook ones.

audience_network_positions

classic, instream_video, rewarded_video

No

All

By default we do not 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 which is not supported for a given objective, it will appear in the list of configured positions, but not in the list of effective positions.

messenger_positions

messenger_home, sponsored_messages

No

messenger_home

If you select messenger_home, you must also select facebook publisher_platform and feed in facebook_positions. messenger_home is only available for single image and carousel formats in LINK_CLICKS, CONVERSIONS and APP_INSTALLS objectives for ads driving traffic to websites, apps and Messenger. sponsored_messages cannot be used with the other placements, including messenger_home and Facebook ones.

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.

To use Instant Articles:

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","right_hand_column", "instant_article"]}' \
-F 'status=ACTIVE' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/<APIVERSION>/act<AD_ACCOUNT_ID>/adsets

Here is an example which targets 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

Returns a response similar to this:

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

Effective Placement

You create adsets 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. In the past, you had to create an actual ad and let it run for a couple of days, and figure out the actual placement settings from Insights. It was also difficult to know why some placements were filtered out. With the effective placements API, you can now figure out which placements your ad will deliver to, and receive validation messages to understand why some placements are filtered out.

Effective Placement API

To read effective placement API, 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>

Effective Placement Filtering Message

Learn 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

Facebook Connections

Target people who connected or did not connect with your brand.

Name Type Description

app_install_state

string

Only for app-related objectives: MOBILE_APP_*, CANVAS_APP_*. You must use with adset's promoted_object. You can apply to both link and video app ads. Options:

INSTALLED: target people with promoted object/app installed.

NOT_INSTALLED: target people without promoted object/app installed

NONE: same as not specifying.

such as 'app_install_state': 'NOT_INSTALLED'

connections

array of 'id' to value


[{'id':123}, {'id':456}, 789]

Array of Facebook IDs. Target fans of your Page, members of your Group, people who RSVP’d to your Event, people who logged into your app with Facebook Login, or authorized your Canvas app. To set this, you must be an admin of the page, group or event, or developer of the app you are advertising. You cannot target on past events. Limit: 50.

excluded_connections

array of 'id' to value


[{'id':123}, {'id':456}, 789]

Array of Facebook IDs. Target people who are not fans of your Page, have not authorized your Canvas App or have not logged into your mobile app with Facebook Login. You can also target people are not members of your groups or did not RSVP to a future event. If you have global Page and you want to exclude Page fans, you can only target people who are not fans of this global page, instead of people who are non-fants of your local page. To set this, you need to be an admin of the Page, group or event, or developer of the app being advertised. For a 'Page Likes' campaign, you must exclude your page from targeting.

friends_of_connections

array of 'id's plus values, values or both


[{'id':123}, {'id':456}, 789]

Array of Facebook Object IDs. Target friends of people connected to your object. Connections are fans of your Page, members of your Group, and people who interacted with your app. To set this, you must be to be an admin of the Page, group, or a developer of the app being advertised.

Education and Work

Use Targeting Search API for all options.

Name Type Description

education_schools

array

Schools/colleges/institutions, such as [{id: 105930651606, 'name': 'Harvard University'}, {id: 105930651607}, 105930651608] Limit: 200 education schools.

education_statuses

array

Array of integers to target based on education level.

1: HIGH_SCHOOL

2: UNDERGRAD

3: ALUM

4: HIGH_SCHOOL_GRAD

5: SOME_COLLEGE

6: ASSOCIATE_DEGREE

7: IN_GRAD_SCHOOL

8: SOME_GRAD_SCHOOL

9: MASTER_DEGREE

10: PROFESSIONAL_DEGREE

11: DOCTORATE_DEGREE

12: UNSPECIFIED

13: SOME_HIGH_SCHOOL

college_years

array

Array of integers. College graduation. Earliest year: 1980

education_majors

array

Majors such as [{'id': 123, 'name': 'Computer Science'}, {'id': 456}, 789] Limit: 200

work_employers

array

Company, organization, or workplace such as [{'id':'50431654','name':'Microsoft'}, {'id':50431655}, 50431656] Limit: 200

work_positions

array

Self-declared work: [{'id':105763692790962, 'name':'Contractor'}, {'id':105763692790963}, 105763692790964] Limit: 200

Custom Audiences

Create a custom audience and add users. You can use the audience in targeting, either for inclusion or exclusion. Include up to 500 custom audiences in custom_audiences and 500 custom audiences in excluded_custom_audiences.

excluded_custom_audiences in targeting_specs is different than excluded_custom_audiences in APP_COMBINATION Custom Audience.

Name Type Description

custom_audiences

array

Array of audience IDs or audience objects. 'id' field only: [123, 456] or [{'id': 123}, {'id': 456}]

excluded_custom_audiences

array

Array of audience IDs or audience objects. 'id' field only: [123, 456] or [{'id': 123}, {'id': 456}]

targeting:{
     "geo_locations":{
       "countries":["US"],
     },
     "age_min":25,
     "age_max":40,
     "custom_audiences":[{"id":6004192254512}]}
     "excluded_custom_audiences":
       [{"id":6004192252847}],
 }

Locales

Provide granular targeting on locale:

Name Type Description

locales

array

Locales, see Targeting Search, Locales. Indices in a sub-array 'locales'. Target people with language other than common language for a location. Provide an ID for the language, such as 5 for German. Limit: 50. If you set targeting to a '1xxx' values, which are virtual 'locales' representing a group of locales, Facebook sets targeting to individual locales in that group. See mapping of virtual 'locales' to language sets at Targeting Search, Locale with type=adlocale.

Custom Broad Category Targeting

Use Broad Categories (BCTs) for custom targeting created or permissioned specifically for your account. To include the cooking category and small business owner category:

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::USER_ADCLUSTERS => array(
      array(
        'id' => 6002714885172,
        'name' => 'Cooking',
      ),
      array(
        'id' => 6002714898572,
        'name' => 'Small Business Owners',
      ),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'user_adclusters': [
            {
                'id': 6002714885172,
                'name': 'Cooking',
            },
            {
                'id': 6002714898572,
                'name': 'Small Business Owners',
            },
        ],
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
      .setFieldUserAdclusters(Arrays.asList(
        new IDName()
          .setFieldId("6002714885172")
          .setFieldName("Cooking")
      , 
        new IDName()
          .setFieldId("6002714898572")
          .setFieldName("Small Business Owners")
      ))
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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"]}, 
    "user_adclusters": [ 
      {"id":6002714885172,"name":"Cooking"}, 
      {"id":6002714898572,"name":"Small Business Owners"} 
    ] 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

To exclude the cooking category and small business owner category:

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::EXCLUSIONS => array(
      TargetingFields::USER_ADCLUSTERS => array(
        array(
         'id' => 6002714885172,
         'name' => 'Cooking',
        ),
        array(
         'id' => 6002714898572,
         'name' => 'Small Business Owners',
        ),
      ),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'exclusions': {
            'user_adclusters': [
                {
                    'id': 6002714885172,
                    'name': 'Cooking',
                },
                {
                    'id': 6002714898572,
                    'name': 'Small Business Owners',
                },
            ],
        },
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldExclusions(
        new FlexibleTargeting()
          .setFieldUserAdclusters(Arrays.asList(
            new IDName()
              .setFieldId("6002714885172")
              .setFieldName("Cooking")
          , 
            new IDName()
              .setFieldId("6002714898572")
              .setFieldName("Small Business Owners")
          ))
      )
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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={ 
    "exclusions": { 
      "user_adclusters": [ 
        {"id":6002714885172,"name":"Cooking"}, 
        {"id":6002714898572,"name":"Small Business Owners"} 
      ] 
    }, 
    "geo_locations": {"countries":["US"]} 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

To target based on BCT plus location and demographics:

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::RELATIONSHIP_STATUSES => array (2),
    TargetingFields::USER_ADCLUSTERS => array(
      array(
        'id' => 6002714886772,
        'name' => 'Food & Dining',
      ),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'relationship_statuses': [2],
        'user_adclusters': [
            {
                'id': 6002714886772,
                'name': 'Food & Dining',
            },
        ],
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
      .setFieldRelationshipStatuses(Arrays.asList(2L))
      .setFieldUserAdclusters(Arrays.asList(
        new IDName()
          .setFieldId("6002714886772")
          .setFieldName("Food & Dining")
      ))
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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"]}, 
    "relationship_statuses": [2], 
    "user_adclusters": [{"id":6002714886772,"name":"Food & Dining"}] 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

You have options:

Name Type Description

user_adclusters

array

Array of ID-name pairs for BCT clusters. See below for information on retrieving BCT's. Limit: 50 ID-name pairs.

To query this targeting for Ad account, make an HTTP GET:

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

The response is an array of JSON key-value pairs:

Name Description type

id

ID of broad category is used for ad targeting spec

long

name

Name of broad category

string

parent_category

Parent category of broad category

string

size

Audience size of broad category

int

type

6=BCT

int

type_name

BCT

string

Targeting Expansion

Enable Facebook to expand interests when this increases results at a lower cost per result. Targeting expansion does not create lookalike audiences. Expanding interests does not change your targeting specifications for location, demographic targeting, such as age or gender, or exclusions.

A new audience for an ad set that's part of a campaign using the app installs or conversions objective will have targeting_optimization turned on by default. For campaigns with other objectives, targeting expansion is not enabled by default.

  • To opt in, set the `targeting_optimization` parameter to `expansion_all`.
  • To opt out, set `targeting_optimization` parameter to `none`.

If you use the targeting_optimization parameter for an unsupported objective, you will see an error. The supported objectives are Web Conversion, App Installs, Lead Generation, Link Click and Post Engagement. For example:

curl \
-F "name=relaxation null test" \
-F "promoted_object={'application_id': '<APP_ID>', 'object_store_url': 'https://itunes.apple.com/app/id1111111'}" \
-F "is_autobid=true" \
-F "daily_budget=100" \
-F "billing_event=IMPRESSIONS" \
-F "campaign_id=<CAMPAIGN_ID>" \
-F "access_token=XXX" \
-F "targeting={'geo_locations': {'countries': ['US', 'GB']}, 'user_os': ['iOS'], 'user_device': ['iPad', 'iPhone', 'iPod'], 'targeting_optimization': 'expansion_all'}" \
https://graph.facebook.com/<VERSION>/act_XXX/adsets

Flexible Targeting

Combine or exclude different targeting options to reach a specific set of users in the flexible_spec with AND and OR statements. Specify groups to be excluded in exclusions. Facebook evaluates targeting in flexible_spec via AND with all segments outside the spec such as age, gender, geo locations. We also evaluate each top level array element in flexible_spec with AND; we evaluate second-level array elements with OR.

Targeting segments such as interests/behaviors specified inside flexible_spec are not available for use outside of flexible_spec.

To target people who live in the U.S, aged between 20-24, who are not single or married and have not recently moved and are travelers or like soccer or movies and are newlyweds or like music:

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 150,
  AdSetFields::DAILY_BUDGET => 2000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::AGE_MIN => 18,
    TargetingFields::AGE_MAX => 43,
    TargetingFields::FLEXIBLE_SPEC => array(
      array(
        TargetingFields::BEHAVIORS => array(
          array(
            'id' => 6002714895372,
            'name' => 'All travelers',
          ),
        ),
        TargetingFields::INTERESTS => array(
          array(
            'id' => 6003107902433,
            'name' => 'Association football (Soccer)',
          ),
          array(
            'id' => 6003139266461,
            'name' => 'Movies',
          ),
        ),
      ),
      array(
        TargetingFields::INTERESTS => array(
          array(
            'id' => 6003020834693,
            'name' => 'Music',
          ),
        ),
        TargetingFields::LIFE_EVENTS => array(
          array(
            'id' => 6002714398172,
            'name' => 'Newlywed (1 year)',
          ),
        ),
      ),
    ),
    TargetingFields::EXCLUSIONS => array(
      TargetingFields::RELATIONSHIP_STATUSES => array(1, 3),
      TargetingFields::LIFE_EVENTS => array(
        array(
          'id' => 6003054185372,
          'name' => 'Recently moved',
        ),
      ),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'age_min': 18,
        'age_max': 43,
        'flexible_spec': [
            {
                'behaviors': [
                    {
                        'id': 6002714895372,
                        'name': 'All travelers',
                    },
                ],
                'interests': [
                    {
                        'id': 6003107902433,
                        'name': 'Association football (Soccer)',
                    },
                    {
                        'id': 6003139266461,
                        'name': 'Movies',
                    },
                ],
            },
            {
                'interests': [
                    {
                        'id': 6003020834693,
                        'name': 'Music',
                    },
                ],
                'life_events': [
                    {
                        'id': 6002714398172,
                        'name': 'Newlywed (1 year)',
                    },
                ],
            },
        ],
        'exclusions': {
            'relationship_statuses': [1, 3],
            'life_events': [
                {
                    'id': 6003054185372,
                    'name': 'Recently moved',
                },
            ],
        },
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(150L)
  .setDailyBudget(2000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldAgeMax(43L)
      .setFieldAgeMin(18L)
      .setFieldExclusions(
        new FlexibleTargeting()
          .setFieldLifeEvents(Arrays.asList(
            new IDName()
              .setFieldId("6003054185372")
              .setFieldName("Recently moved")
          ))
          .setFieldRelationshipStatuses(Arrays.asList(1L, 3L))
      )
      .setFieldFlexibleSpec(Arrays.asList(
        new FlexibleTargeting()
          .setFieldBehaviors(Arrays.asList(
            new IDName()
              .setFieldId("6002714895372")
              .setFieldName("All travelers")
          ))
          .setFieldInterests(Arrays.asList(
            new IDName()
              .setFieldId("6003107902433")
              .setFieldName("Association football (Soccer)")
          , 
            new IDName()
              .setFieldId("6003139266461")
              .setFieldName("Movies")
          ))
      , 
        new FlexibleTargeting()
          .setFieldInterests(Arrays.asList(
            new IDName()
              .setFieldId("6003020834693")
              .setFieldName("Music")
          ))
          .setFieldLifeEvents(Arrays.asList(
            new IDName()
              .setFieldId("6002714398172")
              .setFieldName("Newlywed (1 year)")
          ))
      ))
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
curl \
  -F 'name=My AdSet' \
  -F 'optimization_goal=REACH' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'bid_amount=150' \
  -F 'daily_budget=2000' \
  -F 'campaign_id=<CAMPAIGN_ID>' \
  -F 'targeting={ 
    "age_max": 43, 
    "age_min": 18, 
    "exclusions": { 
      "relationship_statuses": [1,3], 
      "life_events": [{"id":6003054185372,"name":"Recently moved"}] 
    }, 
    "flexible_spec": [ 
      { 
        "behaviors": [{"id":6002714895372,"name":"All travelers"}], 
        "interests": [ 
          {"id":6003107902433,"name":"Association football (Soccer)"}, 
          {"id":6003139266461,"name":"Movies"} 
        ] 
      }, 
      { 
        "interests": [{"id":6003020834693,"name":"Music"}], 
        "life_events": [{"id":6002714398172,"name":"Newlywed (1 year)"}] 
      } 
    ], 
    "geo_locations": {"countries":["US"]} 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

With this flexible spec, the resulting audience is:

(segment 1 or segment2 or segment3) and (segment 4 or segment 5) and segment 6

flexible_spec=
[
  {
    'segment_type':[segment1, segment2], 
    'segment_type':[segment3]
  },
  { 
    'segment_type':[segment4, segment5]
  },
  { 
    'segment_type':[segment6]
  }
]

Specify flexible_spec and exclusions as follows:

Name Type Description

flexible_spec

JSON Object

Array of arrays. Each contains a targeting segment in appropriate format, such as interests, behaviors, partner categories and demographics. The top level array has a limit of 25 and secondary level array has a limit of 1,000.

exclusions

JSON Object

Contains a targeting segment in its appropriate format such as interests, behaviors, partner categories and demographics.

For example, create an audience who lives in the U.S, aged 20-24, who are not single or married and have not recently moved and are travelers or like soccer or movies and are newlyweds or like music:

targeting=
{'geo_locations':{ 
  'countries': ['US'], 
}, 
'age_min':20, 
'age_max':24, 
'flexible_spec': [ 
  {
    'behaviors':[{'id':6002714895372,'name':'All travelers'},], 
    'interests':[ 
      {'id':6003107902433,'name':'Association football (Soccer)'}, 
      {'id':6003139266461, 'name': 'Movies'},],  
  }, 
  {
    'life_events':[{'id': 6002714398172, 'name': 'Newlywed (1 year)'}],
    'interests':[{'id':6003020834693,'name':'Music'},], 
  },   
], 
'exclusions': { 
  'relationship_statuses':[1,3], 
  'life_events':[{'id':6003054185372,'name':'Recently moved'},], 
}, 
} 

The targeting spec for this ad set:

{
  "targeting": { 
    "age_min": 20, 
    "age_max": 24,
    "exclusions": {
      "life_events": [
        {
          "id": "6003054185372", 
          "name": "Recently moved"
        }
      ], 
      "relationship_statuses": [
        1, 
        3
      ]
    }, 
    "flexible_spec": [
      {
        "interests": [
          {
            "id": "6003107902433", 
            "name": "Association football (Soccer)"
          }, 
          {
            "id": "6003139266461", 
            "name": "Movies"
          }
        ], 
        "behaviors": [
          {
            "id": "6002714895372", 
            "name": "All travelers"
          }
        ]
      }, 
      {
        "interests": [
          {
            "id": "6003020834693", 
            "name": "Music"
          }
        ],       
        "life_events": [
          {
            "id": "6002714398172", 
            "name": "Newlywed (1 year)"
          }
        ]
      }
    ], 
    "geo_locations": {
      "countries": [
        "US"
      ]
    }
  }, 
  "id": "6015417075447"
}

Use these fields in flexible targeting:

  • connections
  • friends_of_connections
  • custom_audiences
  • interests
  • user_adclusters
  • behaviors
  • college_years
  • education_majors
  • education_schools
  • education_statuses
  • family_statuses
  • generation
  • home_type
  • home_ownership
  • home_value
  • household_composition
  • interested_in
  • income
  • industries
  • life_events
  • moms
  • net_worth
  • office_type
  • politics
  • relationship_statuses
  • work_positions
  • work_employers

Partner Categories

Target groups created by Facebook's third party data providers and reach people on Facebook based on their off-Facebook activity. These categories are defined by partner data matching. Exclusion targeting is not supported for partner categories.

We group partner categories with Facebook categories under demographics and behaviors. As you do with Facebook targeting, you find them with Targeting Search API. You can also find them under several targeting classes and they appear with Facebook categories. To view only Partner Categories, see Targeting Search, Partner Categories, By Account Id.

To target ads with partner categories, provide type from search results in your targeting_spec:

targeting={
  'behaviors':[
    {id: 6006142989425, 'name': 'Full-size SUV'},
  ],
  'household_composition':[
    {id: 6009218313499, 'name': 'Children in home'},
  ],
  'user_adclusters':[
    {id: 6006371326532, 'name': 'Recent homebuyer'},
  ],
}

If you get categories with class=uncategorized, type is user_adclusters. To target people who are recent home buyers and in household size bigger than 3:

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::FLEXIBLE_SPEC => array(
      array(
        TargetingFields::USER_ADCLUSTERS => array(
          array(
            'id' => 6006371340132,
            'name' => 'Demographic > Household Size > 3',
          ),
        ),
      ),
      array(
        TargetingFields::USER_ADCLUSTERS => array(
          array(
            'id' => 6006371326532,
            'name' => 'Demographic > Home > Home Owner > Recent Buyer',
          ),
        ),
      ),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'flexible_spec': [
            {
                'user_adclusters': [
                    {
                        'id': 6006371340132,
                        'name': 'Demographic > Household Size > 3',
                    },
                ],
            },
            {
                'user_adclusters': [
                    {
                        'id': 6006371326532,
                        'name':
                            'Demographic > Home > Home Owner > Recent Buyer',
                    },
                ],
            },
        ],
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldFlexibleSpec(Arrays.asList(
        new FlexibleTargeting()
          .setFieldUserAdclusters(Arrays.asList(
            new IDName()
              .setFieldId("6006371340132")
              .setFieldName("Demographic > Household Size > 3")
          ))
      , 
        new FlexibleTargeting()
          .setFieldUserAdclusters(Arrays.asList(
            new IDName()
              .setFieldId("6006371326532")
              .setFieldName("Demographic > Home > Home Owner > Recent Buyer")
          ))
      ))
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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={ 
    "flexible_spec": [ 
      { 
        "user_adclusters": [{"id":6006371340132,"name":"Demographic > Household Size > 3"}] 
      }, 
      { 
        "user_adclusters": [ 
          { 
            "id": 6006371326532, 
            "name": "Demographic > Home > Home Owner > Recent Buyer" 
          } 
        ] 
      } 
    ], 
    "geo_locations": {"countries":["US"]} 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

Targeting BCT & Partner Categories:

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array(
        'US',
      ),
    ),
    TargetingFields::FLEXIBLE_SPEC => array(
      array(
        TargetingFields::USER_ADCLUSTERS => array(
          array(
           'id' => 6002714885172,
            'name' => 'Cooking',
          ),
        ),
      ),
      array(
        TargetingFields::USER_ADCLUSTERS => array(
          array(
            'id' => 6006371326532,
            'name' => 'Demographic > Home > Home Owner > Recent Buyer',
          ),
        ),
      ),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'flexible_spec': [
            {
                'user_adclusters': [
                    {
                        'id': 6002714885172,
                        'name': 'Cooking',
                    },
                ],
            },
            {
                'user_adclusters': [
                    {
                        'id': 6006371326532,
                        'name':
                            'Demographic > Home > Home Owner > Recent Buyer',
                    },
                ],
            },
        ],
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldFlexibleSpec(Arrays.asList(
        new FlexibleTargeting()
          .setFieldUserAdclusters(Arrays.asList(
            new IDName()
              .setFieldId("6002714885172")
              .setFieldName("Cooking")
          ))
      , 
        new FlexibleTargeting()
          .setFieldUserAdclusters(Arrays.asList(
            new IDName()
              .setFieldId("6006371326532")
              .setFieldName("Demographic > Home > Home Owner > Recent Buyer")
          ))
      ))
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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={ 
    "flexible_spec": [ 
      {"user_adclusters":[{"id":6002714885172,"name":"Cooking"}]}, 
      { 
        "user_adclusters": [ 
          { 
            "id": 6006371326532, 
            "name": "Demographic > Home > Home Owner > Recent Buyer" 
          } 
        ] 
      } 
    ], 
    "geo_locations": {"countries":["US"]} 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

Targeting Custom Audience & Partner Categories:

To target people who bought games from you directly or are in the "Gamers" partner category.

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;
use FacebookAds\Object\Fields\TargetingFields;
use FacebookAds\Object\Targeting;

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My AdSet',
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::REACH,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::BID_AMOUNT => 2,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array('US'),
    ),
    TargetingFields::CUSTOM_AUDIENCES => array(
      array(
        'id' => <AUDIENCE_ID>,
        'name' => <AUDIENCE_NAME>,
      ),
    ),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_ACTIVE,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')

params = {
    AdSet.Field.name: 'My AdSet',
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.daily_budget: 2000,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.targeting: {
        'geo_locations': {
            'countries': ['US'],
        },
        'custom_audiences': [
            {
                'id': <CUSTOM_AUDIENCE_ID>,
                'name': <AUDIENCE_NAME>,
            },
        ],
    },
    AdSet.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My AdSet")
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setBidAmount(2L)
  .setDailyBudget(1000L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setTargeting(
    new Targeting()
      .setFieldCustomAudiences(Arrays.asList(
        new IDName()
          .setFieldId(<AUDIENCE_ID>)
          .setFieldName(<AUDIENCE_NAME>)
      ))
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCountries(Arrays.asList("US"))
      )
  )
  .setStatus(AdSet.EnumStatus.VALUE_ACTIVE)
  .execute();
String ad_set_id = adSet.getId();
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={ 
    "custom_audiences": [{"id":"<AUDIENCE_ID>","name":"<AUDIENCE_NAME>"}], 
    "geo_locations": {"countries":["US"]} 
  }' \
  -F 'status=ACTIVE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets

Limits

Limitations on ad targeting:

Area Limit

Minimum age of a user to target ad

13 years old

Maximum age of a user to target ad?

65 years old

Languages targeted per ad

50

Interests targeted

400

Colleges targeted

200

Workplaces targeted

200

Majors targeted

200

Cities targeted

250

Connections targeted

50

Latest graduation year targeted

1980

Resources