Ads Management

Create ad campaigns, provide bids for ads auction, and manage ad creative.

Quickstart

Here are the basics steps to manage ad campaigns with the Facebook Marketing API.

1. Create a Campaign

2. Define Targeting

3. Define Budget, Billing, Optimization, and Duration

4. Create Ad Creative

5. Book Ad


1. Create a Campaign

Create a new campaign with the class Campaign. In our example we:

  1. Set a title: My First Campaign.
  2. Pause the campaign so that you don't get billed while testing.
  3. Set an objective for your ad, such as link clicks, which asks people to visit your website.

Add the following:

use FacebookAds\Object\Campaign;
use FacebookAds\Object\Fields\CampaignFields;
use FacebookAds\Object\Values\CampaignObjectiveValues;

$campaign = new Campaign(null, 'act_<AD_ACCOUNT_ID>');
$campaign->setData(array(
  CampaignFields::NAME => 'My campaign',
  CampaignFields::OBJECTIVE => CampaignObjectiveValues::LINK_CLICKS,
));

$campaign->create(array(
  Campaign::STATUS_PARAM_NAME => Campaign::STATUS_PAUSED,
));
from facebookads.adobjects.campaign import Campaign

campaign = Campaign(parent_id='act_<AD_ACCOUNT_ID>')
campaign.update({
    Campaign.Field.name: 'My Campaign',
    Campaign.Field.objective: Campaign.Objective.link_clicks,
})

campaign.remote_create(params={
    'status': Campaign.Status.paused,
})
Campaign campaign = new AdAccount(act_<AD_ACCOUNT_ID>, context).createCampaign()
  .setName("My campaign")
  .setObjective(Campaign.EnumObjective.VALUE_LINK_CLICKS)
  .setStatus(Campaign.EnumStatus.VALUE_PAUSED)
  .execute();
String campaign_id = campaign.getId();
curl \
  -F 'name=My campaign' \
  -F 'objective=LINK_CLICKS' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/campaigns

Verify Campaign Creation

Verify a campaign under Manage Ads in the ads manager.

Manage Ads: My Campaigns
Reference: CampaignAdObjectives in PHPAdObjectives in Python

2. Define Targeting

Create an ad set, which is a group of ads that share the same daily or lifetime budget, schedule, billing, optimization, and targeting data. Here you define the target audience, in step 4 you create the ad set and it's other attributes.

use FacebookAds\Object\TargetingSearch;
use FacebookAds\Object\Search\TargetingSearchTypes;

$result = TargetingSearch::search(
  TargetingSearchTypes::INTEREST,
  null,
  'baseball');
from facebookads.adobjects.targetingsearch import TargetingSearch
params = {
    'q': 'baseball',
    'type': 'adinterest',
}

resp = TargetingSearch.search(params=params)
print(resp)
curl -G \
  -d 'type=adinterest' \
  -d 'q=baseball' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/search

Based on the interests received above we create a sample targeting spec.

use FacebookAds\Object\Targeting;
use FacebookAds\Object\Fields\TargetingFields;

$targeting = new Targeting();
$targeting->{TargetingFields::GEO_LOCATIONS} =
  array(
    'countries' => array('US')
  );
$targeting->{TargetingFields::INTERESTS} = <INTERESTS>;
from facebookads.adobjects.targeting import Targeting

targeting = {
    Targeting.Field.geo_locations: {
        Targeting.Field.countries: ['US'],
    },
    Targeting.Field.interests: <INTERESTS>,
}
Reference: Targeting SpecsReference: Targeting Search

3. Define Budget, Billing, Optimization, and Duration

With targeting set, you create an AdSet describing:

  • How long your ad will run: start_time / end_time.
  • How much money you want to spend per day, daily_budget.
  • What result you want to achieve with your ad: optimization_goal.
  • How you want to pay billing_event.
  • What value you place on your optimization event occuring (bid_amount).

You can also managing billing, set lifetime budgets and so on. Use the example below to create your ad set and set status to paused to avoid charges for your test.

