Marketing API Quickstart

Create ad campaigns, provide bids for ads auction, and manage ad creative. Learn more about Facebook's Ad Campaign Structure.

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

Step 1: Create a Campaign

Reference Docs

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:

curl -X POST \ -F 'name="My campaign"' \ -F 'objective="LINK_CLICKS"' \ -F 'status="PAUSED"' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v4.0/act_<AD_ACCOUNT_ID>/campaigns
'use strict'; const bizSdk = require('facebook-nodejs-business-sdk'); const AdAccount = bizSdk.AdAccount; const Campaign = bizSdk.Campaign; 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 campaign', 'objective' : 'LINK_CLICKS', 'status' : 'PAUSED', }; const campaigns = (new AdAccount(id)).createCampaign( fields, params ); logApiCallResult('campaigns api call complete.', campaigns);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\Campaign; 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 campaign', 'objective' => 'LINK_CLICKS', 'status' => 'PAUSED', ); echo json_encode((new AdAccount($id))->createCampaign( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebook_business.adobjects.adaccount import AdAccount from facebook_business.adobjects.campaign import Campaign 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 campaign', 'objective': 'LINK_CLICKS', 'status': 'PAUSED', } print AdAccount(id).create_campaign( 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).createCampaign() .setName(\"My campaign\") .setObjective(Campaign.EnumObjective.VALUE_LINK_CLICKS) .setStatus(Campaign.EnumStatus.VALUE_PAUSED) .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) campaigns = ad_account.campaigns.create({ name: 'My campaign', objective: 'LINK_CLICKS', status: 'PAUSED', })

Verify Campaign Creation

Verify a campaign under Manage Ads in the ads manager.

Resources:

Step 2: Define Targeting

An ad set is a group of ads that share the same daily or lifetime budget, schedule, billing, optimization, and targeting data.

Before creating your ad set, you need to set your targeting specs. In the current step you define your target audience. In the next step, you create the ad set and specify its 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.11/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>,
}

Step 3: Define Budget, Billing, Optimization, and Duration

Reference Docs

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 occurring: bid_amount.

You can also manage 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.adset import AdSet

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

adset = AdSet(parent_id='act_<AD_ACCOUNT_ID>')
adset.update({
    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.remote_create(params={
    'status': AdSet.Status.paused,
})
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=2018-02-06T04:45:17+0000' \
  -F 'end_time=2018-02-13T04:45:17+0000' \
  -F 'status=PAUSED' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.11/act_<AD_ACCOUNT_ID>/adsets

Step 4: Provide Ad Creative

Reference Docs

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

  • One or more uploaded 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. For 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.11/act_<AD_ACCOUNT_ID>/adimages

Then, use the image hash to create the AdCreative:

curl -X POST \ -F 'name="Sample Creative"' \ -F 'object_story_spec={ "page_id": "<PAGE_ID>", "link_data": { "image_hash": "<IMAGE_HASH>", "link": "https://facebook.com/<PAGE_ID>", "message": "try it out" } }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v4.0/act_<AD_ACCOUNT_ID>/adcreatives
'use strict'; const bizSdk = require('facebook-nodejs-business-sdk'); const AdAccount = bizSdk.AdAccount; const AdCreative = bizSdk.AdCreative; const access_token = '<ACCESS_TOKEN>'; const app_secret = '<APP_SECRET>'; const app_id = '<APP_ID>'; const id = '<AD_ACCOUNT_ID>'; const api = bizSdk.FacebookAdsApi.init(access_token); const showDebugingInfo = true; // Setting this to true shows more debugging info. if (showDebugingInfo) { api.setDebug(true); } const logApiCallResult = (apiCallName, data) => { console.log(apiCallName); if (showDebugingInfo) { console.log('Data:' + JSON.stringify(data)); } }; let fields, params; fields = [ ]; params = { 'name' : 'Sample Creative', 'object_story_spec' : {'page_id':'<pageID>','link_data':{'image_hash':'<imageHash>','link':'https:\/\/facebook.com\/<pageID>','message':'try it out'}}, }; const adcreatives = (new AdAccount(id)).createAdCreative( fields, params ); logApiCallResult('adcreatives api call complete.', adcreatives);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\AdCreative; use FacebookAds\Api; use FacebookAds\Logger\CurlLogger; $access_token = '<ACCESS_TOKEN>'; $app_secret = '<APP_SECRET>'; $app_id = '<APP_ID>'; $id = '<AD_ACCOUNT_ID>'; $api = Api::init($app_id, $app_secret, $access_token); $api->setLogger(new CurlLogger()); $fields = array( ); $params = array( 'name' => 'Sample Creative', 'object_story_spec' => array('page_id' => '<pageID>','link_data' => array('image_hash' => '<imageHash>','link' => 'https:\/\/facebook.com\/<pageID>','message' => 'try it out')), ); echo json_encode((new AdAccount($id))->createAdCreative( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebook_business.adobjects.adaccount import AdAccount from facebook_business.adobjects.adcreative import AdCreative from facebook_business.api import FacebookAdsApi access_token = '<ACCESS_TOKEN>' app_secret = '<APP_SECRET>' app_id = '<APP_ID>' id = '<AD_ACCOUNT_ID>' FacebookAdsApi.init(access_token=access_token) fields = [ ] params = { 'name': 'Sample Creative', 'object_story_spec': {'page_id':'<pageID>','link_data':{'image_hash':'<imageHash>','link':'https:\/\/facebook.com\/<pageID>','message':'try it out'}}, } print AdAccount(id).create_ad_creative( fields=fields, params=params, )
import com.facebook.ads.sdk.*; import java.io.File; import java.util.Arrays; public class SAMPLE_CODE_EXAMPLE { public static void main (String args[]) throws APIException { String access_token = \"<ACCESS_TOKEN>\"; String app_secret = \"<APP_SECRET>\"; String app_id = \"<APP_ID>\"; String id = \"<AD_ACCOUNT_ID>\"; APIContext context = new APIContext(access_token).enableDebug(true); new AdAccount(id, context).createAdCreative() .setName(\"Sample Creative\") .setObjectStorySpec( new AdCreativeObjectStorySpec() .setFieldLinkData( new AdCreativeLinkData() .setFieldImageHash(\"<imageHash>\") .setFieldLink(\"https://facebook.com/<pageID>\") .setFieldMessage(\"try it out\") ) .setFieldPageId(\"<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) adcreatives = ad_account.adcreatives.create({ name: 'Sample Creative', object_story_spec: {'page_id':'<pageID>','link_data':{'image_hash':'<imageHash>','link':'https:\/\/facebook.com\/<pageID>','message':'try it out'}}, })

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

Step 5: Schedule Delivery

Reference Docs

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.

curl -X POST \ -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/v4.0/act_<AD_ACCOUNT_ID>/ads
'use strict'; const bizSdk = require('facebook-nodejs-business-sdk'); const AdAccount = bizSdk.AdAccount; const Ad = bizSdk.Ad; 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 Ad', 'adset_id' : '<adSetID>', 'creative' : {'creative_id':'<adCreativeID>'}, 'status' : 'PAUSED', }; const ads = (new AdAccount(id)).createAd( fields, params ); logApiCallResult('ads api call complete.', ads);
require __DIR__ . '/vendor/autoload.php'; use FacebookAds\Object\AdAccount; use FacebookAds\Object\Ad; 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 Ad', 'adset_id' => '<adSetID>', 'creative' => array('creative_id' => '<adCreativeID>'), 'status' => 'PAUSED', ); echo json_encode((new AdAccount($id))->createAd( $fields, $params )->exportAllData(), JSON_PRETTY_PRINT);
from facebook_business.adobjects.adaccount import AdAccount from facebook_business.adobjects.ad import Ad 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 Ad', 'adset_id': '<adSetID>', 'creative': {'creative_id':'<adCreativeID>'}, 'status': 'PAUSED', } print AdAccount(id).create_ad( 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).createAd() .setName(\"My Ad\") .setAdsetId(<adSetID>L) .setCreative( new AdCreative() .setFieldId(\"<adCreativeID>\") ) .setStatus(Ad.EnumStatus.VALUE_PAUSED) .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) ads = ad_account.ads.create({ name: 'My Ad', adset_id: '<adSetID>', creative: {'creative_id':'<adCreativeID>'}, status: 'PAUSED', })

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. First, the ad goes through ad review, and has the status PENDING_REVIEW. After it finishes review, it goes back to the status of ACTIVE.

Resources