get_media_buy_delivery. This page covers both, the report
your agent has to send, how Apostra answers it, and how to check what Apostra
received for a media buy.
How Apostra gets your delivery
Your products decide it. Each product can declarereporting_capabilities.supports_webhooks in get_products.
Apostra does not read reporting files from your own storage, so there is no
bucket or file option. To send reports, push them. To have Apostra read them,
declare
supports_webhooks: false and answer get_media_buy_delivery.
Certification judges the choice you make. See
Reports arrive on time and the
delivery report format finding.
Push reports to Apostra
When Apostra books on your agent,create_media_buy carries a
reporting_webhook with the url to post reports to. Post to that URL exactly
as it was sent, and sign every request. An unsigned or wrongly signed report
gets 401 and is not read. See
Signing the webhooks you send us.
Send the AdCP envelope
From AdCP 3.1, a delivery report is an MCP webhook envelope withtask_type: "media_buy_delivery" and the report under result:
media-buy/media-buy-delivery-webhook-result.json
for your release. Apostra checks it against every AdCP release from 3.1 that it
bundles, because a delivery webhook does not say which release it follows, and
refuses it only when none of them accepts it. These fields are required:
Send
by_package on every entry. When you cannot split delivery by package,
send an empty array. Leaving it out is a 400. Extra fields are kept, but they
never stand in for a required one: by_day does not replace by_package.
An AdCP 3.0 report, with media_buy_deliveries at the top level and no
envelope, is still accepted so your reporting keeps working. It shows as a miss
in the delivery report format finding. See
Delivery reports.
Say which days the delivery is for
Senddaily_breakdown on every entry, with one item per day and its date as
YYYY-MM-DD, so Apostra can record each day. A report whose
reporting_period is a single day names that day itself. Totals over several
days with no daily_breakdown get a 200, but Apostra does not record them,
because it cannot tell which day they belong to.
Report a day after it has ended. A report for a day still in progress is
acknowledged, but Apostra keeps it only as provisional figures for the buy. It
is not recorded as that day’s delivery, and package figures wait for the closed
day’s report. A period that ends at the next midnight and lasts 23 to 25 hours
is open until that end. Any other period is open until 25 hours after its start.
Report only what you observed. A day, package or source you have no figures for
is not a zero, so leave it out rather than sending 0. Report spend in the
currency the buy was booked in. A report in another currency is still recorded,
but Apostra cannot book its spend.
How Apostra answers
Every report Apostra refuses is in your agent’s
webhook results, with the first failing field.
Correct a report
To correct a figure, send the cumulative-to-date report again with the right value. Apostra keeps the latest report for each reporting day, media buy and source, so a re-sent report replaces your own earlier one for that day. It does not replace another source’s report for the same buy and day. A retry after a503 therefore never counts twice.
When Apostra reads your delivery
If your products declaresupports_webhooks: false, Apostra calls your
get_media_buy_delivery for each live buy twice a day, at 02:00 and 14:00 UTC,
once the buy has delivery to read. Right after a buy is created it reads more
often while it waits for the first usable delivery.
- Reads that return nothing usable. When a read comes back empty, or for an
active buy has no
daily_breakdownyet, Apostra reads again soon after, on a backoff that grows from seconds to an hour. It makes six reads in all for that slot, then waits for the next one. - After a buy completes. Apostra keeps reading it twice a day for seven days, to pick up late or revised reporting, and then stops.
- The schedule is fixed. The frequencies a product declares in
reporting_capabilitiesdo not change when Apostra reads you. They set what certification expects. - Delivery by property is asked for only when you declare it. When every
product on a buy declares
supports_property_breakdowninreporting_capabilities, the read also carriesreporting_dimensions.propertywith alimitof 250 rows per package. Answer it withby_propertyon every package, withby_property_truncatedandby_property_suppressed. A package that comes back without them counts in the property delivery finding. - The reply must be valid AdCP. Apostra checks it against the AdCP
get_media_buy_deliveryresponse. Eachby_packageitem needspackage_id,spend,pricing_model,rateandcurrency. A reply that fails counts in valid responses.
Google Ad Manager storefronts Apostra runs
When your Storefront sells Google Ad Manager (GAM) inventory through the sales agent Apostra runs for you, that agent reports your delivery from GAM in two ways: provisional figures about every 15 minutes while a buy runs, shown in Campaign Pulse, and daily figures read twice a day. See How often Apostra reads GAM delivery. Each daily read runs a new GAM report, so nothing is cached between those reads.Impressions and clicks are filtered for invalid traffic
Deliveryimpressions and clicks are GAM’s ad-server counts,
AD_SERVER_IMPRESSIONS and AD_SERVER_CLICKS, which already leave out the
traffic GAM judged invalid. Google says Ad Manager “discards impressions and clicks
that are considered invalid”
(how Ad Manager counts impressions and clicks),
and that its metric totals are net of General Invalid Traffic (GIVT) filtration
and some Sophisticated Invalid Traffic (SIVT) filtering techniques
(Ad Manager’s invalid traffic methodology).
These filtered counts are the impressions and clicks buyers see.
Your products also report two AdCP vendor metrics from google.com:
unfiltered_impressions and unfiltered_clicks. They are GAM’s counts before
invalid-traffic filtering (AD_SERVER_UNFILTERED_IMPRESSIONS and
AD_SERVER_UNFILTERED_CLICKS), reported beside the filtered counts for
comparison. Each product lists them in reporting_capabilities.vendor_metrics,
and each package’s delivery carries them in vendor_metric_values. The gap
between the unfiltered and filtered counts is the traffic GAM judged invalid.
The ad-server delivery check in
certification compares our tracker with unfiltered_impressions.
How often Apostra reads GAM delivery
Buyers get your GAM delivery in two forms: provisional figures within minutes, and daily figures once GAM has counted each day. Provisional figures, about every 15 minutes. While a buy runs, the sales agent re-reads the delivery counts of your live GAM line items, those delivering or ready to deliver, about every 15 minutes. It reads the counts GAM keeps on each line item rather than running a report, so it uses none of your report quota. Apostra reads them from the agent every 5 minutes, as each package’s snapshot (get_media_buys with include_snapshot), so a new count
reaches buyers within about 5 minutes. A buy is read this way from the start of
its flight for as long as the agent reports it active. You don’t need to set
anything up.
The snapshot holds each package’s running totals since the flight started:
impressions, clicks and spend. Buyers see it in
Campaign Pulse, labelled provisional. It is not final and
not billable, and it is kept apart from the daily figures: it never replaces or
adds to them. The two come from different GAM reads, and GAM can still revise
its counts, so the daily figures for a day can differ from the provisional ones
buyers saw during it.
Daily figures, twice a day. GAM needs about four hours to count
delivery. So your GAM products declare expected_delay_minutes of 240, or more
if you set a longer delay, report daily in your network’s timezone, and declare
supports_webhooks: false. Apostra therefore reads your delivery on the
schedule in
When Apostra reads your delivery:
- Twice a day. Apostra reads each live buy at 02:00 and 14:00 UTC.
- Until the first figures land. Until a buy has its first usable delivery, Apostra reads again on a backoff that grows to an hour, up to six reads for each slot.
- For seven days after a buy completes. Apostra keeps reading twice a day, to pick up GAM’s revisions, and then stops.
Reporting receipts
A reporting receipt is read-only evidence of one report Apostra received for a buyer’s media buy, whether your agent pushed it or Apostra read it. It helps you confirm that a report arrived and see how Apostra handled it. It is not the buyer’s delivery result, a billing record, or a statement that reporting is final.Read receipts
Callget_seller_reporting_receipts as a Seller Account:
buyerAccountId is the Buyer Account that owns the media buy. The tool opens
the shared Media Buy Timeline Glance and returns the same data.
You can read a media buy only if that buyer account booked it with you.
Otherwise the tool answers NOT_FOUND, which does not say whether the buy
exists. The buyer account also needs reporting status. A buyer account on the
standard buyer profile, which new buyer accounts get by default, has it, and so
do buyers in the V3 beta. A buyer account on an earlier profile does not, and for
its media buys the tool answers FEATURE_NOT_ENABLED. You cannot change a
buyer’s profile.
The result holds:
receipts: one item per report, newest first. Each has areceiptIdyou can match to the report your agent sent,receivedAt, and atransport: a report your agent pushed isstorefront_source_push, and a read Apostra made isstorefront_route_poll. The valueswebhook,pollandbucketcome from older reporting paths.acceptanceon each receipt: astateand, when there is one, areasonwith acode, the first error your source reported assourceCode, and itsmessage.receivedTotalsandreceivedDailyTotalson each receipt: the values that arrived in that report, exactly as your report expressed them. They coverspend,impressions,clicks,videoCompletions,views,conversions,leadsandcurrency, as strings so you can compare them without losing precision. A later correction does not rewrite them.computedDailyTotals: Apostra’s current value for each day and package, with the time it wascomputedAt. A later report can correct a computed day, so these can differ from an earlier receipt. Use the receipt to trace the input and the computed totals to see Apostra’s present view.canonical: the current reporting status for the media buy. See Reliable Reporting registration. Reading it does not request a new report.
Receipt states
A state says what happened to that receipt. It does not say that every required
report arrived, that coverage is complete, or that the media buy is final, and
it is not proof that spend is billable.
Limits
A result is bounded so it is never mistaken for a reporting export. It returns the newest five receipts, up to fourteen received daily totals for each receipt, and the newest thirty-one computed daily totals. When more exists, the matching flag istrue: receiptsTruncated, receivedDailyTotalsTruncated on the
receipt, or computedDailyTotalsTruncated.
In the Timeline, the Reporting receipts section shows three receipts at a
time and lets you page through the ones returned. It also has controls for the
two requests below.
Ask Apostra to read again
After you read receipts,request_seller_reporting_update asks Apostra to read
a media buy’s reporting again. It never calls your agent itself: Apostra’s
scheduler makes the read. It takes the same accountId, mediaBuyId and
buyerAccountId, and the same access rules, as the receipts read.
refreshasks for the next read of reporting periods that have ended and are not already queued. At most 25 of your refresh requests can be waiting at one time. The result givesqueuedReportingItemCountand that limit asrequestLimit.replayasks for a read of a range of days. Add"action": { "kind": "replay", "startDay": "2026-11-01", "endDay": "2026-11-07" }. The range is 1 to 31 calendar days, and a request covers at most 25 reporting items. Apostra accepts at most two replay requests from you in any 24 hours. A third comes back withrateLimited: trueand nothing queued.
refusedFinalDays. Items already waiting for a read are counted in
alreadyQueuedReportingItemCount and are not queued again. Both requests act on
the reporting items Apostra has recorded for the buy. If it has recorded none,
queuedReportingItemCount is 0. Neither changes buyer permissions or billing.
Related
- Signing the webhooks you send us covers how to sign a push.
- Webhook results lists every report Apostra refused and why.
- Reliable Reporting registration covers reporting status and revisions.
- Certification and agent requirements say how reporting is judged.