use DateTime;
use FacebookAds\Object\AdSet;
use FacebookAds\Object\Fields\AdSetFields;
use FacebookAds\Object\Values\AdSetBillingEventValues;
use FacebookAds\Object\Values\AdSetOptimizationGoalValues;

$start_time = (new \DateTime("+1 week"))->format(DateTime::ISO8601);
$end_time = (new \DateTime("+2 week"))->format(DateTime::ISO8601);

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My Ad Set',
  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 => <TARGETING>,
  AdSetFields::START_TIME => $start_time,
  AdSetFields::END_TIME => $end_time,
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_PAUSED,
));
import datetime
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet

today = datetime.date.today()
start_time = str(today + datetime.timedelta(weeks=1))
end_time = str(today + datetime.timedelta(weeks=2))

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

params = {
    AdSet.Field.name: 'My Ad Set',
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.daily_budget: 1000,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.reach,
    AdSet.Field.bid_amount: 2,
    AdSet.Field.targeting: <TARGETING>,
    AdSet.Field.start_time: start_time,
    AdSet.Field.end_time: end_time,
    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 Ad Set")
  .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"))
      )
  )
  .setStartTime(start_time)
  .setEndTime(end_time)
  .setStatus(AdSet.EnumStatus.VALUE_PAUSED)
  .execute();
String ad_set_id = adSet.getId();
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=<CAMPAIGN_ID>' \
  -F 'targeting={"geo_locations":{"countries":["US"]}}' \
  -F 'start_time=2017-06-30T19:34:17+0000' \
  -F 'end_time=2017-07-07T19:34:17+0000' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/adsets
Reference: Ad Set

4. Provide Ad Creative

Use AdCreative to design your ad format. The information you provide in AdCreative depends on the objective. Common attributes are:

  • One or more uplaoded images or videos
  • Set title, description, and so on
  • Link your ad to a Facebook Page
  • Add a "Call to Action" button

Depending on your objective you may have to provide advanced fields. By example, ads for an iOS app require an app store URL. With the objective "website clicks", provide a link to your website.

First, create an AdImage from an image file.

use FacebookAds\Object\AdImage;
use FacebookAds\Object\Fields\AdImageFields;

$image = new AdImage(null, 'act_<AD_ACCOUNT_ID>');
$image->{AdImageFields::FILENAME} = '<IMAGE_PATH>';

$image->create();
echo 'Image Hash: '.$image->{AdImageFields::HASH}.PHP_EOL;
from facebookads.adobjects.adimage import AdImage

image = AdImage(parent_id='act_<AD_ACCOUNT_ID>')
image[AdImage.Field.filename] = '<IMAGE_PATH>'
image.remote_create()

# Output image Hash
print(image[AdImage.Field.hash])
AdImage adImage = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdImage()
  .addUploadFile("filename", new File(<IMAGE_PATH>))
  .execute();
curl \
  -F 'filename=@<IMAGE_PATH>' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/adimages

Then, use the image hash to create the AdCreative.

use FacebookAds\Object\AdCreative;
use FacebookAds\Object\AdCreativeLinkData;
use FacebookAds\Object\Fields\AdCreativeLinkDataFields;
use FacebookAds\Object\AdCreativeObjectStorySpec;
use FacebookAds\Object\Fields\AdCreativeObjectStorySpecFields;
use FacebookAds\Object\Fields\AdCreativeFields;

$link_data = new AdCreativeLinkData();
$link_data->setData(array(
  AdCreativeLinkDataFields::MESSAGE => 'try it out',
  AdCreativeLinkDataFields::LINK => '<URL>',
  AdCreativeLinkDataFields::IMAGE_HASH => '<IMAGE_HASH>',
));

$object_story_spec = new AdCreativeObjectStorySpec();
$object_story_spec->setData(array(
  AdCreativeObjectStorySpecFields::PAGE_ID => <PAGE_ID>,
  AdCreativeObjectStorySpecFields::LINK_DATA => $link_data,
));

$creative = new AdCreative(null, 'act_<AD_ACCOUNT_ID>');

