Conversion Tracking and Pixel Stats

See how successful your ad is by reporting on conversion events such as checkouts on your website as direct responses to your ad. The pixel also tells Facebook to deliver your ad to people who are most likely to reach the checkout page of your website. With Facebook pixel and standard events, get metrics for all standard events on your website and optimize ad delivery for standard events.

Pixel Stats provide additional information about a pixel.

Pixel Tracking

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

Optimize for Conversions

To optimize ad delivery for conversions based on standard events:

  1. Define it in promoted_object on the ad set.
  2. Specify pixel id and the pixel event you want to optimize for. Once you set the 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'}

custom_event_type can have the following values depending on the standard event:

Standard Event Name Promoted Object custom_event_type value

ViewContent

CONTENT_VIEW

Search

SEARCH

AddToCart

ADD_TO_CART

AddToWishlist

ADD_TO_WISHLIST

InitiateCheckout

INITIATED_CHECKOUT

AddPaymentInfo

ADD_PAYMENT_INFO

Purchase

PURCHASE

Lead

LEAD

CompleteRegistration

COMPLETE_REGISTRATION

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.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: '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.Field.status: AdSet.Status.active,
}
adset = ad_account.create_ad_set(params=params)
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 for Purchase Value

This feature is available on a limited basis to whitelisted partners and advertisers. Contact your Facebook representative to use value optimization.

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:

  • Optimization Goal—Set to VALUE.
  • Billing Event—Set to IMPRESSIONS.
  • Promoted Object—Set custom_event_type to PURCHASE.
  • Bid Amount—Set is_autobid to true.
  • Attribution Window—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

Rule-Based Custom Conversions

Optimize for actions and track them without adding anything to your Facebook pixel base code. You can do this beyond the 9 standard events.

  1. Create a custom conversion at /{AD_ACCOUNT_ID}/customconversions.
  2. Specify a URL, or partial URL, representing an event in pixel_rule. For example, thankyou.html is a page appearing after purchase.

This records a PURCHASE conversion when 'thankyou.html' displays:

use FacebookAds\Object\CustomConversion;
use FacebookAds\Object\Fields\CustomConversionFields;

$custom_conversion = new CustomConversion(null, 'act_<AD_ACCOUNT_ID>');
$custom_conversion->setData(array(
  CustomConversionFields::NAME => 'Example Custom conversion',
  CustomConversionFields::PIXEL_ID => <PIXEL_ID>,
  CustomConversionFields::PIXEL_RULE => array(
    'url' => array('i_contains' => 'thank-you.html'),
  ),
  CustomConversionFields::CUSTOM_EVENT_TYPE => 'PURCHASE',
));
$custom_conversion->create();
from facebookads.adobjects.customconversion import CustomConversion

    custom_conversion = CustomConversion(parent_id='act_<AD_ACCOUNT_ID>')
    custom_conversion.update({
        CustomConversion.Field.name: 'Example Custom Conversion',
        CustomConversion.Field.pixel_id: <PIXEL_ID>,
        CustomConversion.Field.pixel_rule: {
            'url': {'i_contains': 'thankyou.html'},
        },
        CustomConversion.Field.custom_event_type: 'PURCHASE',
    })

    custom_conversion.remote_create()
curl \
  -F 'name=Example Custom conversion' \
  -F 'pixel_id=<PIXEL_ID>' \
  -F 'pixel_rule={"url":{"i_contains":"thank-you.html"}}' \
  -F 'custom_event_type=PURCHASE' \
  -F 'access_token=<ACCESS_TOKEN>' \
  https://graph.facebook.com/v2.8/act_<AD_ACCOUNT_ID>/customconversions

You can then create your campaign using the CONVERSIONS objective.

  1. At the ad set level, specify the same custom conversion (pixel_id, pixel_rule, custom_event_type) in promoted_object.

Custom Conversions Insights

Ads Insights returns information about Custom Conversions:

curl -i -G \
-d 'fields=actions,action_values' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.7/<AD_ID>/insights

Returns both standard and custom conversions:

{
  "data": [
    {
      "actions": [
        {
          "action_type": "offsite_conversion.custom.17067367629523",
          "value": 1225
        },
        {
          "action_type": "offsite_conversion.fb_pixel_purchase",
          "value": 205
        }
      ],
      "action_values": [
        {
          "action_type": "offsite_conversion.custom.1706736762929507",
          "value": 29390.89
        },
        {
          "action_type": "offsite_conversion.fb_pixel_purchase",
          "value": 29390.89
        }
      ],
      "date_start": "2016-07-28",
      "date_stop": "2016-08-26"
    }
  ],
  "paging": {
    "cursors": {
      "before": "MAZDZD",
      "after": "MjQZD"
    },
    "next": "https://graph.facebook.com/v2.7/<AD_ID>/insights?access_token=<ACCESS_TOKEN>&amp;pretty=0&amp;fields=actions%2Caction_values&amp;date_preset=last_30_days&amp;level=adset&amp;limit=25&amp;after=MjQZD"
  }
}

Custom conversions have unique IDs; query it for a specific conversion, such as a rule-based one:

curl -i -G \
-d 'fields=name,pixel,pixel_aggregation_rule' \
-d 'access_token=<ACCESS_TOKEN>' \
https://graph.facebook.com/v2.7/<CUSTOM_CONVERSION_ID>

Custom Conversions Limitations

The maximum number of custom conversions per ad account is 40. If you use Ads Insights API to get metrics on custom conversions:

  • Getting product ID breakdowns are not supported.
  • Getting unique action counts are not supported.

Pixel Statistics

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=1511833737' \
  -d 'end_time=1512438537' \
  -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
        }, 
        ...

Related Resources