Diagnosing Meta Reach & Frequency Delivery Shortfalls: A Systematic Guide for v19.0+
Systematic diagnostic guide for Meta Marketing API Reach & Frequency (v19.0+) delivery shortfalls: six ordered checks from prediction freshness to creative gaps, with API calls, fixes tied to findings, and escalation criteria.
09 Nov 2025, 16:07 UTC

The Problem: Predicted Reach vs. Actual Delivery
You launched a Reach & Frequency (R&F) campaign using Meta's Marketing API v19.0. The /reachfrequencypredictions endpoint returned a clean estimate — say, 1.2M unique users over 14 days at a $12 CPM. Forty-eight hours later, Ads Manager shows 340k reached. The campaign is pacing at 28% of prediction. This gap is not a bug; it's a diagnostic signal. The prediction is a probabilistic model updated daily, not a guarantee. This guide walks through the six most common causes, ordered by diagnostic yield, with fixes tied to each finding and clear escalation criteria.
Recognizable Conditions
| Symptom in Ads Manager / API | Typical Root Cause Category |
|---|---|
| Campaign stuck in "Pending Review" or error 190 on prediction call | Audience too narrow or CPM below market floor |
| Delivery <50% of prediction for 3+ consecutive days | Pacing failure: budget/date misalignment, creative gaps, or internal competition |
| Prediction regenerates with >20% drift from previous estimate | Stale model, audience shifts (iOS 14.5+ opt-out), or seasonality not captured |
| Frequency cap reached early, reach plateaus | Cap set too low for budget; overlapping R&F campaigns sharing frequency budget |
Cause & Diagnostic Reference
| Cause | Diagnostic Check | API Endpoint / Location | Expected Healthy Result |
|---|---|---|---|
| Prediction older than 24 hours | Check data[0].prediction_time timestamp | GET /act_{ad_account_id}/reachfrequencypredictions | Timestamp within last 24h |
| Audience below minimum threshold | Verify data[0].estimated_reach >= 200k–300k (market-dependent) | Same prediction response | Estimated reach meets regional minimum |
| CPM below current floor | Compare campaign CPM to bid_floor for targeting spec | GET /act_{ad_account_id}/reachfrequencybidfloors | Campaign CPM >= returned floor |
| Creative rejection or format gaps | Audit creative status and placement coverage | GET /act_{ad_account_id}/adcreatives?fields=status,effective_object_story_id | All creatives ACTIVE; 9:16 video present for Reels |
| Overlapping R&F campaigns | Query overlap percentage | GET /act_{ad_account_id}/reachfrequencyoverlap | Overlap <10% or no other active R&F campaigns |
| Budget/date misalignment | Daily budget vs. (CPM × target reach / days); schedule matches prediction window | Ads Manager campaign settings + prediction date_start/date_stop | Daily budget >= (CPM × daily reach target / 1000) |
Ordered Diagnostic Checks
Run these in sequence. Stop at the first actionable finding.
1. Verify Prediction Freshness
Predictions expire functionally after 24 hours. Call GET /act_{ad_account_id}/reachfrequencypredictions?prediction_id={prediction_id} and inspect prediction_time. If older than 24h, regenerate with the same targeting spec, budget, and date range. Rate limit: 200 calls/hour per app — implement exponential backoff for bulk checks.
2. Check Audience Size vs. Minimum Threshold
The prediction response includes estimated_reach. For most markets, the floor is 200k–300k unique users. If your targeting spec (narrow interests, small custom audience, restrictive geo) yields less, the API returns error 190 (invalid parameter) or the campaign stalls. Broaden targeting or switch to auction buying.
3. Confirm CPM >= Current Market Floor
Run:
GET /act_{ad_account_id}/reachfrequencybidfloors?targeting_spec={...}&date_start=2026-11-15&date_stop=2026-11-28
Required permissions: ads_read and ads_management on the ad account. The response returns bid_floor in micros (e.g., 12000000 = $12 CPM). If your campaign CPM is below this, the prediction will be optimistic and delivery will stall. Raise CPM to at least the floor; note that floors change quarterly.
4. Audit Creative Status and Format Coverage
Fetch all creatives attached to the campaign:
GET /act_{ad_account_id}/adcreatives?fields=status,effective_object_story_id,object_story_spec
Filter for status != 'ACTIVE'. Rejected creatives reduce eligible inventory silently. Also verify format coverage: if the prediction included Reels or Stories placements, you must have 9:16 video assets. Missing formats = reduced reach with no error.
5. Review Overlapping R&F Campaigns
Call:
GET /act_{ad_account_id}/reachfrequencyoverlap?campaign_id={campaign_id}
This returns a list of other active R&F campaigns with audience overlap percentage. Frequency cap is enforced per person across all R&F campaigns in the account. Overlap >10% means campaigns compete for the same frequency budget. Pause the lower-priority campaign or consolidate into one R&F campaign with a higher frequency cap.
6. Compare Actual Delivery vs. Prediction Window
In Ads Manager, open the campaign → Delivery column. Check:
- Date range matches prediction date_start/date_stop
- Daily spend ≈ (CPM × daily reach target / 1000)
- Bid strategy shows "Reach & Frequency" (fixed CPM), not "Lowest Cost" or "Cost Cap"
A common mismatch: prediction generated for 14 days, but campaign scheduled for 10. The daily budget then cannot sustain the reserved CPM × reach target.
Fixes Tied to Findings
| Finding | Fix | Risk / Constraint |
|---|---|---|
| Prediction >24h old | Regenerate prediction via API; use new prediction_id for campaign creation | Rate limit (200/hr); prediction may shift >20% |
| Audience < minimum | Broaden targeting (remove narrow interests, expand geo, increase custom audience lookalike %) | May reduce relevance; test with auction first |
| CPM < floor | Increase campaign CPM to >= bid_floor; recreate campaign (R&F cannot be edited post-launch) | Higher cost; forfeits reserved CPM if recreated |
| Creative rejected / missing formats | Replace rejected creatives; add 9:16 video for Reels, 1:1 for Feed, 16:9 for In-Stream | Creative review takes 24h; campaign pauses during gap |
| Overlap >10% | Pause overlapping campaign or merge audiences into single R&F campaign with higher frequency cap | Merging requires cancelling both campaigns; loss of reserved CPM |
| Budget/date mismatch | Align campaign schedule to prediction window; set daily budget >= (CPM × daily reach target / 1000) | Increasing budget requires Finance approval in some orgs |
Concrete Example: CPM Floor Check
Scenario: US campaign targeting 18-34 interested in "fitness" and "wearable technology", 14-day flight, $10 CPM bid. Prediction returns 850k reach. After 48h, delivery is 180k.
- Run
GET /act_123456789/reachfrequencybidfloors?targeting_spec={"geo_locations":{"countries":["US"]},"age_min":18,"age_max":34,"interests":[{"id":"6003139266461"},{"id":"6003370788273"}]}&date_start=2026-11-15&date_stop=2026-11-28 - Response:
{"data":[{"bid_floor":14500000,"currency":"USD"}]}→ floor is $14.50 CPM. - Campaign CPM ($10) < floor ($14.50). Prediction overestimated reach because model assumes floor CPM.
- Fix: Cancel campaign. Create new R&F campaign with CPM = $15. Regenerate prediction first to confirm reach at new CPM.
Permissions needed: ads_management on ad account 123456789. App must be approved for Marketing API Standard Access.
Limitations & Verification
- Predictions are not SLAs. Meta documents them as "estimates based on historical data." They exclude Instagram Explore, Reels, and some Audience Network placements unless explicitly included in the prediction request.
- iOS 14.5+ ATT opt-out varies by region and demographic. Predictions may overestimate reach for audiences with high opt-out rates (e.g., US 18-24). No API parameter adjusts for this; factor 15-30% haircut manually for high-opt-out segments.
- R&F campaigns are immutable after launch. Any targeting, budget, or creative change requires cancelling and recreating, which forfeits the reserved CPM. Plan diagnostics before launch.
- Minimum thresholds and CPM floors change quarterly. Values valid in v19.0 may differ in v20.0+. Always query
/reachfrequencybidfloorsat campaign creation time. - Rate limits:
/reachfrequencypredictionscapped at 200 calls/hour per app. Diagnostic scripts must implement exponential backoff and cache predictions for 24h.
Practical Verification Checklist
- Open Meta Marketing API docs (developers.facebook.com/docs/marketing-api/reach-frequency) and confirm v19.0 endpoint paths, required parameters, and error codes.
- In Ads Manager, create a test R&F campaign with a broad audience (e.g., US 18-65, no interests). Note predicted reach. Compare to actual delivery after 48h.
- Call
/reachfrequencybidfloorswith the same targeting; verify campaign CPM >= floor. - Use
/reachfrequencyoverlapto list overlapping R&F campaigns; confirm overlap percentage. - Check creative status via
/adcreatives?fields=status,effective_object_story_id; ensure all are ACTIVE and cover required placements.
Escalation Criteria
Open a Business Support ticket (business.facebook.com/help) with the following evidence when:
/reachfrequencypredictionsreturns persistent 5xx errors (>3 retries with backoff)- Audience size meets minimum but prediction returns
nullor emptydataarray - CPM at or above floor yet campaign won't activate (stays in "Pending Review" >24h)
- Delivery <50% of prediction for 3+ consecutive days with no diagnostic cause found after all six checks
Attach: prediction ID from /reachfrequencypredictions response, campaign ID, date range, Ads Manager delivery screenshot, and the targeting spec used. Include the bid_floor response if CPM-related.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.