$creative->setData(array(
  AdCreativeFields::NAME => 'Sample Creative',
  AdCreativeFields::OBJECT_STORY_SPEC => $object_story_spec,
));

$creative->create();
from facebookads.adobjects.adcreative import AdCreative
from facebookads.adobjects.adcreative'<LINK>'data import AdCreativeLinkData
from facebookads.adobjects.adcreativeobjectstoryspec \
    import AdCreativeObjectStorySpec

link_data = AdCreativeLinkData()
link_data[AdCreativeLinkData.Field.message] = 'try it out'
link_data[AdCreativeLinkData.Field.link] = '<LINK>'
link_data[AdCreativeLinkData.Field.image_hash] = '<IMAGE_HASH>'

object_story_spec = AdCreativeObjectStorySpec()
object_story_spec[AdCreativeObjectStorySpec.Field.page_id] = <PAGE_ID>
object_story_spec[AdCreativeObjectStorySpec.Field.link_data] = link_data

creative = AdCreative(parent_id='act_<AD_ACCOUNT_ID>')
creative[AdCreative.Field.name] = 'AdCreative for Link Ad'
creative[AdCreative.Field.object_story_spec] = object_story_spec
creative.remote_create()

print(creative)
AdCreative adCreative = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdCreative()
  .setName("Sample Creative")
  .setObjectStorySpec(
    new AdCreativeObjectStorySpec()
      .setFieldLinkData(
        new AdCreativeLinkData()
          .setFieldCaption("My caption")
          .setFieldImageHash(<IMAGE_HASH>)
          .setFieldLink(<URL>)
          .setFieldMessage("try it out")
      )
      .setFieldPageId(<PAGE_ID>)
  )
  .execute();
String ad_creative_id = adCreative.getId();
curl \
  -F 'name=Sample Creative' \
  -F 'object_story_spec={ 
    "link_data": { 
      "image_hash": "<IMAGE_HASH>", 
      "link": "<URL>", 
      "message": "try it out" 
    }, 
    "page_id": "<PAGE_ID>" 
  }' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/adcreatives

Verify your image upload by going to your Image Library in the ads manager.

The AdCreative with your link is not yet visible in Ads Manager. You see this data once you book you ad. You can debug your ad creative with Graph API Explorer:

GET /{my-creative-id} HTTP/1.1
Host: graph.facebook.com

Manage Ads: Image LibraryReference: Ad Creative

5. Schedule Delivery

Finally, create your Facebook ad with Ad. With an Ad you link your AdCreative and AdSet to a new object representing your ad. Set the status of your Ad to paused. This will avoid placing an order instantly.

use FacebookAds\Object\Ad;
use FacebookAds\Object\Fields\AdFields;

$data = array(
  AdFields::NAME => 'My Ad',
  AdFields::ADSET_ID => <AD_SET_ID>,
  AdFields::CREATIVE => array(
    'creative_id' => <CREATIVE_ID>,
  ),
);

$ad = new Ad(null, 'act_<AD_ACCOUNT_ID>');
$ad->setData($data);
$ad->create(array(
  Ad::STATUS_PARAM_NAME => Ad::STATUS_PAUSED,
));
from facebookads.adobjects.ad import Ad

ad = Ad(parent_id='act_<AD_ACCOUNT_ID>')
ad[Ad.Field.name] = 'My Ad'
ad[Ad.Field.adset_id] = <AD_SET_ID>
ad[Ad.Field.creative] = {
    'creative_id': <CREATIVE_ID>,
}
ad.remote_create(params={
    'status': Ad.Status.paused,
})
Ad ad = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAd()
  .setName("My Ad")
  .setAdsetId(<AD_SET_ID>)
  .setCreative(
    new AdCreative()
      .setFieldId(<CREATIVE_ID>)
  )
  .setStatus(Ad.EnumStatus.VALUE_PAUSED)
  .execute();
curl \
  -F 'name=My Ad' \
  -F 'adset_id=<AD_SET_ID>' \
  -F 'creative={"creative_id":"<CREATIVE_ID>"}' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/ads

