Marketing API Version

Reach and Frequency

Bid on a predicted unique audience reach for your ads on Facebook and Instagram and control display frequency. This is similar to how people traditionally buy TV ads. This is a specialized, advanced option that most advertisers will only use if they want high assurance their ads reach a certain number of people. Most of the time, expect to use standard budget and bidding in the Ads Auction. See Bidding and Optimization.

Reach and frequency works across ad types and devices. Since Facebook targets based on real people, not cookies, we can more accurately predict reach and control frequency across devices.

Restrictions

  • Available for certain ad accounts. Check ad account's CAN_USE_REACH_AND_FREQUENCY.
  • Accounts also have country-based limitations; check with HTTP GET: https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>?fields=rf_spec
  • Only set one country at a time in target_spec.
  • No minimal iOS versions for user_os, such as iOS_ver_2.0_and_above

Search rf_spec for applicable limits:

NameTypeDescription

countries

Array

Supported countries for reach and frequency

min_campaign_duration

Object

Minimum campaign duration in days, per supported country

max_campaign_duration

Object

Maximum campaign duration in days, per supported country

max_days_to_finish

Object

Days in advance campaign can finish at time prediction made, per supported country

min_reach_limits

Object

Minimum reach in number of people, per supported country

Results look like this:

{
  "rf_spec": {
    "min_reach_limits": {
      "US": 1000000,
      "CA": 1000000,
    },
    "countries": [
      "US",
      "CA",
    ],
    "min_campaign_duration": {
      "US": 3,
      "CA": 3,
    },
    "max_campaign_duration": {
      "US": 30,
      "CA": 30,
    },
    "max_days_to_finish": {
      "US": 56,
      "CA": 56,
    }
  }
}

Create Predictions

Predictions contain the number of people your ad can reach in a date range based on a given reach, frequency, audience and budget. You can reserve then assign a prediction to your ad set and Facebook tries to deliver your ads to fulfill the prediction. See Reach and Frequency Prediction, Reference.

While you can cancel or change campaigns prior to the start date, you can lose access to this feature if you frequently cancel. Only book campaigns you intend to run. For testing, limit your reservations to the smallest size and length; be certain you cancel them since this is real ads inventory that we reserve for you. If your account is flagged for excessive lapsed test campaigns, you lose access.

Limits

These are default limits for predictions:

  • Target audiences of at least 300k people
  • Minimum reach of 200k people
  • Ad sets must run at minumum 1 day and maximum of 90 days (The number of days is calculated as number of days the campaign spans. For example, if campaign starts at 12:00pm on day 1 and ends at 10:00am on day 2, the campaign is considered to have run for 2 days although the different in hours is less than 24 hours).
  • Ad set stop time must be within 180 days of a prediction
  • The campaign must end after 6AM on the last day in the ad account timezone

Reading Predictions

For details specify fields. To see all reachfrequencypredictions for an account, make a HTTP GET to https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/reachfrequencypredictions?fields=<COMMA_SEPERATED_FIELD_LIST>.

To reach all reachfrequencypredictions based on a reachfrequencyprediction ID, make a HTTP GET with fields you want: https://graph.facebook.com/<API_VERSION>/<RF_PREDICTION_ID>?fields=<COMMA_SEPERATED_FIELD_LIST>.

By default, Facebook returns the ID. For field details, see Reach Frequency Prediction, Reading.

Response Status Codes

This shows possible status results in reachfrequencyprediction. Initial limitations appear when applicable, however they may vary per ad account or by country in the future:

CodeStatusDescription

1

SUCCESS

Prediction successful

2

PENDING

Prediction still being produced

3

FAIL

Unreachable audience. Too high reach or budget.

4

FAIL

Prediction settings invalid, for example, duration

5

FAIL

targeting_spec invalid

6

FAIL

Budget or bid for given reach too low

7

FAIL

Too short ad set length

8

FAIL

Too long ad set length

9

FAIL

Ad set end date too far in future

10

FAIL

Frequency cap not specified

11

FAIL

