Repository navigation
Description
Summary
A buyer that certifies sales agents on live delivery needs to confirm, for scheduled and offline channels, that a buy ran as ordered and that stops and changes took effect. AdCP 3.2 covers most of this:
- spot-level as-run records (
by_package[].by_spot[], withaired_at,spot_id,creative_id,station,daypart); spot_reportingcapability on products;- static OOH
ooh_metrics.postings(see Static OOH: measurement shape + proof-of-posting (the no-play-event channel) #6140); - DOOH
dooh_metrics; - per-installment delivery (
installment-delivery-metrics).
Four gaps remain. We checked against 3.2.0-rc.7.
Gaps
-
When a stop or change takes effect.
installment.deadlines.cancellation_deadlineis the last time to cancel without penalty. There is no field for the last time a cancellation, pause or creative change still takes effect: the traffic or log cutoff for broadcast, the posting cycle for OOH, the issue close for print, the reel lock for cinema. Without it, a buyer can't tell "the seller failed to stop" from "we asked after the cutoff".Proposal: an optional
change_cutoff(datetime) oninstallment.deadlines, plus an optional product-level default lead time for products without installments. -
Selecting installments on a package. Installments are declared on the product, and delivery can be reported per installment, but a package request cannot say which installments it books: which episodes, airings, issues or posting periods.
Proposal: an optional
installments: installment-ref[]on the package request and the confirmed package. -
Cinema delivery evidence. There is no cinema metric block or settlement artifact, meaning the screening or attendance report by screen and week that exhibitors' ad networks issue.
Proposal: a
cinema_metricsblock (screens, screenings, attendance with its source) and a screening record, following theooh_metrics.postingspattern. -
Print insertion evidence. Per-installment delivery covers issue-level counts, but there is no insertion record. Industry practice is a tear sheet or affidavit per insertion.
Proposal: an insertion record per installment (placement, page or section, tear-sheet reference), again following the postings pattern.
Why it matters
Without these, a buyer can only confirm that an offline order was accepted and that delivery reports arrived. It cannot confirm that the order ran as booked, or that a cancellation was honoured. Linear TV and radio are covered by by_spot in 3.2; the gaps above are what remain across scheduled and offline channels.
Activity
bokelley commentedon Sep 30, 2026
Triage
Outcome: Flag — four normative schema additions; WG ratification required before any implementation.
Milestone: Spec Backlog
Labels added:
needs-wg-review·media-buyProtocol and product review complete. Expert findings are summarised below, followed by a decision memo (DR-0023) for WG consideration.
Expert findings
change_cutoffoninstallment.deadlinescinema_metricsblockx-status: experimental— direct parallel toooh_metrics;available-metric.jsonneeds tokenDR-0023 draft — for WG ratification
Decision
Add optional, non-breaking extensions to AdCP delivery-evidence schemas, in three tiers by readiness.
Tier 1 — ready for spec brief (Gaps 1 and 3)
change_cutoff(string,format: date-time, optional) oninstallment-deadlines.json. Normative text must distinguish: broadcast log/traffic cutoff, OOH posting-cycle lock, print issue close, cinema reel-lock date. Distinct fromcancellation_deadline(penalty-free cancel window) andbooking_deadline(new-booking window); it governs whether a mid-flight change or stop still takes effect operationally.cinema_metricsblock ondelivery-metrics.json,x-status: experimental, mirroring theooh_metricsprecedent. Minimum properties:screens(integer, contracted),screenings({scheduled, actual}integer counts),attendance({modeled, source}— source enum:ticketing_data | exhibitor_report | modeled). Per-screening record parallel toooh_metrics.postings[].{panel_id, occurred_at, evidence}. Addcinema_metricstoken toavailable-metric.jsonenum.Tier 2 — needs WG design session before brief (Gap 2)
installment_selection: installment-ref[]onpackage-request.json; echo field on the confirmed package object. Three questions the WG must resolve before spec is drafted:PRODUCT_UNAVAILABLEvs.INVALID_REQUEST)?Tier 3 — deferred, no committed release (Gap 4)
Print insertion record: deferred to Spec Backlog until: (a) WG resolves placement —
delivery-metrics.jsonblock (parallel toooh_metrics) vs. extension ofinstallment-delivery-metrics.json(more coherent — one insertion = one installment); (b)page/sectionfield — free strings now vs. closed enum (SRDS/PIB position taxonomy); (c) WG affirms thatplacement-evidence.json(url,content_digest, capture metadata) satisfies legal tear-sheet/affidavit use cases.Rationale
All four proposals are non-breaking: optional fields on schemas with
additionalProperties: true, new optional blocks, new enum tokens. Tiers 1 proposals follow directly established patterns with no open design questions. Tier 2 has semantics ambiguity that would produce incompatible implementations if left open. Tier 3 has low near-term adopter value; no active programmatic print channel has surfaced a blocking need.Implications
minorchangeset class, targetingmain(3.2.0-rc.N or 3.3.0); not backportable to3.1.x.sort-metric.jsonenum extension forcinema_metricsbreakdowns is deferred to the implementing PR author.Wire sketches
Gap 1 —
installment.deadlineswithchange_cutoffadded:{ "booking_deadline": "2026-11-01T18:00:00Z", "cancellation_deadline": "2026-11-07T18:00:00Z", "change_cutoff": "2026-11-10T18:00:00Z", "material_deadlines": [ { "stage": "draft", "due_at": "2026-10-15T18:00:00Z" }, { "stage": "final", "due_at": "2026-10-22T18:00:00Z" } ] }Gap 2 — Package request with
installment_selection(shape pending WG resolution):{ "product_id": "pod-morning-run-s3", "installment_selection": [ { "collection_ref": { "publisher_id": "npr", "collection_id": "mr-s3" }, "installment_id": "ep-03" }, { "collection_ref": { "publisher_id": "npr", "collection_id": "mr-s3" }, "installment_id": "ep-04" } ] }Gap 3 —
cinema_metricsdelivery response excerpt:{ "cinema_metrics": { "screens": 450, "screenings": { "scheduled": 3150, "actual": 3087 }, "attendance": { "modeled": 412000, "source": "ticketing_data" }, "screenings_detail": [ { "screen_id": "ncm-la-0042", "occurred_at": "2026-10-04T19:45:00-07:00", "creative_id": "cr-trailer-a", "evidence": { "url": "https://...", "content_digest": "sha256:..." } } ] } }Triage · 2026-09-30 · Claude Code
Generated by Claude Code
feat(schema): add change_cutoff to installment deadlines (#8054)
bokelley commentedon Oct 30, 2026
A fifth gap: live event sponsorship evidence
The same problem shows up for live events, and it fits this issue's pattern.
What already works. Taxonomy v1.1.0 places event sponsorship under
product_placement("Event sponsorships", "Naming rights"), the fee prices asflat_rate, and an installment can represent the event date. A seller can describe and sell the sponsorship today.What's missing is proof that it delivered. There is no delivery shape for:
Without these, a buyer can't tell whether a sponsorship delivered. Nor can it settle the make-good when attendance misses forecast, which is the most common dispute.
Proposal. An experimental
event_metricsblock, followingooh_metrics.postingsand thecinema_metricsproposal above:forecast_attendance,registered,attended, andattendance_source;deliverables[]fulfilment record whose items reference deliverable IDs declared on the product, each withstatusand anevidence_ref.Out of scope: attendee lists and lead sharing. They involve personal data and belong under governance and consent, not delivery metrics. Ads that run at an event (venue screens, for example) keep their own channel, as the taxonomy already says.
Where we hit it. We're building a simulated market in which a fictional publisher, Northstar Journal, runs one conference a quarter. Its sponsors ask for money back when registrations come in under forecast. We currently have to carry attendance in an
extobject, and this issue is the upstream path we'd point to.This looks Normative and experimental, and could ride the same decision memo as gaps 3 and 4.
bokelley commentedon Oct 31, 2026
Part of this shipped: gap 1,
change_cutoffon installment deadlines, in #8054 (3.3.0-beta.0).Gap 2, installment selection on packages, was merged in #8246 but withdrawn to 4.0 by #8537 (3.3.0-beta.2) under the closed
commercial-termsdecision (#8501); it is in the 4.0 work list there. Gaps 3 to 5 (cinema metrics, print insertion record, event metrics) have no PR and no decision, so per the WG rule ('anything not decided moves to 3.4') only the remainder moves to 3.4. Objections by Fri 2026-11-06. The milestone stays 3.3.0 for now; it will be moved after Nov 6.