Verify that your ad exists by going to Manage Ads in the ads manager:

  1. Click on the campaign you created.
  2. Click on the ad set you created.
  3. Click on the ad you created.

Once you're comfortable booking ads with the API, set the status to active. The ad first goes through ad review, and has the status PENDING_REVIEW. After it finishes review and it goes back to the status of ACTIVE.


Manage Ads: My CampaignsReference: Ad

Campaign Structure

Facebook's campaign structure has 3 levels: campaign, ad set and ad. In the API, there is a fourth level available for developers, called the creative.

  • Campaigns contains your advertising objective and one or more ad sets. This helps you optimize and measure results for each advertising objective.

  • Ad Sets have one or more ads. You define budget and schedule for each ad set. Create an ad set for each target audience with your bid; ads in the set target the same audience with the same bid. This helps control the amount you spend on each audience, determine when audience will see your ads, and provides metrics for each audience.

  • Ads contain ad creative). Create multiple ads in each ad set will to optimize ad delivery based different images, links, video, text or placements.

  • Ad creatives contain just the visual elements of the ad and once created, are immutable. Each ad account has a creative library to store creatives for reuse in ads.

Objective Schedule Budget Bidding Targeting Creative

Campaign

Ad Set

Ad

Mapping between the public facing naming of the object and API endpoints:

Public facing name API endpoint

Campaign

/campaigns

Ad Set

/adsets

Ad

/ads

Creative

/adcreatives

Campaigns

A campaign is the highest level organizational structure within an ad account and should represent a single objective for an advertiser, for example, to drive page post engagement. All of the objectives can be found listed within the documentation. Setting objective of the campain will enforce validation on any ads added to the campaign to ensure they also have the correct objective.

In the ads manager we show all of the active and paused campaigns within an ad account.

To read the campaigns associated with a specific account, you make a request to the connection of the ad account you are using. By default we only return campaigns whose status is ACTIVE or PAUSED, so you will need to specify additional statuses if required:

use FacebookAds\Object\Values\ArchivableCrudObjectEffectiveStatuses;
use FacebookAds\Object\AdAccount;
use FacebookAds\Object\Fields\CampaignFields;

