The Facebook Pixel is the main tool you can use to track events on a website. You can then use data from the pixel with Marketing API to:
Due to the changes for iOS 14+, we have introduced a new tool for tracking web events for iOS 14+ ad campaigns.
Facebook’s Aggregated Event Measurement is a protocol that allows for measurement of web events from iOS 14 users. Aggregated Event Measurement limits domains to 8 conversion events that can be used for campaign optimization.
Visit our Domain Verification guide to verify your domain ownership for Aggregated Event Measurement.
Visit our Business Help Center to learn more.
Visit our Changelog for more information about other changes available.
If a pixel exists for an ad account, get the code with Marketing API with an HTTP GET
to https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/adspixels
. For example:
The response contains the code
parameter containing the actual code. <PIXEL_ID>
is your pixel id. When you copy the code above, replace <PIXEL_ID>
with your own Facebook pixel id. Now you can add the pixel code to your website.
name | description | type |
---|---|---|
code | Pixel code | string |
You should use the JavaScript code for Facebook Pixel. In some cases, you may use an HTML or an image pixel then add another 3rd-party tag from your website. The image pixel looks like this:
<img src="https://www.facebook.com/tr?id=<PIXEL_ID>&ev=PageView&noscript=1" height="1" width="1" style="display:none"/>
Replace <PIXEL_ID>
with your Facebook pixel ID.
Track different pixels by providing the pixel id in an ad's tracking specs. For tracking conversions, set tracking specs to:
// tracking spec to match website actions from Facebook pixel {"action.type":["offsite_conversion"],"fb_pixel":[<fb_pixel_id>]}
This tracks the performance and activity for all standard events. To track a Facebook pixel without optimizing for conversion, set tracking_specs
at the ad level:
use FacebookAds\Object\Ad;
use FacebookAds\Object\Fields\AdFields;
$ad = new Ad(null, 'act_<AD_ACCOUNT_ID>');
$ad->setData(array(
AdFields::ADSET_ID => <AD_SET_ID>,
AdFields::CREATIVE => array(
'creative_id' => <CREATIVE_ID>,
),
AdFields::NAME => 'Offsite Conversions Ad',
AdFields::TRACKING_SPECS => array(array(
'action.type' => 'offsite_conversion',
'fb_pixel' => <PIXEL_ID>,
)),
));
$ad->create();
from facebookads.adobjects.ad import Ad
ad = Ad(parent_id='act_<AD_ACCOUNT_ID>')
ad.update({
Ad.Field.adset_id: <AD_SET_ID>,
Ad.Field.name: 'Offsite Conversions Ad',
Ad.Field.creative: {
'creative_id': <CREATIVE_ID>,
},
Ad.Field.tracking_specs: [
{
'action.type': 'offsite_conversion',
'fb_pixel': <PIXEL_ID>,
},
],
})
ad.remote_create(params={
'status': Ad.Status.paused,
})
Ad ad = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAd()
.setAdsetId(<AD_SET_ID>)
.setCreative(
new AdCreative()
.setFieldId(<CREATIVE_ID>)
)
.setName("Offsite Conversions Ad")
.setTrackingSpecs("{\"action.type\":\"offsite_conversion\",\"fb_pixel\":\"" + <PIXEL_ID> + "\"}")
.execute();
String ad_id = ad.getId();
curl \
-F 'adset_id=<AD_SET_ID>' \
-F 'creative={"creative_id":"<CREATIVE_ID>"}' \
-F 'name=Offsite Conversions Ad' \
-F 'tracking_specs=[{"action.type":"offsite_conversion","fb_pixel":"<PIXEL_ID>"}]' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/act_<AD_ACCOUNT_ID>/ads
You can share pixels between businesses and ad accounts, so you ususally need only one. You can also use an existing pixel rather than creating a new one. You only need to create new pixels via API if you develop ads management software and enable people to create their own Facebook pixels in your. To create a pixel, HTTP POST
to https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/adspixels
.
The response has the pixel ID:
{ "id": "11111" }
Use these fields:
name | description | type |
---|---|---|
name | Name of your pixel | string |
To install your pixel, see Facebook Pixel, Using the Pixel. After you confirm the pixel and standard events work, remove existing Conversion Tracking pixels and Custom Audience pixels from your website.
You can send additional customer data through the pixel and match more website actions with people on Facebook. See Advanced Matching.
Reporting ViewContent
standard event with parameters
fbq('track', 'ViewContent', { content_type: 'product', content_ids: ['1234'], content_name: 'ABC Leather Sandal', content_category: 'Shoes' value: 0.50, currency: 'USD' });
Reporting ViewContent
with the img pixel
<img src="https://www.facebook.com/tr?id=<PIXEL_ID>&ev=ViewContent&cd[content_name]=ABC%20Leather%20Sandal&cd[content_category]=Shoes&cd[content_type]=product&cd[content_ids]=1234&cd[value]=0.50&cd[currency]=USD&noscript=1" height="1" width="1" style="display:none"/>
Reporting Purchase
with additional product information
fbq('track', 'Purchase', { content_type: 'product', contents: [ { 'id': '1234', 'quantity': 2, }, { 'id': '4642', 'quantity': 1, } ], value: 25.00, currency: 'USD' });
Report a Search event
fbq('track', 'Search', { search_string: 'leather sandals', content_category: 'Product Search', content_ids: ['1234', '2424', '1318', '6832'], value: 0.50, currency: 'USD' });
Report a Lead event
fbq('track', 'Lead', { content_name: 'Auto Insurance', content_category: 'Quote', value: 40.00, currency: 'USD' });
Report a custom event
fbq('trackCustom', '<CustomEventName>', { custom_param1: 'ABC', custom_param2: 123, value: 10.00, currency: 'USD' });
Report a custom event from a specific pixel. The trackSingleCustom
method does not validate custom data.
<script> function onClick() { fbq('trackSingleCustom', '<PIXEL_ID>', 'PageView'); }; </script>
Report a custom event via img pixel
<img src="https://www.facebook.com/tr?id=<PIXEL_ID>&ev=CustomEventName&cd[custom_param1]=ABC&cd[custom_param2]=123&cd[value]=10.00&cd[currency]=USD&noscript=1" height="1" width="1" style="display:none"/>
To suppress pixel being fired via pushState
or replaceState
:
fbq.disablePushState = true;
After you install the pixel track in-page actions, such as product purchases, by tying events to HTML elements such as buttons. For example:
<button onClick="fbq('track', 'Purchase');">Button Text</button>
Or you could create a function that pushes the event. The advantage is if you have multiple HTML elements, you can call a single function when someone clicks any of them; you don't have to define individual onClick
element.
For example, to push the event:
<script> function onClick() { fbq('track', 'Purchase'); }; </script>
You can call this function to fire Purchase events from multiple HTML elements. For example:
<button onClick="onClick()">Buy Now</button> <button onClick="onClick()">Buy as a Gift</button>
Note: Pixel Helper may show multiple pixel events firing from the same page. The Pixel Helper expects pages to fire only on load but by tying events to elements, such as a button, you are using an alternative solution that overturns the expected behavior.
To optimize ad delivery for conversions based on standard events:
promoted_object
, conversion_specs
are automatically inferred based on the objective and promoted_object
. You cannot manually set conversion_specs
:// optimize for Purchase standard event. "promoted_object" : {'pixel_id':<FB_PIXEL_ID>, 'custom_event_type':'PURCHASE'}
See the list of standard events where custom_event_type
can have values, depending on the standard event.
To create an oCPM adset optimizing for Purchase events:
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 => 'Ad Set oCPM',
AdSetFields::BID_AMOUNT => 150,
AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
AdSetFields::OPTIMIZATION_GOAL =>
AdSetOptimizationGoalValues::OFFSITE_CONVERSIONS,
AdSetFields::PROMOTED_OBJECT => array(
'pixel_id' => <PIXEL_ID>,
'custom_event_type' => 'PURCHASE',
),
AdSetFields::DAILY_BUDGET => 1000,
AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
AdSetFields::TARGETING => (new Targeting())->setData(array(
TargetingFields::GEO_LOCATIONS => array(
'countries' => array('US'),
),
)),
));
$adset->create(array(
AdSet::STATUS_PARAM_NAME => AdSet::STATUS_PAUSED,
));
from facebookads.adobjects.adset import AdSet
from facebookads.adobjects.targeting import Targeting
adset = AdSet(parent_id='act_<AD_ACCOUNT_ID>')
adset.update({
AdSet.Field.name: 'Ad Set oCPM',
AdSet.Field.bid_amount: 150,
AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
AdSet.Field.optimization_goal: AdSet.OptimizationGoal.offsite_conversions,
AdSet.Field.promoted_object: {
'pixel_id': <PIXEL_ID>,
'custom_event_type': 'PURCHASE',
},
AdSet.Field.daily_budget: 1000,
AdSet.Field.campaign_id: <CAMPAIGN_ID>,
AdSet.Field.targeting: {
Targeting.Field.geo_locations: {
'countries': ['US'],
},
},
})
adset.remote_create(params={
'status': AdSet.Status.paused,
})
print(adset)
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
.setName("Ad Set oCPM")
.setBidAmount(150L)
.setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
.setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_OFFSITE_CONVERSIONS)
.setPromotedObject("{\"pixel_id\":\"" + <PIXEL_ID> + "\",\"custom_event_type\":\"PURCHASE\"}")
.setDailyBudget(1000L)
.setCampaignId(<CAMPAIGN_ID>)
.setTargeting(
new Targeting()
.setFieldGeoLocations(
new TargetingGeoLocation()
.setFieldCountries(Arrays.asList("US"))
)
)
.setStatus(AdSet.EnumStatus.VALUE_PAUSED)
.execute();
String ad_set_id = adSet.getId();
curl \
-F 'name=Ad Set oCPM' \
-F 'bid_amount=150' \
-F 'billing_event=IMPRESSIONS' \
-F 'optimization_goal=OFFSITE_CONVERSIONS' \
-F 'promoted_object={"pixel_id":"<PIXEL_ID>","custom_event_type":"PURCHASE"}' \
-F 'daily_budget=1000' \
-F 'campaign_id=<CAMPAIGN_ID>' \
-F 'targeting={"geo_locations":{"countries":["US"]}}' \
-F 'status=PAUSED' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/act_<AD_ACCOUNT_ID>/adsets
Optimize the delivery of your ads based on a valued goal, such as purchase value, if you configure your pixel to send purchase values. To use value optimization:
VALUE
.IMPRESSIONS
.custom_event_type
to PURCHASE
.is_autobid
to true
.7-day
or 1-day
.Example:
curl \ -F 'name=Ad Set Value Optimization' \ -F 'is_autobid=true' \ -F 'billing_event=IMPRESSIONS' \ -F 'optimization_goal=VALUE' \ -F 'promoted_object={"pixel_id":"<PIXEL_ID>","custom_event_type":"PURCHASE"}' \ -F 'daily_budget=1000' \ -F 'campaign_id=<CAMPAIGN_ID>' \ -F "attribution_spec=[{'event_type': 'CLICK_THROUGH', 'window_days':'1'}]" \ -F 'targeting={"geo_locations":{"countries":["US"]}}' \ -F 'status=PAUSED' \ -F 'access_token=<ACCESS_TOKEN>' \ https://graph.facebook.com/v2.10/act_<AD_ACCOUNT_ID>/adsets
You can share your Facebook pixel with your own ad accounts and with other businesses via Business Manager. You must be an admin of the business. To share a pixel:
To list your own ad accounts your pixel is shared with:
use FacebookAds\Object\AdsPixel;
$pixel = new AdsPixel(<PIXEL_ID>, $ad_account_id);
$shared_accounts = $pixel->getSharedAccounts(
array(),
array(
'business' => '<BUSINESS_ID>',
));
foreach ($shared_accounts as $shared_account) {
echo $shared_account->{AdAccountFields::ID}.PHP_EOL;
}
from facebookads.adobjects.adspixel import AdsPixel
from facebookads.adobjects.adaccount import AdAccount
pixel = AdsPixel(<PIXEL_ID>)
shared_accounts = pixel.get_ad_accounts('<BUSINESS_ID>')
for shared_account in shared_accounts:
print(shared_account[AdAccount.Field.id])
APINodeList<AdAccount> adAccounts = new AdsPixel(<PIXEL_ID>, context).getSharedAccounts()
.setBusiness(<BUSINESS_ID>)
.execute();
curl -G \
-d 'business=<BUSINESS_ID>' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/<PIXEL_ID>/shared_accounts
To unshare a pixel:
use FacebookAds\Object\AdsPixel;
$pixel = new AdsPixel(<PIXEL_ID>);
// ad account id without 'act_'
$pixel->unsharePixelWithAdAccount(<BUSINESS_ID>, <ACCOUNT_ID>);
from facebookads.adobjects.adspixel import AdsPixel
pixel = AdsPixel(<PIXEL_ID>)
pixel.unshare_pixel_from_ad_account(<BUSINESS_ID>, <ACCOUNT_ID>)
curl -X DELETE \
-d 'business=<BUSINESS_ID>' \
-d 'account_id=<ACCOUNT_ID>' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/<PIXEL_ID>/shared_accounts
You can share your pixel with other businesses too. You can only share pixels created by your business. Once you share your pixel with another business, they cannot share it further. They can only assign their ad accounts to your pixel. To share a pixel with another business or agency:
use FacebookAds\Object\AdsPixel;
$pixel = new AdsPixel(<PIXEL_ID>);
$pixel->sharePixelWithAgency(<BUSINESS_ID>, <AGENCY_ID>);
from facebookads.adobjects.adspixel import AdsPixel
pixel = AdsPixel(<PIXEL_ID>)
response = pixel.share_pixel_with_agency(<BUSINESS_ID>, <AGENCY_ID>)
print(response.body())
curl \
-F 'business=<BUSINESS_ID>' \
-F 'agency_id=<AGENCY_ID>' \
-F 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/<PIXEL_ID>/shared_agencies
To list ad accounts that a business assigned to your pixel:
use FacebookAds\Object\AdsPixel;
$pixel = new AdsPixel(<PIXEL_ID>, $ad_account_id);
$shared_accounts = $pixel->getSharedAccounts(
array(),
array(
'business' => '<BUSINESS_ID>',
));
foreach ($shared_accounts as $shared_account) {
echo $shared_account->{AdAccountFields::ID}.PHP_EOL;
}
from facebookads.adobjects.adspixel import AdsPixel
from facebookads.adobjects.adaccount import AdAccount
pixel = AdsPixel(<PIXEL_ID>)
shared_accounts = pixel.get_ad_accounts('<BUSINESS_ID>')
for shared_account in shared_accounts:
print(shared_account[AdAccount.Field.id])
APINodeList<AdAccount> adAccounts = new AdsPixel(<PIXEL_ID>, context).getSharedAccounts()
.setBusiness(<BUSINESS_ID>)
.execute();
curl -G \
-d 'business=<BUSINESS_ID>' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/<PIXEL_ID>/shared_accounts
To unshare a pixel from a business, use a DELETE
:
use FacebookAds\Object\AdsPixel;
$pixel = new AdsPixel(<PIXEL_ID>);
$pixel->unsharePixelWithAgency(<BUSINESS_ID>, <AGENCY_ID>);
from facebookads.adobjects.adspixel import AdsPixel
pixel = AdsPixel(<PIXEL_ID>)
fixtures.unshare_pixel_from_agency(<PIXEL_ID>, <BUSINESS_ID>, <AGENCY_ID>)
curl -X DELETE \
-d 'business=<BUSINESS_ID>' \
-d 'agency_id=<AGENCY_ID>' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/<PIXEL_ID>/shared_agencies
Use Pixel Stats edge for more information. To read custom data stats for 'product_info'
, between two UNIX timestamps:
use FacebookAds\Object\AdsPixel;
$pixel = new AdsPixel(<PIXEL_ID>);
$pixel->getStats(array(), array(
'aggregation' => 'custom_data_field',
'event' => 'product_info',
'start_time' => (new \DateTime("-1 week"))->getTimestamp(),
'end_time' => (new \DateTime("now"))->getTimestamp(),
));
from facebookads.adobjects.adspixel import AdsPixel
import time
pixel = AdsPixel(<PIXEL_ID>)
pixel.get_stats(params={
'aggregation': 'custom_data_field',
'event': 'product_info',
'start_time': int(time.time()) - 3600 * 24 * 7,
'end_time': int(time.time()),
})
APINodeList<AdsPixelStatsResult> adsPixelStatsResults = new AdsPixel(<PIXEL_ID>, context).getStats()
.setAggregation(AdsPixelStatsResult.EnumAggregation.VALUE_CUSTOM_DATA_FIELD)
.setEvent("product_info")
.setStartTime(start_time)
.setEndTime("1469739348")
.execute();
curl -G \
-d 'aggregation=custom_data_field' \
-d 'event=product_info' \
-d 'start_time=1516682708' \
-d 'end_time=1517287508' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/<PIXEL_ID>/stats
The response:
"data": [ { "aggregation": "custom_data_field", "timestamp": "2014-06-16T13:00:00", "data": [ { "value": "product", "count": 3212 }, { "value": "price", "count": 3212 }, { "value": "sale", "count": 12 } ] }, { "aggregation": "custom_data_field", "timestamp": "2014-06-16T14:00:00", "data": [ { "value": "product", "count": 1232 }, { "value": "price", "count": 1232 }, { "value": "sale", "count": 321 } ] ...
To read device type stats for the past 24 hours:
use FacebookAds\Object\AdsPixel;
$pixel = new AdsPixel(<PIXEL_ID>);
$pixel->getStats(array(), array(
'aggregation' => 'device_type',
));
from facebookads.adobjects.adspixel import AdsPixel
pixel = AdsPixel(<PIXEL_ID>)
pixel.get_stats(params={
'aggregation': 'device_type',
})
APINodeList<AdsPixelStatsResult> adsPixelStatsResults = new AdsPixel(<PIXEL_ID>, context).getStats()
.setAggregation(AdsPixelStatsResult.EnumAggregation.VALUE_DEVICE_TYPE)
.execute();
curl -G \
-d 'aggregation=device_type' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.11/<PIXEL_ID>/stats
The response:
"data": [ { "aggregation": "device_type", "timestamp": "2014-07-17T18:00:00", "data": [ { "value": "desktop", "count": 208883 }, { "value": "mobile_iphone", "count": 61754 }, { "value": "mobile_android_phone", "count": 56152 }, { "value": "mobile_ipad", "count": 49282 }, { "value": "mobile_android_tablet", "count": 8382 }, { "value": "mobile_windows_phone", "count": 1570 }, { "value": "mobile_ipod", "count": 428 }, ...
To read the browser type stats for the past 24 hours:
curl \ -D 'access_token=__ACCESS_TOKEN__' \ -D 'aggregation=browser_type' \ 'https://graph.facebook.com/<API_VERSION>/<pixel_id>/stats'
The response:
"data": [ { "aggregation": "browser_type", "timestamp": "2014-07-17T18:00:00", "data": [ { "value": "Chrome 39", "count": 61507 }, { "value": "Firefox 35", "count": 12879 }, { "value": "IE 10", "count": 6677 }, { "value": "Chrome 37", "count": 6662 }, { "value": "Safari 8", "count": 3663 }, ...
You can use Marketing API to accept and check Facebook's Terms of Service for Custom Audiences, Moble Custom Audiences, Website Custom Audiences, and legacy Conversion Pixels. This API is currently under limited availability. Contact your Facebook Representative for access.
To check if your ad account can accept the Terms of Service via API, make a GET
to: ad_account_ID/customaudiencestos
In the reponse, check the type: custom_audience
and type: web_custom_audience
fields. To accept the Terms of Service for an ad account make a POST
request. To do this you need to be an ad account admininistrator or advertiser with ['MANAGE', 'ADVERTISE']
roles, not just an analyst. See Business Manager API, Permitted Roles. For example:
ad_account_ID/customaudiencestos?tos_id=custom_audience_tos
or:
ad_account_ID/customaudiencestos?tos_id=web_custom_audience_tos
To see if an ad account accepted the terms, make a GET
to:
ad_account_id? fields=tos_accepted
In the response check to see if it contains custom_audience_tos
, web_custom_audience_tos
, or similar:
{ "tos_accepted": { "web_custom_audience_tos": 1, "custom_audience_tos": 1 }, "id": “act_xxxxxxxxxxxx" }