Skip to main content
Per-ad delivery shows how every ad in one Meta campaign performed over a date range, one row per ad per day. Use it to see which ads are winning and which are tiring, for example when frequency climbs while click-through falls. Each ad names the Apostra creative it runs and, when a Creative Session made it, the session and the variant you picked, so you can tell which concept worked. It reads the campaign from Meta on every call, through your connected Meta ad account. It covers Meta campaigns you bought through Apostra and Meta campaigns you connected from your own ad account.

Read per-ad delivery

Call get_delivery with report: "live_ad_delivery", one campaign and a date range of at most 90 days:
The dates are calendar days in the Meta ad account’s timezone, which the response names. A lifetime range, metric selection, grouping dimensions and other filters are refused: this report always returns every figure below for every ad.

What comes back

The response follows AdCP’s delivery shape. Ads sit inside their ad sets, the way AdCP nests by_creative inside by_package:

Each ad

Each ad set

Each by_package entry is a Meta ad set. Its figures are the sums of its ads. It has no reach or frequency, because those do not add up across ads.

Things to know

  • Days with no delivery are missing, not zero. Meta returns no row for a day an ad did not deliver. The ad’s totals already count those days as zero.
  • Reach does not add up. Never add daily reach to get the reach for the range: the same person can be counted on several days. Use the ad’s own reach, which counts each person once over the range.
  • Totals and reach come from two reads. An ad’s totals are the sums of its days. Its reach and frequency for the range come from a second Meta read made in the same call, so on a campaign that is delivering they can be a few impressions ahead or behind.
  • Conversions are the ad set’s optimization event only. An ad set that is not optimized for a conversion event has no conversions. Meta can still revise conversions within its attribution window, so a later read can differ.
  • Creative Session names. When a Creative Session finishes a creative, Apostra records the session and variant on the creative, so its ads name them for as long as they run. A creative finished before Apostra kept that record (November 2026) names them only while its session is still kept, which is 7 days after the session was created.
  • Meta only. A campaign on any other platform is refused with VALIDATION_ERROR.
  • Live, not billing. These are Meta’s figures at the time of the call. They are not Apostra’s reporting figures and are not used for billing.

Paging

Ad sets come in package_id order and their ads in platform_ad_id order. A page holds whole ads, up to limit ads (100 by default) and as many as fit in one response. When more ads remain, page.truncated is true and page.nextCursor is set: call again with the same request and cursor set to that value. An ad set split across pages appears on each page with the same totals and by_creative_truncated: true. Each page reads Meta again.

Errors