$account = new AdAccount('act_<AD_ACCOUNT_ID>');
$campaigns = $account->getCampaigns(array(
  CampaignFields::NAME,
  CampaignFields::OBJECTIVE,
), array(
  CampaignFields::EFFECTIVE_STATUS => array(
    ArchivableCrudObjectEffectiveStatuses::ACTIVE,
    ArchivableCrudObjectEffectiveStatuses::PAUSED,
  ),
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.campaign import Campaign

fields = {
    Campaign.Field.name,
    Campaign.Field.objective,
}

params = {
    Campaign.Field.effective_status: [
        'ACTIVE',
        'PAUSED',
    ],
}

account = AdAccount('act_<AD_ACCOUNT_ID>')
campaigns = account.get_campaigns(fields=fields, params=params)
APINodeList<Campaign> campaigns = new AdAccount(act_<AD_ACCOUNT_ID>, context).getCampaigns()
  .setEffectiveStatus("[\"ACTIVE\",\"PAUSED\"]")
  .requestNameField()
  .requestObjectiveField()
  .execute();
curl -G \
  -d 'effective_status=["ACTIVE","PAUSED"]' \
  -d 'fields=name,objective' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/campaigns

We also show some high level insights, including impressions, clicks and the amount spent. You can retrieve these by calling the following endpoint, optionally specifying the start and/or end time:

use FacebookAds\Object\Campaign;

$campaign = new Campaign(<CAMPAIGN_ID>);
$insights = $campaign->getInsights(array(
  AdsInsightsFields::IMPRESSIONS,
  AdsInsightsFields::INLINE_LINK_CLICKS,
  AdsInsightsFields::SPEND,
), array(
  'end_time' => (new \DateTime('now'))->getTimestamp(),
));
from facebookads.adobjects.campaign import Campaign
from facebookads.adobjects.adsinsights import AdsInsights
import time

fields = [
    AdsInsights.Field.impressions,
    AdsInsights.Field.inline_link_clicks,
    AdsInsights.Field.spend,
]

params = {
    'end_time': int(time.time()),
}

campaign = Campaign(<CAMPAIGN_ID>)
insights = campaign.get_insights(fields=fields, params=params)
APINodeList<AdsInsights> adsInsightss = new Campaign(<CAMPAIGN_ID>, context).getInsights()
  .setParam("end_time", end_time)
  .requestField("impressions")
  .requestField("inline_link_clicks")
  .requestField("spend")
  .execute();
curl -G \
  -d 'end_time=1498265320' \
  -d 'fields=impressions,inline_link_clicks,spend' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/<CAMPAIGN_ID>/insights

Ad Sets

Ad sets are groups of ads, and are used to configure the budget and period the ads should run for. All ads contained within an ad set should have the same targeting.

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

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My First AdSet',
  AdSetFields::LIFETIME_BUDGET => 20000,
  AdSetFields::START_TIME => <START_TIME>,
  AdSetFields::END_TIME => <END_TIME>,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::BID_AMOUNT => 500,
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::OPTIMIZATION_GOAL =>
    AdSetOptimizationGoalValues::POST_ENGAGEMENT,
  AdSetFields::TARGETING => (new Targeting())->setData(array(
    TargetingFields::GEO_LOCATIONS => array(
      'countries' => array('JP'),
      'regions' => array(
        array('key' => '3886')
      ),
      'cities' => array(
        array(
          'key' => '2420605',
          'radius' => 10,
          'distance_unit' => 'mile',
        )
      ),
    ),
    TargetingFields::GENDERS => array(1),
    TargetingFields::AGE_MIN => 20,
    TargetingFields::AGE_MAX => 24,
    TargetingFields::INTERESTS => array(
      array(
        'id' => 6003107902433,
        'name' => 'Association football (Soccer)',
      )
    ),
    TargetingFields::BEHAVIORS => array(
      array(
        'id' => 6002714895372,
        'name' => 'All travelers',
      )
    ),
    TargetingFields::LIFE_EVENTS => array(
      array(
        'id' => 6002714398172,
        'name' => 'Newlywed (1 year)',
      )
    ),
    TargetingFields::HOME_OWNERSHIP => array(
      array(
        'id' => 6006371327132,
        'name' => 'Renters',
      )
    ),
    TargetingFields::PUBLISHER_PLATFORMS => array(
      'facebook', 'audience_network'),
  )),
));
$adset->create(array(
  AdSet::STATUS_PARAM_NAME => AdSet::STATUS_PAUSED,
));
from facebookads.adobjects.adaccount import AdAccount
from facebookads.adobjects.adset import AdSet
from facebookads.adobjects.targeting import Targeting

