Optimized Cost Per Mille Ads

Optimized Cost Per Mille (oCPM) allows you to prioritize your marketing goals, then automatically deliver ads towards these goals in the most effective way possible. Specify goals in absolute values, such as how much you value the fulfillment of a particular goal. These values are not bids. These values should be the value you place on an outcome.

An alternative to oCPM is Cost Per Action (CPA), which lets you specify conversion events and get charged by the amount of conversions. CPM and oCPM ads are different, since they charge per impressions served on the site.

How It Works

We automatically bid on your behalf, constrained by your defined campaign budget. The dynamic bids enable you to to capture the highest-value impressions for your goals, and you should expect total ROI for a campaign to exceed that of a CPC or a traditional CPM campaign.

Optimize your campaigns by defining the ad set's optimization_goal.

oCPM for Mobile App Installs is only available if the application has reported an install event in the last 28 days via the Facebook SDK or a mobile measurement partner.

Create oCPM ad

The ad set object contains bid information. To create an oCPM ad:

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

$adset = new AdSet(null, 'act_<AD_ACCOUNT_ID>');
$adset->setData(array(
  AdSetFields::NAME => 'My Ad Set for oCPM',
  AdSetFields::BILLING_EVENT => AdSetBillingEventValues::IMPRESSIONS,
  AdSetFields::OPTIMIZATION_GOAL => AdSetOptimizationGoalValues::LINK_CLICKS,
  AdSetFields::BID_AMOUNT => 150,
  AdSetFields::CAMPAIGN_ID => <CAMPAIGN_ID>,
  AdSetFields::DAILY_BUDGET => 1000,
  AdSetFields::TARGETING => array(
    '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

# Create an Ad Set with bid_type set to oCPM
adset = AdSet(parent_id='act_<AD_ACCOUNT_ID>')
adset.update({
    AdSet.Field.name: 'My Ad Set for oCPM',
    AdSet.Field.billing_event: AdSet.BillingEvent.impressions,
    AdSet.Field.optimization_goal: AdSet.OptimizationGoal.link_clicks,
    AdSet.Field.bid_amount: 150,
    AdSet.Field.campaign_id: '<CAMPAIGN_ID>',
    AdSet.Field.daily_budget: 1000,
    AdSet.Field.targeting: {
        Targeting.Field.geo_locations: {
            'countries': ['US'],
        },
    },
})

adset.remote_create(params={
    'status': AdSet.Status.paused,
})
AdSet adSet = new AdAccount(act_<AD_ACCOUNT_ID>, context).createAdSet()
  .setName("My Ad Set for oCPM")
  .setBillingEvent(AdSet.EnumBillingEvent.VALUE_IMPRESSIONS)
  .setOptimizationGoal(AdSet.EnumOptimizationGoal.VALUE_LINK_CLICKS)
  .setBidAmount(150L)
  .setCampaignId(<CAMPAIGN_ID>)
  .setDailyBudget(1000L)
  .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=My Ad Set for oCPM' \
  -F 'billing_event=IMPRESSIONS' \
  -F 'optimization_goal=LINK_CLICKS' \
  -F 'bid_amount=150' \
  -F 'campaign_id=<CAMPAIGN_ID>' \
  -F 'daily_budget=1000' \
  -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

When you do this, these fields must follow the restrictions below:

Name Description

billing_event

You must set to IMPRESSIONS.

optimization_goal

Set to what action you want to optimize.

bid_amount

Value you place on the optimization goal, specified in cents.

Facebook's Create Flow in Ads Manager will default these values to:

  • 1000 for optimization_goal=APP_INSTALLS
  • 3000 for optimization_goal=OFFSITE_CONVERSIONS, however we recommend to bid true value of the conversion, which may be higher
  • 500 for all other actions

See Validation Best practices for ad units that support oCPM bidding.

Budget and Pricing

An Optimized CPM campaign must have a budget. The ad system bids on each impression on your behalf, bidding high when the impression is likely to work for your goals, and bidding low when it’s unlikely to work for your goals.

Keep in mind that this dynamic enables you to capture the highest-value impressions for your goals, and you should expect the total ROI on the campaign to surpass your traditional CPC or CPM campaign. Note that stats for each of the goals are provided in Ads Manager and in the API, so you can check your ad's performance and gauge the success of a campaign, based on your goals.