Ad placement not supported, such as mixed RHS and Feed

12

FAIL

Ad set dates issues: start time in past, not midnight, or not full day

13

FAIL

Targeted country not yet supported

14

FAIL

Ad set dates include blackout days

15

FAIL

Insufficient inventory, unable to reserve. See Reserving a Prediction.

16

FAIL

Minumum reach required for account not achieved. See Getting Account Restrictions

17

FAIL

Actual reach available for this predict is less than the minimum reach of the targeted country, usually 200,000 for most countries.

18

FAIL

Invalid day parting schedule provided.

19

FAIL

Target CPM unachievable.

20

FAIL

Frequency cap too low for blended delivery

21

FAIL

Ads inventory changed significantly enough for inaccurate prediction.

23

FAIL

Frequency cap interval not supported in target country.

24

FAIL

Holdout Lift Study ad set under account or campaign group not consistent with Reach and Frequency prediction.

25

FAIL

Frequency cap can't exceed number of days your campaign runs.

26

FAILURE_EMPTY_AUDIENCE

Selected audience empty and unusable.

27

FAIL

No modification allowed on your running campaign.

28

FAIL

Cannot modify running campaign created with Insertion Order.

29

FAIL

Cannot modify running campaign due to time constraints.

30

FAIL

To edit running Reach and Frequency ad set, choose budget higher than current spend.

31

FAIL

Lift Study for account or campaign group starts after campaign starts.

32

FAIL

Lift study for account or campaign group ends before campaign ends.

100+

FATAL

System failure, no user fault. Retry.

Using Predictions

Provide your Prediction ID and it's data as input to create a new ID which serves as a reservation ID. Then attach this reservation ID to your ad set. Creating a reservation makes inventory unavailable to others, so you should attach it before it expires.

If the reservation succeeds, we temporarily reserve the inventory for you. You have approximately one hour after the reservation to assign an ad to an ad set.

Reserving

Reserve predictions for your ad sets to lock in your price and have preditable reach. Reserve an audience identified by reachfrequencyprediction for a set time with reserve for action. You can use a single prediction ID to create multiple reservations. For example:

curl \
-F 'action=reserve' \
-F 'rf_prediction_id=<RF_PREDICTION_ID>' \
-F 'access_token=<ACCESS_TOKEN>' \
'https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/reachfrequencypredictions'