ad_account = AdAccount(fbid='act_<AD_ACCOUNT_ID>')
params = {
    AdSet.Field.name: 'My First AdSet',
    AdSet.Field.lifetime_budget: 20000,
    AdSet.Field.start_time: <START_TIME>,
    AdSet.Field.end_time: <END_TIME>,
    AdSet.Field.campaign_id: <CAMPAIGN_ID>,
    AdSet.Field.bid_amount: 500,
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.post_engagement,
    AdSet.Field.targeting: {
        Targeting.Field.geo_locations: {
            'countries': ['JP'],
        },
        Targeting.Field.genders: [1],
        Targeting.Field.age_min: 20,
        Targeting.Field.age_max: 24,
        Targeting.Field.interests: [
            {
                'id': 6003107902433,
                'name': 'Association football (Soccer)',
            },
        ],
        Targeting.Field.behaviors: [
            {
                'id': 6002714895372,
                'name': 'All travelers',
            },
        ],
        Targeting.Field.life_events: [
            {
                'id': 6002714398172,
                'name': 'Newlywed (1 year)',
            },
        ],
        Targeting.Field.home_ownership: [
            {
                'id': 6006371327132,
                'name': 'Renters',
            },
        ],
        Targeting.Field.publisher_platforms: [
            'facebook',
            'audience_network',
        ],
    },
    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 First AdSet")
  .setLifetimeBudget(20000L)
  .setStartTime(<START_TIME>)
  .setEndTime(<END_TIME>)
  .setCampaignId(<CAMPAIGN_ID>)
  .setBidAmount(500L)
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_POST_ENGAGEMENT)
  .setTargeting(
    new Targeting()
      .setFieldAgeMax(24L)
      .setFieldAgeMin(20L)
      .setFieldBehaviors(Arrays.asList(
        new IDName()
          .setFieldId("6002714895372")
          .setFieldName("All travelers")
      ))
      .setFieldGenders(Arrays.asList(1L))
      .setFieldGeoLocations(
        new TargetingGeoLocation()
          .setFieldCities(Arrays.asList(
            new TargetingGeoLocationCity()
              .setFieldDistanceUnit("mile")
              .setFieldKey("2420605")
              .setFieldRadius(10L)
          ))
          .setFieldCountries(Arrays.asList("JP"))
          .setFieldRegions(Arrays.asList(
            new TargetingGeoLocationRegion()
              .setFieldKey("3886")
          ))
      )
      .setFieldHomeOwnership(Arrays.asList(
        new IDName()
          .setFieldId("6006371327132")
          .setFieldName("Renters")
      ))
      .setFieldInterests(Arrays.asList(
        new IDName()
          .setFieldId("6003107902433")
          .setFieldName("Association football (Soccer)")
      ))
      .setFieldLifeEvents(Arrays.asList(
        new IDName()
          .setFieldId("6002714398172")
          .setFieldName("Newlywed (1 year)")
      ))
      .setFieldPublisherPlatforms(Arrays.asList("facebook", "audience_network"))
  )
  .setStatus(AdSet.EnumStatus.VALUE_PAUSED)
  .execute();
String ad_set_id = adSet.getId();
curl \
  -F 'name=My First AdSet' \
  -F 'lifetime_budget=20000' \
  -F 'start_time=<START_TIME>' \
  -F 'end_time=<END_TIME>' \
  -F 'campaign_id=<CAMPAIGN_ID>' \
  -F 'bid_amount=500' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'optimization_goal=POST_ENGAGEMENT' \
  -F 'targeting={ 
    "age_max": 24, 
    "age_min": 20, 
    "behaviors": [{"id":6002714895372,"name":"All travelers"}], 
    "genders": [1], 
    "geo_locations": { 
      "countries": ["JP"], 
      "regions": [{"key":"3886"}], 
      "cities": [ 
        { 
          "key": "2420605", 
          "radius": 10, 
          "distance_unit": "mile" 
        } 
      ] 
    }, 
    "home_ownership": [{"id":6006371327132,"name":"Renters"}], 
    "interests": [{"id":6003107902433,"name":"Association football (Soccer)"}], 
    "life_events": [{"id":6002714398172,"name":"Newlywed (1 year)"}], 
    "publisher_platforms": ["facebook","audience_network"] 
  }' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/adsets

Within your UI, you will likely want to list all ad sets within a campaign. You can achieve this by making a request to the following path specifying the fields and statuses you want:

use FacebookAds\Object\Campaign;
use FacebookAds\Object\Fields\AdSetFields;

$campaign = new Campaign(<CAMPAIGN_ID>);
$adsets = $campaign->getAdSets(array(
  AdSetFields::NAME,
  AdSetFields::START_TIME,
  AdSetFields::END_TIME,
  AdSetFields::DAILY_BUDGET,
  AdSetFields::LIFETIME_BUDGET,
));
from facebookads.adobjects.campaign import Campaign
from facebookads.adobjects.adset import AdSet

campaign = Campaign(<CAMPAIGN_ID>)
ads = campaign.get_ad_sets(fields=[
    AdSet.Field.name,
    AdSet.Field.start_time,
    AdSet.Field.end_time,
    AdSet.Field.daily_budget,
    AdSet.Field.lifetime_budget,
])
APINodeList<AdSet> adSets = new Campaign(<CAMPAIGN_ID>, context).getAdSets()
  .requestNameField()
  .requestStartTimeField()
  .requestEndTimeField()
  .requestDailyBudgetField()
  .requestLifetimeBudgetField()
  .execute();
