You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
AdCP webhooks are specced per feature. sync_creatives task completion, reporting_webhook on media buys, mcp-webhook-payload, push_notification_config on async operations, and proposed channels for creative lifecycle (#2261), dependency impact (#2853), and org-level compliance alerts (#1711) each define their own delivery semantics, subscription model, and observability. Each new RFC reinvents the contract. There is no shared log surface, no story for resources that outlive a single media buy, and no canonical contract for what a buyer agent can assume about a persistent push channel.
The result: every new webhook RFC re-litigates at-least-once delivery, coalescence, replay, auth renewal, and the snapshot-vs-log relationship. #4278 (delivery visibility) and #2853 (dependency impact) are both currently drafting the same primitives in parallel.
Goal
One contract for persistent push. One shape for the snapshot+log duality. One subscription model spanning per-resource and per-account scope. Future RFCs reference the foundation instead of re-deriving it.
Design principles
Snapshot is authoritative. The current truth lives on the read API; the webhook is a change signal, not the source of truth.
Push is at-least-once and unordered. Buyers reconcile via the snapshot, not via webhook ordering. Idempotency via stable notification_id.
Every push event has a snapshot delta. A webhook fires when a state visible on a read API changes. No webhook-only state.
Subscription anchors to the resource that outlives the relationship. Media buys carry their own webhook config. Creatives, audiences, properties — which outlive any single buy — anchor at the account.
Replay = re-read the snapshot. No event-replay primitive in v1. If you missed a push, ask the read API for current state.
One contract across all event types. Same delivery semantics for delivery reporting, dependency impact, creative lifecycle, governance alerts. Differ in payload, not in transport.
Tracks
1. Protocol pattern doc — snapshot/log duality
Foundation document under docs/protocols/. Names the five-rule contract:
Every push event has a stable notification_id.
Every push event corresponds to a snapshot delta visible on a read API.
Push is at-least-once; the snapshot is authoritative when they disagree.
Replay = re-read the snapshot. No event-replay primitive in v1.
Push events and log entries share an id space — a webhook delivery references the same id the buyer received in the push body.
Everything else in this epic references this doc.
2. Persistent webhook contract
Codify the on-the-wire delivery contract:
At-least-once delivery; idempotency via notification_id.
No ordering guarantee.
Per-kind coalescence windows (acute / batched).
Mutability of push_notification_config via update_* (without re-creating the resource).
Termination — webhooks keep firing through terminal lifecycle states (e.g., final reporting), then stop.
Both fire against the same webhook URL shape. Differ only in subscription anchor and event scoping.
4. Standardized log surface
Generalize #4278's webhook_activity[] from a media-buy-specific field to a pattern: any resource with a snapshot exposes recent events on read. Includes:
These epics depend on this one; they don't define their own contracts.
Release strategy
Target 3.1.0 for tracks 1–4 (snapshot/log doc, persistent contract, subscription model, log surface). All three currently-active consumer RFCs (#2853, #2261, #4278) need these primitives in 3.1.
Track 5 (auth & transport hygiene) lands incrementally — some items are spec clarifications (#3554, #3555, #3557, #4339), others are migration tracks (#4205) with their own cadence. #4288 is a 4.0 breaking change.
Track 6 (#3245) and track 7 (#2618) follow the rest.
Open questions
Per-account subscription anchor — where does it live in the schema? Account-level notification_configs[] array? Per-resource-type subscription endpoints on the account? Whatever shape, it needs to compose with 4.0: multi-subscriber reporting_webhook on media buys #3009's multi-subscriber direction.
Replay primitive — really out of scope for v1? Catch-up via snapshot works for current-state surfaces, but not for events that don't change current state (e.g., a delivery report fire that already drained from the log). Worth confirming the constraint or scoping in a minimal list_notifications(resource_id, since) tool.
Stable id ownership. Who issues notification_id? Seller agent generates and includes in the push body; buyer dedupes by it. Trivial in single-subscriber case; gets interesting with 4.0: multi-subscriber reporting_webhook on media buys #3009 multi-subscriber (does each subscriber see the same id? probably yes — same event, same id).
Snapshot/log doc location. New file under docs/protocols/ vs. expansion of existing docs/building/implementation/webhooks.mdx. Probably the former — the existing doc is implementation-oriented; the new one is contract-oriented.
Problem
AdCP webhooks are specced per feature.
sync_creativestask completion,reporting_webhookon media buys,mcp-webhook-payload,push_notification_configon async operations, and proposed channels for creative lifecycle (#2261), dependency impact (#2853), and org-level compliance alerts (#1711) each define their own delivery semantics, subscription model, and observability. Each new RFC reinvents the contract. There is no shared log surface, no story for resources that outlive a single media buy, and no canonical contract for what a buyer agent can assume about a persistent push channel.The result: every new webhook RFC re-litigates at-least-once delivery, coalescence, replay, auth renewal, and the snapshot-vs-log relationship. #4278 (delivery visibility) and #2853 (dependency impact) are both currently drafting the same primitives in parallel.
Goal
One contract for persistent push. One shape for the snapshot+log duality. One subscription model spanning per-resource and per-account scope. Future RFCs reference the foundation instead of re-deriving it.
Design principles
notification_id.Tracks
1. Protocol pattern doc — snapshot/log duality
Foundation document under
docs/protocols/. Names the five-rule contract:notification_id.Everything else in this epic references this doc.
2. Persistent webhook contract
Codify the on-the-wire delivery contract:
notification_id.push_notification_configviaupdate_*(without re-creating the resource).finalreporting), then stop.3. Subscription model
Two subscription anchors:
push_notification_configon media buys. Extend pattern to other resources where it makes sense.Both fire against the same webhook URL shape. Differ only in subscription anchor and event scoping.
4. Standardized log surface
Generalize #4278's
webhook_activity[]from a media-buy-specific field to a pattern: any resource with a snapshot exposes recent events on read. Includes:{ "_meta": { "truncated": true, "original_size_bytes": N, "preview": ... } }from RFC: Buyer-side webhook delivery visibility on get_media_buys #4278).delivery_idacross retry attempts.5. Auth & transport hygiene
Cluster of existing open issues that converge here:
required: ["authentication"]from reporting-webhook and artifact_webhook (4.0).{443, 8443}as hardened destination-port allowlist.6. Delivery semantics edge cases
7. Conformance
Out of scope (consumers of this epic, separate tracks)
reporting_webhook(4.0). Extends subscription model from 1→N parties on a single resource.These epics depend on this one; they don't define their own contracts.
Release strategy
Target 3.1.0 for tracks 1–4 (snapshot/log doc, persistent contract, subscription model, log surface). All three currently-active consumer RFCs (#2853, #2261, #4278) need these primitives in 3.1.
Track 5 (auth & transport hygiene) lands incrementally — some items are spec clarifications (#3554, #3555, #3557, #4339), others are migration tracks (#4205) with their own cadence. #4288 is a 4.0 breaking change.
Track 6 (#3245) and track 7 (#2618) follow the rest.
Open questions
Per-account subscription anchor — where does it live in the schema? Account-level
notification_configs[]array? Per-resource-type subscription endpoints on the account? Whatever shape, it needs to compose with 4.0: multi-subscriber reporting_webhook on media buys #3009's multi-subscriber direction.Replay primitive — really out of scope for v1? Catch-up via snapshot works for current-state surfaces, but not for events that don't change current state (e.g., a delivery report fire that already drained from the log). Worth confirming the constraint or scoping in a minimal
list_notifications(resource_id, since)tool.Stable id ownership. Who issues
notification_id? Seller agent generates and includes in the push body; buyer dedupes by it. Trivial in single-subscriber case; gets interesting with 4.0: multi-subscriber reporting_webhook on media buys #3009 multi-subscriber (does each subscriber see the same id? probably yes — same event, same id).Retention SHOULD vs. MUST. Inherited from RFC: Buyer-side webhook delivery visibility on get_media_buys #4278. The foundation should pick a normative stance so consumers don't each re-decide.
Snapshot/log doc location. New file under
docs/protocols/vs. expansion of existingdocs/building/implementation/webhooks.mdx. Probably the former — the existing doc is implementation-oriented; the new one is contract-oriented.Consumers to cross-link