Concepts

Sync and history

Two kinds of numbers, the daily warehouse and the lifetime history, and how each is filled, refreshed and read.

Win & Scale holds two different bodies of numbers for an ad account. They answer different questions and are never added together.

WarehouseHistory
ShapeOne row per ad per dayOne row per ad, lifetime totals
Answers"How did last week go?" Any dated read."What ever ran here, and what did it buy?"
Filled byA nightly sync of a trailing window, plus a backfillA pull that replaces the whole snapshot
Read withmeta_get_overview, meta_get_ad_performance, meta_get_performance_cube, meta_get_strategy_rollupmeta_get_account_history

meta_get_history_winners and meta_get_cross_analysis read either one, chosen by window: 30d, 90d (the default) or 180d from the warehouse, or lifetime from the history.

The warehouse

  • The nightly sync keeps a trailing window of recent days current. POST /api/v1/sync (meta_sync_now) pulls the last days days on demand: default 3, up to 90. Offer it when lastSyncedAt is stale.
  • Every workspace backfills 90 days once, after its first sync.
  • Older days come from a backfill. POST /api/v1/backfill (meta_backfill_insights) walks back one month at a time from the oldest day held, to where the account's spend began, capped at Meta's 37 months. It runs in the background and returns 202. Asking again resumes and never re-reads a finished month. Progress shows in the overview's coverage.
  • "Last N days" means the last N complete days, ending yesterday (UTC). This matches Ads Manager. this_week runs to today.
  • Coverage is explicit. coverage says what the warehouse holds. A window that starts before it carries a warning, and zero there means "not held", not "no spend".

Purchases and ROAS are blank where the purchase pixel did not fire.

The history

  • It is a snapshot, replaced whole on every pull. Archived and deleted ads are included. Rows for ads Meta no longer reports are removed, but an empty answer from Meta removes nothing.
  • It is empty until the first pull. POST /api/v1/history/pull (meta_pull_account_history) fills it, and the app also pulls it right after a Meta connection.
  • It is never summed with the warehouse. For a time series use GET /api/v1/overview.
  • An ad with spend in a window that the history has not pulled yet is counted and never judged. Evidence health reports how many.

Meta's quota

Meta limits calls per hour. GET /api/v1/api-usage (meta_get_api_usage) shows the calls made, the errors, the throttles, the percentage of the app and ads-management allowances used, and the minutes until access returns if throttled. Check it before a large launch.

When the quota is used up:

  • a history pull is scheduled instead: the response has status: queued and retryInMin, it runs by itself, and the stored history stays readable meanwhile;
  • a backfill waits and resumes.

Live reads

Two tools call Meta live instead of reading the warehouse: meta_get_breakdowns (performance by age, gender, country, publisher platform or device platform, or one ad's placement and retention) and meta_get_audience_breakdown (who responds to each Value). Both are cached, so use their results as a snapshot. Neither has a REST endpoint.

Freshness is surfaced, not hidden

Every judgement depends on this page being true. Start with evidence health, and if the sync is stale, sync and read again before you trust a comparison.

On this page