curl -G \
  -d 'fields=name,start_time,end_time,daily_budget,lifetime_budget' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/<CAMPAIGN_ID>/adsets

Ads

An ad object contains all of the information neccessary to display an ad on Facebook, such as the creative.

use FacebookAds\Object\Ad;
use FacebookAds\Object\Fields\AdFields;

$data = array(
  AdFields::NAME => 'My Ad',
  AdFields::ADSET_ID => <AD_SET_ID>,
  AdFields::CREATIVE => array(
    'creative_id' => <CREATIVE_ID>,
  ),
);

$ad = new Ad(null, 'act_<AD_ACCOUNT_ID>');
$ad->setData($data);
$ad->create(array(
  Ad::STATUS_PARAM_NAME => Ad::STATUS_PAUSED,
));
from facebookads.adobjects.ad import Ad

ad = Ad(parent_id='act_<AD_ACCOUNT_ID>')
ad[Ad.Field.name] = 'My Ad'
ad[Ad.Field.adset_id] = <AD_SET_ID>
ad[Ad.Field.creative] = {
    'creative_id': <CREATIVE_ID>,
}
ad.remote_create(params={
    'status': Ad.Status.paused,
})
Ad ad = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAd()
  .setName("My Ad")
  .setAdsetId(<AD_SET_ID>)
  .setCreative(
    new AdCreative()
      .setFieldId(<CREATIVE_ID>)
  )
  .setStatus(Ad.EnumStatus.VALUE_PAUSED)
  .execute();
curl \
  -F 'name=My Ad' \
  -F 'adset_id=<AD_SET_ID>' \
  -F 'creative={"creative_id":"<CREATIVE_ID>"}' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/ads

To see a preview of your ad, see the creative guide.

Finally, you will want to list all of the ads for an ad set within your UI. To do this, you can make a request to the following path, specifying the fields you want to retrieve:

use FacebookAds\Object\AdSet;
use FacebookAds\Object\Values\ArchivableCrudObjectEffectiveStatuses;
use FacebookAds\Object\Fields\AdFields;

$adset = new AdSet(<AD_SET_ID>);
$ads = $adset->getAds(array(
  AdFields::NAME,
  AdFields::CONFIGURED_STATUS,
  AdFields::EFFECTIVE_STATUS,
  AdFields::CREATIVE,
), array(
  AdFields::EFFECTIVE_STATUS => array(
    ArchivableCrudObjectEffectiveStatuses::ACTIVE,
    ArchivableCrudObjectEffectiveStatuses::PAUSED,
    ArchivableCrudObjectEffectiveStatuses::PENDING_REVIEW,
    ArchivableCrudObjectEffectiveStatuses::PREAPPROVED,
  ),
));
from facebookads.adobjects.adset import AdSet
from facebookads.adobjects.ad import Ad

fields = [
    Ad.Field.name,
    Ad.Field.configured_status,
    Ad.Field.effective_status,
    Ad.Field.creative,
]

params = {
    Ad.Field.effective_status: [
        'ACTIVE',
        'PAUSED',
        'PENDING_REVIEW',
        'PREAPPROVED',
    ],
}

ad_set = AdSet(<AD_SET_ID>)
ads = ad_set.get_ads(fields=fields, params=params)
APINodeList<Ad> ads = new AdSet(<AD_SET_ID>, context).getAds()
  .setEffectiveStatus("[\"ACTIVE\",\"PAUSED\",\"PENDING_REVIEW\",\"PREAPPROVED\"]")
  .requestNameField()
  .requestConfiguredStatusField()
  .requestEffectiveStatusField()
  .requestCreativeField()
  .execute();
curl -G \
  --data-urlencode 'effective_status=[ 
    "ACTIVE", 
    "PAUSED", 
    "PENDING_REVIEW", 
    "PREAPPROVED" 
  ]' \
  -d 'fields=name,configured_status,effective_status,creative' \
  -d 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/<AD_SET_ID>/ads