// Response 
{"id":9876543210"}

To reserve inventory based on a prediction, make a HTTP POST at https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/reachfrequencypredictions.

For reach, budget, and impression, you can reserve a prediction at a specific point on curve_budget_reach rather than the original tuple of prediction reach/budget. Use these fields:

NameTypeDescriptionRequired

rf_prediction_id

int

reachfrequencyprediction ID

yes

action

string

reserve - reserve inventory with previous prediction
cancel - cancel reserved prediction

Yes, required for reservation and cancellation

rf_prediction_id_to_release

int

Reserved prediction or reservation ID. A new reservation releases a reserved audience and uses it for the new reservation. See Reusing Reserved Audiences

no

rf_prediction_id_to_share

int

ID of previously created prediction. New predictions use the audience from a given prediction.

no

reach

int

You can override this value. Specify reach, budget, and impression for that point on curve_budget_reach.

No. If specified you must provide budget and impression

budget

int

You can override this value. Specify reach, budget, and impression for that point on curve_budget_reach.

no, but if specified you must specify reach and impression

impression

int

You can override this value*. To do so, specify the reach, budget, and impression for that point on curve_budget_reach

no, but if specified you must specify reach and budget

Facebook reserves predictions asynchronously; you should poll and check the status of the prediction. Initially the prediction status is 2 (PENDING). On completion, status is 1, SUCCESS, or 15, FAIL which means we lack inventory to complete this reservation.

Since the reservation system is dynamic, you may see small changes in inventory availability between your prediction time and reservation time. However, Facebook respects values you get at the prediction time, so long as changes fall into a reasonable threshold.

Assigning to Ad Sets

After you successfully reserve a prediction, create an ad set with it:

curl \
-F "rf_prediction_id=<RF_PREDICTION_ID>" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<AD_SET_ID>"

To successfully assign a prediction, your ad set must meet these criteria:

  • Do not specify:
    • start_time - derived from prediction
    • end_time - derived from prediction
    • targeting - derived from prediction
    • bid_amount
    • optimization_goal
    • Either lifetime_budget or daily_budget
  • You can assign reservations to ad sets without active ads. However, you must have at least one active ad before the ad set starts.
  • You must include rf_prediction_id which attachs the prediction to the new ad set.
  • The ad campaign attribute of buying_type is RESERVED

You can also attach reachfrequencyprediction to ad sets to modify it's prediction. Making a HTTP POST request to: https://graph.facebook.com/{ad_set_id} with rf_prediction_id for the reachfrequencyprediction you want to use.

The following are limits on the ad set:

  • Placement options: desktopfeed, rightcolumn, mobilefeed, and instagramstream. If placement includes instagramstream, you must use destination_ids not destination_id. destination_ids field should contain the id as destination_id, plus the Instagram account ID.
  • Either Custom Audience or Partner Categories but not both
  • Website Custom Audiences, fan or video engagement-exclusion targeting are not permitted
  • Ad set's promoted_object must match the prediction's destination_id. For page posts, it must be the page ID specified and for app ads, it must match the app ID specified.
  • Standard and Scheduled Ads Pacing supported, while accelerated delivery not.

We charge Reach and Frequency campaigns on actual impressions delivered. If the campaign start time passes and the ad set lacks active ads, the campaign fails to deliver and no charges apply. Facebook releases remaining inventory, however we may penalize the ad account for repeat occurances.

When you create a campaign using Facebook's reach and frequency buying type you are agreeing to pay the proposed costs for the advertising inventory you reserve. If you want to change your audience size or frequency, then your costs will also change. You can make these changes any time before your campaign starts. You can edit your ad creative until your campaign starts.

Managing Ads

Reach and Frequency ad sets may contain multiple ads; you can add more ads at any point. If the ad set activates and there are no active ads in it, you must create your first ad within 24 hours for ad sets lasting 3 to 30 days, or 6 hours for ad sets lasting 1 to 2 days. If you do not, we delete the reservation.

Detaching Predictions, Modifying Ad Sets

You can cancel or change ad sets at any time. If you frequently cancel your sets you may be blocked from this buying type. To pause or edit a set after it starts, see Pausing or Restarting Running Ad Sets and Editing Running Ad Sets. To delete an active set, see Ad Set, Reference. You'll be charged for any impressions delivered.

If you assign a reservation to an ad set before the ad set becomes active, you cannot change most attributes unless you detach the reservation. Make a HTTP POST request to the set and set rf_prediction_id to 0. You can only modify the name attribute on the ad set object.

To detach a reservation:

curl \
-F "rf_prediction_id=0" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<AD_SET_ID>"

Once an ad set is active, the reservation cannot be detached and attributes of the set cannot be modified, except a few whitelisted ad attributes listed below:

  • name
  • creative_id
  • creative_spec
  • conversion_specs
  • tracking_specs
  • view_tags

Pausing and Restarting Ad Sets

You can pause an active set, see Ad Set, Reference. If you pause an ad set for more than 30 minutes, we no longer guarantee the prediction for this set.

To reactivate a set paused for more than 30 minutes, you need a new prediction. Make a POST to reachfrequencypredictions. See Create a Prediction and Reserve the Prediction. You should pass an existing_campaign_id for the active set to be reactivated in the request. After you create and reserve a new prediction, attach reachfrequencyprediction to the ad set with HTTP POST to: https://graph.facebook.com/{ad_set_id} specifying rf_prediction_id for the prediction you want to use.

Editing Running Ad Sets

You can make these updates after a set starts.

  • Increase or decrease ad set budget and reach. Budget or reach should be greater than the current spend or delivered reach.
  • Extend ad set schedule to 90 days.

You cannot edit or pause and active set if it meets one of the following criteria:

  • Heavily under-delivered. Delivered less than 10% of prediction. Over-spent sets with spend over budget
  • Ad sets running only for one day
  • Ad sets ending within next 24 hours

To edit running ad sets, get a new prediction. See Create a Prediction and Reserve the Prediction. You should pass an existing_campaign_id for the active set to be reactivated in the request.

After a new prediction is created and reserved, you can attach reachfrequencyprediction to the ad set by making a HTTP POST request to: https://graph.facebook.com/{ad_set_id} specifying rf_prediction_id as the id of the reachfrequencyprediction you want to use.

Reusing Reserved Audiences

If you cancel a reservation it frees reserved inventory for other advertisers. However, you can reuse an audience from a previously reserved prediction if you aren't already using it. This enables us to take into account additional inventory to create a prediction, without you having to cancel an existing reservation.

Include rf_prediction_id_to_share when you create a reservation. This is the ID of a previous prediction. This invalidates the previous reservation, so you can use this inventory for your newly created reservation.

To reserve the new prediction, you must also pass the additional parameter rf_prediction_id_to_release which is the ID of the previous reservation.

Ad Rotation and Sequencing

You can rotate ads in the ad set you are using. You do not need to detach the reservation from the ad set to do this. Add one or more ads to the ad set and wait until it becomes active. At this point, you can change the status of the initial ad to paused. You must have at least one active ad within the ad set.

You can design a sequence of ads that deliver in order. First create the ad set and ads. Then specify the sequence at the ad set level in creative_sequence. Each individual ad in this ad set may not appear, appear once, or appear multiple times in the sequence.

If creative_sequence array length is zero, then you're using no sequencing. If the length is not zero, we recommend you make it equal frequency_cap in rf_prediction_id. If the length is larger than frequency_cap, we truncate the last several ads from the array. If the length is less than frequency_cap, we recursely auto-fill the array by repeating the sequence from the beginning. To make results clear, set the length of creative_sequence to the same amount as frequency_cap.

Each ads in the sequence has ACTIVE, PENDING_REVIEW, or CREDIT_CARD_NEEDED status. A particular ad in the sequence will only be delivered to a user if all the preceding ads in the sequence have been delivered. Ads not included in the creative_sequence will not be delivered.

All ads in an ad set using ad sequencing, no matter in the sequence or not, cannot be paused, archived, or deleted.

This feature is only available for Reach and Frequency ad sets, i.e. the buying_type of its parent ad campaign is RESERVED, and this ad set has rf_prediction_id set.

More details can be found at ad set document.

Error Codes

CodeDescription

1487583

An ad set with no ads cannot be assigned a reach and frequency prediction

1487055

Ad set status invalid

1487600

Ad set is already assigned to a reservation. If you want to use another prediction, please first disconnect current from the set using null value and then assign new prediction.

1487578

The specified reachandfrequencyprediction ID does not exist, or does not belong to the account given.

1487581

Reach and Frequency prediction cannot be modified on an active ad set

1487594

No Ads In Reach And Frequency ad set

1487595

Invalid Target Spec In Reach And Frequency ad set

1487614

Ad set start time does not match with original prediction

1487615

Ad set stop time does not match with original prediction

1487616

Cannot associate ad set with invalid prediction

1487671

Direct transition from one prediction to another for an ad set is not allowed.

1487244

Ad set Update Failed - reason should be given in response

1487672

Failed to assign prediction to ad set.

1487680

You don't have permission to use reach and frequency ad sets.

Examples

Creating a reachfrequencyprediction for an app destination_id:

curl \
-F 'target_spec={"geo_locations": {"countries":["US"]}, "age_max":35, "age_min":26, "genders":[2], "publisher_platforms":["facebook"], "facebook_positions":["feed"]}' \
-F 'start_time=1388534400' \
-F 'end_time=1389312000' \
-F 'frequency_cap=4' \
-F 'reach=1000000' \
-F 'budget=3000000' \
-F 'destination_id=<APP_ID>' \
-F 'prediction_mode=1' \
-F "objective=MOBILE_APP_INSTALLS" \
-F 'access_token=<ACCESS_TOKEN>' \
'https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/reachfrequencypredictions'

{"id":"67890123456"}

Creating a reachfrequencyprediction for a page destination_id:

curl \
-F 'target_spec={"geo_locations": {"countries":["US"]}, "age_max":35, "age_min":26, "genders":[2], "publisher_platforms":["facebook"], "facebook_positions":["feed"]}' \
-F 'start_time=1388534400' \
-F 'end_time=1389312000' \
-F 'frequency_cap=4' \
-F 'reach=1000000' \
-F 'budget=3000000' \
-F 'destination_id=<PAGE_ID>' \
-F 'prediction_mode=1' \
-F "objective=POST_ENGAGEMENT" \
-F 'access_token=<ACCESS_TOKEN>' \
'https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/reachfrequencypredictions'

{"id":"67890123456"}

Creating a reachfrequencyprediction for an app destination_id with Instagram placement:

curl \
-F 'target_spec={"geo_locations": {"countries":["US"]}, "age_max":35, "age_min":26, "genders":[2], "publisher_platforms":["facebook","instagram"], "device_platforms":["mobile"]}' \
-F 'start_time=1388534400' \
-F 'end_time=1389312000' \
-F 'frequency_cap=4' \
-F 'reach=1000000' \
-F 'budget=3000000' \
-F 'destination_ids=[<APP_ID>,<INSTAGRAM_ACCOUNT_ID>]' \
-F 'prediction_mode=1' \
-F "objective=MOBILE_APP_INSTALLS" \
-F 'access_token=<ACCESS_TOKEN>' \
'https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/reachfrequencypredictions'

{"id":"67890123456"}

Poll the following endpoint via HTTP GET requests to retrieve the status until it is something other than 2:

https://graph.facebook.com/67890123456?fields=status

If the status is 1 (successful), then this can be attached to an ad set or reserved.

Reserving a prediction:

curl \
-F 'action=reserve' \
-F 'rf_prediction_id=<RF_PREDICTION_ID>' \
-F 'access_token=<ACCESS_TOKEN>' \
'https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/reachfrequencypredictions'

{"id":"9876543210"}

Poll the following endpoint via HTTP GET requests to retrieve the status until it is something other than 2:

https://graph.facebook.com/<API_VERSION>/<PREDICTION_ID>?fields=status

If the status is 1 (successful), then this can be attached to an ad set. Let's set up your campaign structure by creating a campaign, an ad set, a creative, an ad, and assigning the reservation to the ad set.

Create an ad campaign:

curl \
-F "name=Test" \
-F "buying_type=RESERVED" \
-F "status=ACTIVE" \
-F "objective=POST_ENGAGEMENT" \
-F "access_token=<ACCESS_TOKEN>" \
https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/campaigns

{"id":"1122334455"}

Create an ad set:

curl  \
-F "name=TestReachSet" \
-F "status=1" \
-F "campaign_id=<CAMPAIGN_ID>" \
-F "rf_prediction_id=<RF_PREDICTION_ID>" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/adsets"

{"id":"09876543"}

Generate an ad creative:

curl \
-F "name=sample creative" \
-F "type=1" \
-F "title=hello world" \
-F "body=hi i'm an ad" \
-F "link_url="https://www.facebook.com/" \
-F "image_hash=4aca812b4eadb72818a2c4124abd121a" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/adcreatives"

{"id":"1323123123123"}

Create an ad:

// Create an ad
curl \
-F "name=my ad" \
-F "adset_id=<AD_SET_ID>" \
-F "creative={'creative_id':<CREATIVE_ID>}" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/act_<AD_ACCOUNT_ID>/ads"

{"id":"3213213123"}

Assigning a new prediction to the ad set:

curl \
-F "rf_prediction_id=<RF_PREDICTION_ID>" \
-F "access_token=<ACCESS_TOKEN>" \
"https://graph.facebook.com/<API_VERSION>/<AD_SET_ID>"