Documentation Index
Fetch the complete documentation index at: https://docs.adcontextprotocol.org/llms.txt
Use this file to discover all available pages before exploring further.
Overview
For a media buy to invoice deterministically, two questions must have machine-readable answers:- Whose number is authoritative? Different deals name different parties — the seller’s ad server, a buyer’s third-party ad server, or a named measurement vendor like Nielsen or IAS.
- Has that number stopped moving? Telemetry settles over hours, days, or weeks (broadcast C3 → C7 DVR accumulation, digital post-IVT scrubbing, podcast 30-day downloads, conversion dedup). Final numbers are billable; provisional numbers are not.
measurement_terms.billing_measurement (negotiated at create_media_buy) names authority; is_final / final flags with finalized_at timestamps (on get_media_buy_delivery and report_usage) mark closure.
This page ties those pieces together.
Naming authority
measurement_terms.billing_measurement carries:
| Field | Meaning |
|---|---|
vendor (required, BrandRef) | The party whose count of the billing metric governs invoicing. Same field shape covers seller’s ad server, buyer’s 3PAS, or a third-party vendor — the BrandRef domain disambiguates. |
max_variance_percent | Tolerance above which the seller’s and authoritative party’s counts trigger resolution under makegood_policy. IAB default is 10%; broadcast/CTV often 5%. |
measurement_window | Which maturation stage of the data is the reconciliation point (c7, post_sivt, downloads_30d, etc.) — references a window_id from the product’s reporting_capabilities.measurement_windows. |
finalization_deadline_hours | Maximum hours by which the authoritative party MUST publish a final record. When measurement_window is set, hours are counted from the window’s close (not from reporting_period.end); when absent, from reporting_period.end. The deadline applies symmetrically to whichever party is named in vendor. On miss, the counterparty MAY fall back to its own attestation; the breach is handled under makegood_policy. |
billing_measurement is absent the default is seller-attested, with no contractual finalization deadline.
Marking numbers as final
Final means settled for the named measurement window — not “final forever.” A broadcast row markedis_final: true for measurement_window: "c3" is final for C3; a later c7 row supersedes it with its own provisional → final lifecycle. Disputes (when AdCP 3.2 adds them) join on (media_buy_id, reporting_period, measurement_window).
On get_media_buy_delivery
Each row in media_buy_deliveries[] carries:
is_final: boolean— row-level finality, equivalent to all packages in the row being final for the same window.finalized_at: string (date-time)— present iffis_final: true. Anchors any deadline declared inbilling_measurement.finalization_deadline_hours.- Per-package:
by_package[*].is_final,by_package[*].finalized_at,by_package[*].measurement_window,by_package[*].supersedes_window.
On report_usage
Each usage record carries:
final: boolean— absent means unknown. Settrueonly when the reporter has actually settled the numbers (e.g., post-SIVT month-end close). Setfalsefor preliminary records (daily pacing pushes, intra-period progress). Whenmeasurement_terms.billing_measurementnames this reporter as authoritative, the receiver MUST NOT invoice onfinal: falseor absent — request a final record first. For 3.0-style usage with nobilling_measurementand for non-media-buy variants (signals, governance, creative, brand — domains with no provisional state concept), receivers MAY treat absent as final, preserving existing behavior.finalized_at: string (date-time)— present ifffinal: true.measurement_window: string— SHOULD be set when the buy’sbilling_measurement.measurement_windowis set, so the receiver reconciles against the correct stage.
(account, media_buy_id, reporting_period) is later reported with final: true, that record supersedes any prior records for the period.
Distinguishing webhook finality from row finality
get_media_buy_delivery webhooks carry a top-level notification_type enum that includes "final" — this signals “this is the last scheduled notification for the campaign,” not that contained rows are final for invoicing. The two axes are independent: a webhook with notification_type: "final" may still contain rows where is_final: false (e.g., a campaign-end notification before C7 settles). Always check the per-row is_final for billing decisions.
How a seller produces an invoice
Seller-attested (default)
get_media_buy_delivery rows where is_final: true for the contracted measurement_window. No report_usage from the buyer is required.
Buyer-attested (3PAS)
- Buyer’s CM360 settles post-SIVT for the period.
- The buyer’s operator — in practice a holdco platform (e.g., Choreograph, Annalect, Acxiom) or an in-house agency engineering team that wraps the CM360 export — calls
report_usagewith the media-buy record:media_buy_id,impressions,vendor_cost,currency,final: true,finalized_at,measurement_window: "post_sivt". Daily pacing pushes (if used) setfinal: false; only the settled file setsfinal: true. - Seller compares against its own post-SIVT row from
get_media_buy_delivery(is_final: true, samemeasurement_window). If|seller - buyer| / max ≤ max_variance_percent, the seller invoices on the buyer’s numbers. - If variance exceeds threshold, the seller proposes a remedy from
makegood_policy.available_remedies. - If the buyer doesn’t publish a final record within
finalization_deadline_hours, the seller MAY invoice off its own seller-attested numbers and treat the late finalization as a breach undermakegood_policy.
Today’s reality: monthly 3PAS reconciliation is mostly handled out-of-band via CSV/PDF emailed to the seller’s AR team. This flow is the wire-format upgrade — the first adopters are likely holdco operators with the engineering to wrap CM360 / Flashtalking / Innovid exports in report_usage, working with sympathetic direct publishers rather than RTB SSPs.
Vendor-attested (named third party)
- Seller holds the vendor relationship (the common CTV pattern). The seller pulls C7 numbers from Nielsen (NPower, etc.) on its own schedule and publishes them on
get_media_buy_deliveryas a row withmeasurement_window: "c7",is_final: true, andfinalized_atset when the C7 window closes plus its internal processing. Noreport_usagepush from the buyer is needed; reconciliation happens against the seller’s row. - Buyer holds the vendor relationship. The buyer (or its operator) fetches the vendor’s authoritative numbers — e.g., an agency’s iSpot subscription, an in-house IAS dashboard export — and pushes them via
report_usageagainst the buy’s account withfinal: true,finalized_at, andmeasurement_window: "c7". The vendor itself does not call AdCP.
vendor.domain BrandRef identifies who the contract names, not who calls the API. The vendor’s own integration (NPower feed, IAS API, DV pinnacle) is out of AdCP scope.
Today’s reality: SSPs running RTB will keep being seller-attested for the foreseeable future — their billing systems were never designed for buyer-attested invoice basis andmax_variance_percentplusmakegood_policyis not enough commercial cover for them to retrofit it. The first real adopters here are CTV direct sellers (e.g., Disney, NBCU, Paramount) whose Nielsen-backed guarantees already invoice on a measurement vendor’s count — for them this PR just describes existing practice in structured terms.
Resolving disagreements today
When numbers disagree beyondmax_variance_percent, AdCP 3.0–3.1 expects out-of-band resolution between counterparties, backed by:
- The buy’s
makegood_policy.available_remedies— the menu of remedies (additional delivery, credit, invoice adjustment) the seller has pre-committed to. - Final records on both sides with
finalized_attimestamps — a full audit trail of who said what was final, when. - The original
committed_metricsandmeasurement_termscaptured atcreate_media_buy— what the parties signed up for.
under_review / seller_proposed_adjustment / buyer_accepted / unresolved_arbitration, and recording resolution in the audit log — is targeted for AdCP 3.2. The data shape needed to dispute (final records, attestation, measurement window, makegood menu) is already on the wire in 3.1.
Worked example: buyer-attested 3PAS reconciliation
create_media_buy excerpt — measurement terms
get_media_buy_delivery — seller's final post-SIVT row
report_usage — buyer's final 3PAS push
|5120000 - 5040000| / 5120000 = 1.56% — well under the 10% threshold. Seller invoices on the buyer’s 5.04M impressions × the agreed rate. Both sides retain audit-traceable final records.
Related
measurement-terms— schemaget_media_buy_delivery— seller-side finality flagsreport_usage— buyer-side / third-party finality flags- Accountability — performance standards, makegood remedies, cancellation
- Reporting capabilities and measurement windows