You may find the total number of ads is greater than the number you want to show on a single page. In this case you should specify the limit field as the number of items you want to retrieve and then paginate through the remaining items.

Pagination is performed using the cursors returned as part of the response:

"paging": {
  "previous" : "https://graph.facebook.com/...",
  "next": "https://graph.facebook.com/...", 
  "cursors": {
    "before": "NjAxNjc3NTU1ODMyNw==", 
    "after": "NjAxMTc0NTU2MjcyNw=="
  }

In the case that there are additional pages to retrieve, the response will include the previous and next fields in the response, and these URLs can be called to retrieve these pages of data. Read more about cursor-based pagination in our developer documentation.

Learn more about Facebook's ad campaign structure here.

Objectives

Objectives are actions you want people to make when they see the ad and objects are what people act upon. See Help Center.

Setting Objectives

After you create new campaign, ad set, ad, and ad creative objects, provide the required fields for each object creation. The minimum API call needed to create a campaign:

use FacebookAds\Object\Campaign;
use FacebookAds\Object\Fields\CampaignFields;

$campaign = new Campaign(null, 'act_<AD_ACCOUNT_ID>');

$campaign->setData(array(
  CampaignFields::NAME => 'My First Campaign',
  CampaignFields::OBJECTIVE => '<OBJECTIVE>',
));

$campaign->create(array(
  Campaign::STATUS_PARAM_NAME => Campaign::STATUS_PAUSED,
));
from facebookads.adobjects.campaign import Campaign

campaign = Campaign(parent_id='act_<AD_ACCOUNT_ID>')
campaign.update({
    Campaign.Field.name: 'My First Campaign',
    Campaign.Field.objective: '<OBJECTIVE>',
})

campaign.remote_create(params={
    'status': Campaign.Status.paused,
})
print(campaign)
Campaign campaign = new AdAccount(act_<AD_ACCOUNT_ID>, context).createCampaign()
  .setName("My First Campaign")
  .setObjective(<OBJECTIVE>)
  .setStatus(Campaign.EnumStatus.VALUE_PAUSED)
  .execute();
String campaign_id = campaign.getId();
curl \
  -F 'name=My First Campaign' \
  -F 'objective=<OBJECTIVE>' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/campaigns

Explicitly setting the objective has the following benefits:

  • You get correct tracking, optimization, and bidding options for your ad.
  • You can view unique UI and analytics dashboards for each objective

See campaign for acceptable values for the objective parameter. For this example, let's choose POST_ENGAGEMENT:

use FacebookAds\Object\Campaign;
use FacebookAds\Object\Fields\CampaignFields;
use FacebookAds\Object\Values\CampaignObjectiveValues;

$campaign = new Campaign(null, 'act_<AD_ACCOUNT_ID>');

$campaign->setData(array(
  CampaignFields::NAME => 'My First Campaign',
  CampaignFields::OBJECTIVE => CampaignObjectiveValues::POST_ENGAGEMENT,
));

$campaign->create(array(
  Campaign::STATUS_PARAM_NAME => Campaign::STATUS_PAUSED,
));
from facebookads.adobjects.campaign import Campaign

campaign = Campaign(parent_id='act_<AD_ACCOUNT_ID>')
campaign.update({
    Campaign.Field.name: 'My First Campaign',
    Campaign.Field.objective: Campaign.Objective.post_engagement,
})

campaign.remote_create(params={
    'status': Campaign.Status.paused,
})
print(campaign)
Campaign campaign = new AdAccount(act_<AD_ACCOUNT_ID>, context).createCampaign()
  .setName("My First Campaign")
  .setObjective(Campaign.EnumObjective.VALUE_POST_ENGAGEMENT)
  .setStatus(Campaign.EnumStatus.VALUE_PAUSED)
  .execute();
String campaign_id = campaign.getId();
curl \
  -F 'name=My First Campaign' \
  -F 'objective=POST_ENGAGEMENT' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.9/act_<AD_ACCOUNT_ID>/campaigns

Reference