Create your first ad with the Marketing API by following these steps.
You should get familiar with the Graph API and Facebook's Ad Campaign Structure . Once you are ready to start making calls, you need:
After that, you can get started. Don't forget to check general best practices for using the Marketing API.
Start the process creating a new campaign object from the class Campaign
. At this stage, you need to set an objective for your ads, which is the overall goal of your campaign. We recommend that you create a PAUSED
campaign initially, so you do not get billed while testing.
curl -X POST \
-F 'name="My campaign"' \
-F 'objective="OUTCOME_TRAFFIC"' \
-F 'status="PAUSED"' \
-F 'special_ad_categories=[]' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v20.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' : 'OUTCOME_TRAFFIC',
'status' : 'PAUSED',
'special_ad_categories' : [],
};
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' => 'OUTCOME_TRAFFIC',
'status' => 'PAUSED',
'special_ad_categories' => array(),
);
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': 'OUTCOME_TRAFFIC',
'status': 'PAUSED',
'special_ad_categories': [],
}
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_OUTCOME_TRAFFIC)
.setStatus(Campaign.EnumStatus.VALUE_PAUSED)
.setParam(\"special_ad_categories\", \"[]\")
.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: 'OUTCOME_TRAFFIC',
status: 'PAUSED',
special_ad_categories: [],
})
On success, we return an ID for your newly created ad campaign. Remember to save this ID. You can also verify your campaign has been created in ads manager .
Before moving to create your ad sets, you need to define your target audience. In the next step, you create an ad set and specify your audience's attributes.
You have many targeting options . In this example, we use targeting search to find predefined values that can be used to set up an audience.
First, let's look for available countries including the word "united":
curl -G \ -d 'location_types=["country"]' \ -d 'type=adgeolocation' \ -d 'q=united' \ -d 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v<API_VERSION>/search Open In Graph API Explorer Open In Postman
Then, we can look for interests including the word "movie":
curl -G \ -d 'type=adinterest' \ -d 'q=movie' \ -d 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v<API_VERSION>/search
Based on the values returned from the calls above, we know that we can create an audience of people in the United States that are interested in movies. The targeting spec looks like this:
targeting={ "geo_locations": {"countries":["US"]}, "interests": [{id: 6003139266461, 'name': 'Movies'}] }
An ad set is a group of ads that share the same daily or lifetime budget, schedule, billing, optimization, and targeting data. In this step, you need to create a new object from the class AdSet
and specify:
start_time
and end_time
.daily_budget
or lifetime_budget
.optimization_goal
.billing_event
.bid_amount
field.To create your ad set, you also need the ad campaign ID you saved from Step 1:
curl -X POST \
-F 'name="My Reach 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"
]
}' \
-F 'status="PAUSED"' \
-F 'promoted_object={
"page_id": "<PAGE_ID>"
}' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v20.0/act_<AD_ACCOUNT_ID>/adsets
'use strict';
const bizSdk = require('facebook-nodejs-business-sdk');
const AdAccount = bizSdk.AdAccount;
const AdSet = bizSdk.AdSet;
const access_token = '<ACCESS_TOKEN>';
const app_secret = '<APP_SECRET>';
const app_id = '<APP_ID>';
const id = '<AD_ACCOUNT_ID>';
const api = bizSdk.FacebookAdsApi.init(access_token);
const showDebugingInfo = true; // Setting this to true shows more debugging info.
if (showDebugingInfo) {
api.setDebug(true);
}
const logApiCallResult = (apiCallName, data) => {
console.log(apiCallName);
if (showDebugingInfo) {
console.log('Data:' + JSON.stringify(data));
}
};
let fields, params;
fields = [
];
params = {
'name' : 'My Reach Ad Set',
'optimization_goal' : 'REACH',
'billing_event' : 'IMPRESSIONS',
'bid_amount' : '2',
'daily_budget' : '1000',
'campaign_id' : '<adCampaignLinkClicksID>',
'targeting' : {'geo_locations':{'countries':['US']},'facebook_positions':['feed']},
'status' : 'PAUSED',
'promoted_object' : {'page_id':'<pageID>'},
};
const adsets = (new AdAccount(id)).createAdSet(
fields,
params
);
logApiCallResult('adsets api call complete.', adsets);
require __DIR__ . '/vendor/autoload.php';
use FacebookAds\Object\AdAccount;
use FacebookAds\Object\AdSet;
use FacebookAds\Api;
use FacebookAds\Logger\CurlLogger;
$access_token = '<ACCESS_TOKEN>';
$app_secret = '<APP_SECRET>';
$app_id = '<APP_ID>';
$id = '<AD_ACCOUNT_ID>';
$api = Api::init($app_id, $app_secret, $access_token);
$api->setLogger(new CurlLogger());
$fields = array(
);
$params = array(
'name' => 'My Reach Ad Set',
'optimization_goal' => 'REACH',
'billing_event' => 'IMPRESSIONS',
'bid_amount' => '2',
'daily_budget' => '1000',
'campaign_id' => '<adCampaignLinkClicksID>',
'targeting' => array('geo_locations' => array('countries' => array('US')),'facebook_positions' => array('feed')),
'status' => 'PAUSED',
'promoted_object' => array('page_id' => '<pageID>'),
);
echo json_encode((new AdAccount($id))->createAdSet(
$fields,
$params
)->exportAllData(), JSON_PRETTY_PRINT);
from facebook_business.adobjects.adaccount import AdAccount
from facebook_business.adobjects.adset import AdSet
from facebook_business.api import FacebookAdsApi
access_token = '<ACCESS_TOKEN>'
app_secret = '<APP_SECRET>'
app_id = '<APP_ID>'
id = '<AD_ACCOUNT_ID>'
FacebookAdsApi.init(access_token=access_token)
fields = [
]
params = {
'name': 'My Reach Ad Set',
'optimization_goal': 'REACH',
'billing_event': 'IMPRESSIONS',
'bid_amount': '2',
'daily_budget': '1000',
'campaign_id': '<adCampaignLinkClicksID>',
'targeting': {'geo_locations':{'countries':['US']},'facebook_positions':['feed']},
'status': 'PAUSED',
'promoted_object': {'page_id':'<pageID>'},
}
print AdAccount(id).create_ad_set(
fields=fields,
params=params,
)
import com.facebook.ads.sdk.*;
import java.io.File;
import java.util.Arrays;
public class SAMPLE_CODE_EXAMPLE {
public static void main (String args[]) throws APIException {
String access_token = \"<ACCESS_TOKEN>\";
String app_secret = \"<APP_SECRET>\";
String app_id = \"<APP_ID>\";
String id = \"<AD_ACCOUNT_ID>\";
APIContext context = new APIContext(access_token).enableDebug(true);
new AdAccount(id, context).createAdSet()
.setName(\"My Reach Ad Set\")
.setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_REACH)
.setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
.setBidAmount(2L)
.setDailyBudget(1000L)
.setCampaignId(\"<adCampaignLinkClicksID>\")
.setTargeting(
new Targeting()
.setFieldFacebookPositions(Arrays.asList(\"feed\"))
.setFieldGeoLocations(
new TargetingGeoLocation()
.setFieldCountries(Arrays.asList(\"US\"))
)
)
.setStatus(AdSet.EnumStatus.VALUE_PAUSED)
.setPromotedObject(\"{\\"page_id\\":\\"<pageID>\\"}\")
.execute();
}
}
require 'facebook_ads'
access_token = '<ACCESS_TOKEN>'
app_secret = '<APP_SECRET>'
app_id = '<APP_ID>'
id = '<AD_ACCOUNT_ID>'
FacebookAds.configure do |config|
config.access_token = access_token
config.app_secret = app_secret
end
ad_account = FacebookAds::AdAccount.get(id)
adsets = ad_account.adsets.create({
name: 'My Reach Ad Set',
optimization_goal: 'REACH',
billing_event: 'IMPRESSIONS',
bid_amount: '2',
daily_budget: '1000',
campaign_id: '<adCampaignLinkClicksID>',
targeting: {'geo_locations':{'countries':['US']},'facebook_positions':['feed']},
status: 'PAUSED',
promoted_object: {'page_id':'<pageID>'},
})
We recommend the creation of an ad set with the PAUSED
status to avoid charges during your test.
In this step, you will use the AdCreative
object to provide the visual elements of your ad. The information you need to provide depends on your objective, but common attributes are:
Depending on your objective you may have to provide advanced fields. For example, ads for an iOS app require an app store URL.
You can define creative as part of an ad set or standalone. In either case, we store your ad creative in your ad account's creative library to use in ads.
This example shows how to provide an image and create the AdCreative
object.
First, create an AdImage
object from an image file:
curl \ -F 'filename=@<IMAGE_PATH>' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v<API_VERSION>/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 'degrees_of_freedom_spec={ "creative_features_spec": { "standard_enhancements": { "enroll_status": "OPT_IN" } } }' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v<API_VERSION>/act_<AD_ACCOUNT_ID>/adcreatives Open In Graph API Explorer Open In Postman
Verify your image upload by going to your Media Libraryinside ads manager .
At this point, the AdCreative
with your link is not yet visible in Ads Manager. You see this data once you book your ad. You can debug your ad creative with Graph API Explorer
and specify any fields you want to read:
GET /{my-creative-id} HTTP/1.1
Host: graph.facebook.com/?fields=object_story_spec
Finally, create your Ad
object to link your AdCreative
and AdSet
. Set the status
of your Ad
to paused
to 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/v20.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 in the ads manager . Click on the campaign you just created, then on the ad set, and on the ad.
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
. Once the review is done, it goes back to the status of ACTIVE
.
Alternatively, you can copy an existing ad, asset or campaign. It helps you quickly duplicate a campaign to change configurations or create test groups to extract performance knowledge. For more details, see: