> ## 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.

# What's new in AdCP 3.3

> Adopter overview of the AdCP 3.3 beta: scheduled, human-gated, and offline media in the same buy as programmatic, honest delivery data for linear TV, print, and DOOH, and the places 3.2 implementations could still disagree, now closed.

# What's new in AdCP 3.3

> [!WARNING]
>
> **3.3 is in its beta cycle.** Beta.0 publishes the protocol artifacts before SDK support. Beta.1 incorporates integration feedback, then becomes SDK-backed after a second SDK refresh against the exact beta.1 bundle. Use the beta in development and staging, and read the [3.3 beta program](/dist/docs/3.3.0-beta.0/reference/3-3-beta) before testing. This page lists only what has merged; it is refreshed at each beta cut.

AdCP 3.3 lets scheduled, human-gated, and offline media run through the same buy as programmatic. A booking can say when it will be confirmed. A proposal's third-party definitions are pinned so they cannot drift after commitment. A proposal request can target a vendor-measured outcome, and a governance plan can budget by period. Products, audiences, and delivery reports can carry what a linear-TV, print, or DOOH seller actually knows: spot lifecycle and makegoods, break position, print proof of insertion and circulation, structured DOOH location, property-grain rollups, and audience sizes as honest ranges. Minute-level dayparts, broadcast mezzanine formats, and the NMO and VideoAmp demographic systems fill in the TV edges.

Around that, 3.3 tightens the places where two conformant 3.2 implementations could still disagree: discovery never provisions an account, one agent-resolution rule covers every signing surface, `required_for` is enforced over A2A with its hardening clauses required, and `reporting_webhook.operation_id` correlation fails closed. Catalog intake becomes an optional declaration, verifiers can advertise A2A `required_for` enforcement through `request_signing.operation_sources`, and `ext.adcp` becomes a reserved namespace. New single-adopter surfaces ship as experimental, so 3.4 can reshape them without breaking stable integrations.

No stable field, enum value, or task is removed. Two result fields, one usage, and the RFC 9421 signing profiles are deprecated, all functional throughout 3.x: `seller_id` on event source and audience results (use `platform_id`), the natural key as the account reference after provisioning, and the RFC 9421 profiles (use the experimental Web Bot Auth profile). 3.3 adds optional fields, enum values, and capability declarations. Schema-valid 3.2 messages stay schema-valid except for the new domain identifier format, and unless they already used a name 3.3 now defines with a different shape; the list is in the [migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#what-can-fail-validation). The normative narrowings are recorded in [Versioning and governance](/dist/docs/3.3.0-beta.0/reference/versioning#3-3-exceptions-to-3-x-compatibility-beta) and lead the [migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#required-to-claim-3-3-behavior).

## Scheduled and human-gated buying

* **Account IDs you can rely on.** Sellers SHOULD return `account_id` from `sync_accounts`, and a seller that accepts it on every account-scoped task, for every account, and never changes it declares the optional `account.stable_account_id` capability. Buyers send the ID to those sellers instead of the natural key. Natural keys keep working throughout 3.x, but using them as the reference after provisioning is now deprecated and planned for removal in 4.0; they remain the way to open an account and to look up its ID. See [Toward account IDs everywhere](/dist/docs/3.3.0-beta.0/accounts/overview#toward-account-ids-everywhere).
* **Expected confirmation time.** The `submitted` envelope of `create_media_buy`, `buy_products`, and `accept_proposal` can carry `expected_confirmation_at`. A seller whose confirmation waits on a booking round or a manual review window SHOULD set it, and buyers SHOULD check status at that time instead of polling tightly. It is an estimate, not a commitment. `refine_proposals` can carry it too, on a `submitted` finalize whose hold waits on a person's agreement, such as a creator or host. On `buy_products`, `accept_proposal`, and `refine_proposals`, send it only to callers negotiating 3.3. See [Expected confirmation time](/dist/docs/3.3.0-beta.0/media-buy/task-reference/create_media_buy#expected-confirmation-time).
* **Definition pins.** For callers negotiating 3.3, a seller MUST pin the third-party definitions its proposal terms reference (publisher-catalog format options and placements, `adagents.json` collections, data-provider signals) in `commercial_terms.definition_pins[]`. A changed definition fails finalize with the `definition_changed` reason and fails `accept_proposal` with `REFERENCE_DEFINITION_CHANGED`, before any hold or mutation. See [Definition pins](/dist/docs/3.3.0-beta.0/media-buy/specification#definition-pins).
* **Vendor-metric outcome goals.** `criteria.outcome_target.goal` accepts `kind: "vendor_metric"`, so a buyer can plan "5,000 store visits measured by a foot-traffic vendor", optionally with a cost per visit. The seller answers in each forecast point's `vendor_metric_values[]` and plans only `(vendor, metric_id)` pairs its products declare. Send it only on a negotiated 3.3 version. See [Vendor-metric goals](/dist/docs/3.3.0-beta.0/media-buy/task-reference/request_proposals#vendor-metric-goals).
* **Governance budget periods (experimental).** A campaign governance plan can split its budget by time with `budget.periods[]`. `check_governance` denies a dated action that straddles a period, sits in unallocated budget, or overruns its period. Governance agents declare `governance.supports_budget_periods`. Part of the experimental `governance.campaign` cluster. See [Budget periods](/dist/docs/3.3.0-beta.0/governance/campaign/tasks/sync_plans#budget-periods).
* **Holds you can plan and extend (experimental).** Products and proposals can carry a `hold_policy` (`media_buy.hold_policy`), and `refine_proposals` `extend_hold` lengthens a committed hold without re-finalizing (`media_buy.hold_extension`). See [Hold policy](/dist/docs/3.3.0-beta.0/media-buy/task-reference/refine_proposals#hold-policy-experimental).
* **Delegated composition (experimental).** A platform that owns the catalog can make `product_ids` the complete composable universe with `criteria.product_ids_exclusive`, and a seller that holds no inventory can declare `terms_only` finalize (`media_buy.delegated_composition`). See [delegated composition](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/delegated-composition).
* **Fixed-price, non-guaranteed sellers.** The new `sales-fixed-rate` specialism covers sellers in any medium, digital or linear TV, that publish a fixed price, reserve no inventory, make no delivery commitment, and may hold a buy for review. `get_media_buys` can carry `expected_confirmation_at` while a buy is provisional (`confirmed_at: null`). See [Choosing a sales specialism](/dist/docs/3.3.0-beta.0/building/verification/compliance-catalog#choosing-a-sales-specialism).
* **Renewal and replacement lineage (experimental).** A new buy can name the buy it succeeds with `predecessor_media_buy_id` and `lineage_reason` (`renewal`, `terms_change`, `migration`, `sunset`, `replacement`). The link is forward-only and same-account; the predecessor is never mutated. Feature id `media_buy.lineage`. See [Media Buy Lineage](/dist/docs/3.3.0-beta.0/media-buy/specification#media-buy-lineage).
* **Did a failed mutation apply?** `core/error.json` can carry `mutation_outcome` (`not_applied`, `unknown`, `applied`), so a buyer knows whether to re-plan after a failed state-changing request. See [Mutation outcome](/dist/docs/3.3.0-beta.0/building/by-layer/L3/error-handling#mutation-outcome).
* **Operator fees.** The `operator_fee` price adjustment kind lets an agency's buying platform show a fee it keeps out of the advertiser's budget without changing the seller's price. Sellers never author it. See [Operator fees](/dist/docs/3.3.0-beta.0/media-buy/advanced-topics/pricing-models#operator-fees).
* **Change cutoff.** Installment deadlines can carry `change_cutoff`, the last moment a creative swap, pause, or stop still takes effect (traffic log close, posting-cycle lock, print issue close). See [Installment deadlines](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/collections-and-installments#installment-deadlines).

## Delivery data offline sellers actually have

* **Spot lifecycle, makegoods, and break position (experimental).** `by_spot[]` rows can carry `spot_status` (`scheduled`, `aired`, `preempted`, `makegood`), `scheduled_at`, `replaces_spot_id`, and `break_position`. Sellers declare what they report, so a missing row is not read as non-delivery, and they never send `scheduled` or `preempted` rows, or the new capability fields, to callers pinned below 3.3. Feature id `media_buy.spot_lifecycle`. See [Spot lifecycle](/dist/docs/3.3.0-beta.0/media-buy/media-buys/optimization-reporting#spot-lifecycle-makegoods-and-break-position).
* **Print proof of insertion and circulation (experimental).** `print_metrics` on `by_installment` rows reports the page and position delivered, circulation and its basis (`audited` or `seller_modeled`), and a tearsheet `evidence` record. See [Delivery evidence and circulation](/dist/docs/3.3.0-beta.0/creative/channels/print#delivery-evidence-and-circulation).
* **Property-grain rollups.** `media_buy.features.supports_property_breakdown` and `supports_installment_property_breakdown` commit a seller to return `by_property` and `by_installment_property` on every product that declares the per-product flag. Two capability-gated scenarios grade it. See [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities).
* **Structured DOOH location.** Concrete screens can carry `dooh_placement_attributes.location` (`lat`, `lon`, structured `address`), and network products can carry `dooh_inventory_summary.venue_counts[]`. Both are disclosure metadata; `location` never changes placement identity. See [DOOH](/dist/docs/3.3.0-beta.0/creative/channels/dooh#structured-location-for-planning-and-mapping).
* **Rows without impressions.** Delivery rows may omit `impressions` when the seller did not measure them, for example on rows that report plays or downloads instead. Absence means not measured, never zero; receivers do not derive impression-based rates, and sellers never omit it toward callers pinned below 3.3. See [Rows without impressions](/dist/docs/3.3.0-beta.0/media-buy/media-buys/optimization-reporting#rows-without-impressions).
* **Delivery projection (experimental).** Top-level `by_package[]` delivery rows can carry an advisory `projection` of lifetime impressions and spend with a `projected_end_state` and `basis`. It is a forecast, not a delivery record. Feature id `media_buy.delivery_projection`. See [Delivery projection](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_media_buy_delivery#delivery-projection).
* **Installment lifecycle and proof of publication (experimental).** `by_installment[]` rows can carry `installment_status` and a `publication` record (`published_at`, `posts[]`, optional `evidence`), so a creator post, newsletter edition, or podcast episode reports whether and where it ran. Feature id `media_buy.installment_lifecycle`. See [Installment lifecycle](/dist/docs/3.3.0-beta.0/media-buy/media-buys/optimization-reporting#installment-lifecycle-and-proof-of-publication).
* **Report source custody.** A Reliable Reporting report definition's `source` can say whether the producer is the `system_of_record` or derived its figures `upstream_derived`.
* **Audience sizes as ranges.** `sync_audiences` results can carry `audience_size` and `targetable_size` as bounded ranges with a `precision`, plus `match_rate_basis`. `matched_count` and `effective_match_rate` may now be absent, and buyers MUST NOT read absence as zero. See [Audience size](/dist/docs/3.3.0-beta.0/media-buy/task-reference/sync_audiences#audience-size).

## Creator and collection cards (experimental)

Collections can carry images, sample content, and follower counts, talent can link to its brand identity, and product and proposal responses can return full collection objects on request (`media_buy.collection_cards`, `brand.collection_links`). See [Collection cards](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/collections-and-installments#collection-cards-experimental).

## Open opportunities and later proposals (experimental)

A buyer can keep an opportunity open after the first response and let sellers send more. `opportunity.later_proposals` gives consent with optional `until`, `max_count`, and `min_interval` limits. Sellers then create draft-only later proposals, announce each with the identifiers-only `proposal.created` notification, and serve them through the new [`list_proposals`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/list_proposals) read, which returns each snapshot beside its disposition. `accept_proposal` and `buy_products` accept an explicit `opportunity.status: "open"` so a buyer can buy part of a plan and keep sourcing. Everything is experimental under `media_buy.open_opportunities` and advertised in parts. See [Open opportunities and later proposals](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/proposal-negotiation#open-opportunities-and-later-proposals) and [#8096](https://github.com/adcontextprotocol/adcp/issues/8096).

## Agent identity and buyer self-onboarding (experimental)

A buyer agent can now make itself known to a seller it has never spoken to. The new Web Bot Auth signing profile identifies the signer by its origin and verifies against that origin's key directory, with no capabilities call and no seller-issued credential. The operator's trust.json lists its agents; brands publish grants in theirs, and sellers publish their onboarding posture in `account.agent_onboarding`. `get_principal` reports relationship status and expiry. The RFC 9421 profile is deprecated in 3.3 and works through 3.x. See [A buyer agent onboards itself](/dist/docs/3.3.0-beta.0/accounts/buyer-agent-self-onboarding) and the [agent identity migration guide](/dist/docs/3.3.0-beta.0/reference/migration/agent-identity-3-3).

## Linear TV edges

* **Minute-level dayparts (experimental).** A daypart entry can use `start_time` and `end_time` (`HH:MM`) instead of whole hours, and products declare the finest resolution they honor in `time_granularity`. A seller rejects a finer time with `UNSUPPORTED_FEATURE` and never rounds it. Feature id `media_buy.daypart_granularity`. See [Minute-resolution dayparts](/dist/docs/3.3.0-beta.0/media-buy/advanced-topics/targeting#minute-resolution-dayparts-experimental).
* **Broadcast formats and currencies.** `demographic-system` gains `nmo` (Netherlands) and `videoamp`. `video_hosted` gains the `mxf` container and the `mpeg2`, `avc_intra`, and `xavc` codecs as stable values, plus an experimental `loudness` object (feature id `creative.broadcast_loudness`). See [Broadcast creative](/dist/docs/3.3.0-beta.0/creative/channels/broadcast#loudness-experimental).
* **Broadcast TV guide.** The [broadcast guide](/dist/docs/3.3.0-beta.0/creative/channels/broadcast) now states the reconciliation contract between as-run logs and audience data and walks a CPM-on-demo buy end to end.

## Playback events for hosted video and audio trackers

The `pixel_tracker` `event` enum adds `start`, `first_quartile`, `midpoint`, `third_quartile` and `complete`, so a buyer can attach quartile measurement to `video_hosted` and `audio_hosted` files instead of sending `event: custom` names no seller is obliged to recognize. Downgrades to 3.0.x sellers drop these trackers with an advisory, and 3.2 buyers send them as `custom` events named for the 3.3 value until they move. See the [migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#hosted-video-and-audio-playback-trackers).

## Platform object IDs have one name

`sync_event_sources` and `sync_audiences` results now use optional `platform_id` for the object's ID in the seller's ad platform, matching creatives and catalogs. A seller reporting this ID in 3.3 and later 3.x responses MUST emit both `platform_id` and the deprecated `seller_id` alias with identical values, including discovery responses. Buyers MUST prefer `platform_id` and fall back to `seller_id` only when the new field is absent. Continue using `event_source_id` and `audience_id` in AdCP requests. The aliases keep working throughout 3.x; removal is no earlier than 4.0 under the six-month notice policy. Seller identity in `adagents.json` and publisher identifiers is unchanged. See [Deprecations](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#deprecations).

## Tightened rules

These narrow what a conformant implementation may do. Each is detailed in the [migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#required-to-claim-3-3-behavior) and recorded in [Versioning and governance](/dist/docs/3.3.0-beta.0/reference/versioning#3-3-exceptions-to-3-x-compatibility-beta).

* **Discovery never provisions an account.** Discovery and negotiation tasks MUST NOT create or activate an account or accept default terms. See [Account references before provisioning](/dist/docs/3.3.0-beta.0/accounts/overview#account-references-before-provisioning).
* **One agent-resolution rule.** Request signing, webhook signing, governance JWS `iss`, designated-task response signing, and rights attestations share one algorithm for which brand.json lists an agent and which keys it may sign with. Some signatures that verified under 3.2 now fail. See [Agent resolution](/dist/docs/3.3.0-beta.0/building/by-layer/L1/security#agent-resolution).
* **`required_for` over A2A, hardened.** The A2A operation-resolution errata shipped in 3.2.3. Its hardening clauses were SHOULD in 3.2.x and are MUST from 3.3. Verifiers declare support with the new optional `request_signing.operation_sources` capability; a counterparty MUST NOT infer A2A enforcement from an absent field, and buyers sign every operation in `required_for` regardless of the marker. See [Operation resolution over A2A](/dist/docs/3.3.0-beta.0/building/by-layer/L1/security#operation-resolution-over-a2a).
* **`reporting_webhook.operation_id` fails closed.** The seller echoes it into every `media_buy_delivery` webhook and sends none to a registration that omits it. See [Reporting webhooks](/dist/docs/3.3.0-beta.0/building/by-layer/L3/webhooks#reporting-webhooks).
* **Definition pins** are required for callers negotiating 3.3 (above).
* **Advertise only the measurement terms you accept.** See [Advertise only what you accept](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_products#advertise-only-what-you-accept).
* **Audience identifiers keep their wire form.** `uids[].value` for `uid2` and `euid` is the raw identifier, never the encrypted token, and is never case-folded or re-encoded.
* **brand.json fetch limits.** The cap rises to 2 MiB, with new MUSTs for streaming enforcement, nesting depth, and bounded fetches.
* **Delivery rows may omit `impressions`** toward 3.3 callers only, and receivers MUST NOT read absence as zero or derive impression-denominated values. The schema loosens; the rules around it narrow.
* **Receivers ignore `aggregated_totals` in delivery webhooks** and do not reject a payload for carrying it.
* **Counterparty-asserted domain lists are bounded.** `media_buy.portfolio.publisher_domains` and `signals.data_provider_domains` have a normative byte budget, with completeness flags for truncation; buyers never read absence from either list as a denial. See [below](#nobody-else-gets-to-write-your-capabilities-document).
* **Platform IDs under both names.** A seller reporting an event source or audience platform ID emits `platform_id` and the deprecated `seller_id` alias with identical values. See [Platform object IDs have one name](#platform-object-ids-have-one-name).
* **Property domain identifiers have an enforceable format.** `domain` and `subdomain` values must be lowercase ASCII hostnames; mixed-case, trailing-dot, and URL-shaped values are rejected. See [the migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#property-domain-identifiers-have-an-enforceable-format).
* **Property list references resolve through AdCP tasks.** Issuers expose `get_property_list` over MCP and accept the reference's list-scoped Bearer token; a custom download route alone no longer suffices. See [the migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#property-list-references-resolve-through-adcp-tasks).
* **Flight start activates committed buys only.** A provisional buy (`confirmed_at: null`) never auto-activates; it stays `pending_start` until the seller confirms or rejects it. See [Provisional buys](/dist/docs/3.3.0-beta.0/media-buy/specification#provisional-buys-seller-review-hold).
* **Seller revisions advance on every committed change.** The media-buy `revision` advances on every committed change to the state `get_media_buys` reports, whatever its origin: an AdCP task, a seller operator, seller automation, another authorized principal, a connected platform, or a `sync_creatives` assignment. `history` entries for externally originated changes carry the same `origin.kind` vocabulary as `account.change`, and creatives gain an optional seller-maintained `seller_revision` that `account.change.resource_revision` carries. Buyers that send a stale `revision` will see more `CONFLICT`; that is intended. Recorded as [DR-0031](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0031-seller-revision-any-origin.md). See [the migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#seller-revisions-advance-on-every-committed-change).
* **Multi-qualifier metrics omit flat totals.** When a buy's packages report a metric under more than one qualifier set, such as viewability at `mrc` and `groupm`, the seller omits that metric's flat carrier from buy and window `totals`; read the package rows. See [the migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#multi-qualifier-metrics-omit-flat-totals).
* **Refinement carries compliance forward.** A `build_creative` refinement keeps the parent leaf's required disclosures and prohibited claims, and a refined leaf never inherits approval. See [the migration guide](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#refinement-carries-compliance-forward).

Two more guarantees loosen here, and the response-size default a third ([below](#bounded-agent-responses)): a 3.2 verifier can reject a brand.json between 256 KiB and 2 MiB that a 3.3 verifier accepts, and a `ready` audience no longer promises match counts. Separately, `reporting_webhook.authentication` and `artifact_webhook.authentication` become optional on requests served at 3.3, so an integration can drop HMAC before 4.0 ([details](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#reporting-and-artifact-webhooks-can-omit-authentication)). Many new fields sit inside objects 3.2 closes, so send them only to peers that negotiated 3.3; see [Send only to 3.3 peers](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#send-only-to-3-3-peers).

## Optional declarations

* **Catalog ingestion.** `media_buy.features.catalog_ingestion` declares accepted catalog types, ingestion modes, feed formats, content identifier types, an inline batch limit, and item-status granularity. A declaring seller rejects out-of-declaration requests with `UNSUPPORTED_FEATURE` before changing state. See [`sync_catalogs`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/sync_catalogs#ingestion-compatibility).
* **SDK implementation metadata.** Agents can report `adcp.implementation.sdks[]`: package identifiers, exact resolved versions, and the server components they actually use. Missing metadata means unknown; `sdks: []` reports none. It is self-reported, does not establish approval or change conformance obligations, and cannot justify certification shortcuts without independently trusted evidence. See [implementation metadata](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities#implementation).
* **Targeting error details.** `UNSUPPORTED_FEATURE` for an unsupported or removed targeting dimension SHOULD carry the new `unsupported-targeting-dimension` details. No new error code. See [Rejected targeting dimensions](/dist/docs/3.3.0-beta.0/media-buy/advanced-topics/targeting#rejected-targeting-dimensions).
* **Assignment landing pages and trackers.** A seller that declares `creative.supports_assignment_landing_page` accepts a per-assignment `landing_page_url` that changes one creative's destination on one package without touching the library creative, and one that declares `creative.supports_assignment_trackers` fires assignment-scoped measurement `trackers` alongside the creative's own. See [Assignment landing pages](/dist/docs/3.3.0-beta.0/creative/task-reference/sync_creatives#assignment-landing-pages).
* **Age determination basis on signals.** Signal listings, definitions, and enrichment can carry an optional `age_determination_bases` (`verified`, `declared`, `inferred`) next to `demographic_predicate`, so a buyer who sets `accepted_bases` can tell a verified age cohort from a modelled one. A signal listing passes the basis test only when its age range is within it and every one of its bases is accepted; absent means no basis claim. The field is stable, completing the basis vocabulary already on the wire as `accepted_bases`, `supported_bases`, and `applied_bases`. On 3.2, carry it as `ext.adcp.age_determination_bases`. See [Migrating from 3.2 to 3.3](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#age_determination_bases-on-signals).
* **Several collection lists per package (experimental).** `collection_lists` and `collection_lists_exclude` let a package run on the intersection of several lists and exclude their union. Feature id `media_buy.collection_lists`. See [Combining several collection lists](/dist/docs/3.3.0-beta.0/governance/collection/index#combining-several-collection-lists-experimental).
* **Signal readiness (experimental).** `get_signals` results can carry `signal_status` (`processing`, `ready`, `failed`) and the `source_audience_id` a custom segment was built from. Feature id `signals.signal_lifecycle`. See [Custom segments built from a seed audience](/dist/docs/3.3.0-beta.0/signals/tasks/get_signals#custom-segments-built-from-a-seed-audience).
* **Event source archive.** A seller that declares `media_buy.event_source_archive` accepts `archived` on `sync_event_sources` items to archive or restore a source without losing its configuration. See [Archiving an event source](/dist/docs/3.3.0-beta.0/media-buy/task-reference/sync_event_sources#archiving-an-event-source).
* **Creative and brand.** `list_creatives` echoes creative-level `provenance`; brand.json gains a brand-wide `prohibited_terms` list; rights constraints can carry advisory `channels[]` and `excluded_channels[]` (experimental, `brand.rights_lifecycle`); and the HTML-markup legacy formats project to `display_tag` inline markup instead of `html5`.
* **The `ext.adcp` namespace.** `ext.adcp` is a registered, AdCP-owned extension namespace. Its first member is an optional `opportunity` binding for cooperating 3.2 `get_products` integrations. See [AdCP opportunity extension](/dist/docs/3.3.0-beta.0/building/by-layer/L2/context-sessions#adcp-opportunity-extension).

## Bounded agent responses

A seller agent that answers a discovery call with tens of megabytes is an availability attack on every buyer that reads the body before checking its size. 3.3 adds [Response size bounds](/dist/docs/3.3.0-beta.0/building/by-layer/L1/security#response-size-bounds): clients SHOULD bound every AdCP response they read, enforce the bound while the body is received rather than after buffering or parsing, cover SSE per event and cumulatively, surface an oversized response as an error rather than truncating it, and bound JSON depth and node count once the byte cap passes — the byte cap bounds ingress, the parse bounds bound memory. The default is 4 MiB, matching what the SDKs and the hosted grader ship, and 4 MiB is the ceiling on what any default may be.

This is a recommendation, not a conformance requirement, but the interop effect is real in both directions. A buyer adopting the default rejects a response it would previously have buffered, and the rejection arrives as a mid-body connection abort rather than an `adcp_error`. A buyer still on the older 1 MiB figure rejects a response a 3.3 buyer accepts.

The seller-side counterpart matters more than the number: keep discovery responses small. `tools/list`, `get_adcp_capabilities`, and the A2A agent card are the first bytes a counterparty reads, and an oversized one makes an agent unreachable rather than slow. `get_adcp_capabilities` is the sharpest case — above `MAX_CAPABILITIES_BYTES` your signing keys stop resolving too. See [Discovery responses stay small](/dist/docs/3.3.0-beta.0/building/concepts/managing-response-size#discovery-responses-stay-small).

### Bounded inbound push and webhook bodies

The response bound covers what a client reads on its own call path. 3.3 adds the receiver-side counterpart: [Inbound body bounds](/dist/docs/3.3.0-beta.0/building/by-layer/L1/security#inbound-body-bounds). Receivers of A2A push notifications and AdCP webhooks (reporting, artifact, collection-list, and account notification subscribers) SHOULD pre-reject an over-limit `Content-Length`, count decoded bytes while streaming, apply the 64-deep, 100,000-member parse bounds after the byte cap and before RFC 9421 or Web Bot Auth verification, apply connect, idle, and total deadlines, and reject with HTTP 413 rather than truncating. The default cap is 4 MiB, generalizing the attestation task-body cap rather than adding a new number, and a tighter per-feature cap governs. This is a recommendation, not a conformance requirement.

## Nobody else gets to write your capabilities document

Two capability fields enumerate relationships a *counterparty* asserts:
`media_buy.portfolio.publisher_domains` and `signals.data_provider_domains` are both
populated from those counterparties' `/.well-known/adagents.json`, which any domain
owner publishes unilaterally and without the named agent's consent. An agent that
mirrored every publisher claiming it had handed an unauthenticated stranger a write
primitive into its own discovery document — and since the signing-key path fetches
that document unnarrowed under `MAX_CAPABILITIES_BYTES`, pushing it past 64 KiB cost
the victim *signature verification*, arriving a cache cycle later with no visible
connection to its cause.

3.3 adds a normative byte budget — one eighth of the capabilities budget for any
single counterparty-asserted field, one quarter for both together — and declares
structural bounds (100 unique entries, 253 characters each) that the conformance
storyboard grades in 3.x and the schema enforces in 4.0. No previously-valid
document becomes schema-invalid; what changes is what counts as conformant. Because a bounded
list would otherwise make a large legitimate network look unauthorized for most of
its own inventory, the bound ships with `publisher_domains_complete` and
`data_provider_domains_complete` — default `true`, set `false` when you truncate.
Both lists are explicitly non-exhaustive, so a buyer must resolve the publisher named
on a product through that publisher's own `adagents.json` and must never read absence
from the list as a denial.

## Account change feed: recognize your own changes

The experimental account change feed (`account.change_feed`) gains two changes ahead of graduation. A record whose `origin.kind` is `adcp` can echo the originating request's `idempotency_key`, so a buyer recognizes its own changes on a shared account; the seller includes it only on records served to the principal that sent the request, and every other reader sees the same record without it. And `changed_paths` is now required when `origin.kind` is `adcp` or `seller_operator`, staying best-effort for `seller_system` and `connected_platform`. See [`list_account_changes`](/dist/docs/3.3.0-beta.0/accounts/tasks/list_account_changes#recognizing-your-own-changes).

## Experimental in 3.3

New feature ids are `media_buy.spot_lifecycle`, `media_buy.daypart_granularity`, `creative.broadcast_loudness`, `media_buy.hold_policy`, `media_buy.hold_ranking`, `media_buy.installment_holds`, `media_buy.hold_extension`, `media_buy.delegated_composition`, `media_buy.collection_cards`, `media_buy.collection_catalog`, `brand.collection_links`, `media_buy.open_opportunities`, `media_buy.lineage`, `media_buy.delivery_projection`, `media_buy.installment_lifecycle`, `media_buy.collection_lists`, `media_buy.offline_delivery_metrics`, `signals.signal_lifecycle`, `signing.web_bot_auth`, `account.agent_onboarding`, `security.profiles`, and `identity.trust_json`. `media_buy.offline_delivery_metrics` registers the new `print_metrics` block together with the 3.2 `ooh_metrics` block. `identity.trust_json` publishes the `trust.json` v1 schemas, identifying agents by origin with no keys in the record; the Web Bot Auth profile reads it, and publishers declare nothing ([trust.json](/dist/docs/3.3.0-beta.0/reference/trust-json)). Governance budget periods extend the existing `governance.campaign` cluster, `get_principal` relationship status extends `protocol.principal`, and rights channel restrictions extend `brand.rights_lifecycle`. The `creative.evaluator` surface on `build_creative` drops its account-arranged `evaluator_id` source form and withdraws the `list_evaluators` follow-on: sources are now inline `exemplars` or an allowlisted `agent_url`, and a seller's house evaluator is an agent it lists in `creative_policy.accepted_verifiers[]` ([migration](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#experimental-creative-evaluator-drops-evaluator_id)). Reliable Reporting carries a new breaking-change notice: older superseded snapshots [may be compacted](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#superseded-reporting-snapshots-may-be-compacted) no earlier than the first minor after November 20, 2026. The per-surface status table is in the [release notes](/dist/docs/3.3.0-beta.0/reference/release-notes#experimental-surfaces-in-3-3).

## Clarifications and conformance

* **Broadcast TV certification.** `sales-broadcast-tv` now certifies one authorized TV transaction on a guaranteed or a non-guaranteed fixed-price path. Existing claimants should expect new checks; 1.0.x claims have a grace window.
* **Signing buyers serve `get_adcp_capabilities`** at their agent URL, because request-signature discovery starts there. See [request signing](/dist/docs/3.3.0-beta.0/building/by-layer/L1/request-signing).
* **Fixed-rate certification.** The `sales_fixed_rate` storyboard grades the new `sales-fixed-rate` specialism; its optional hold phases run only when the seller advertises the `force_media_buy_confirmation` controller scenario.
* **Hold-failure testing.** The experimental `force_hold_unavailable` controller scenario lets a runner reach the all-or-none hold-failure path; storyboards that use it are still in review.
* **Storyboard and schema fixes.** Storyboards that seed a sandbox fixture account send `sandbox: true` explicitly, and `validate_input` warning items now declare `field` as a string, so a warning whose `field` is not a string fails validation.
* **New storyboards.** `media_buy_seller/unprovisioned_account_reference` (advisory until runner capability `14.1.0`), and capability-gated `media_buy_seller/stable_account_id`, `media_buy_seller/definition_pin_drift`, `governance/budget_periods`, `media_buy_seller/property_delivery_reporting`, `media_buy_seller/installment_property_delivery_reporting`, `media_buy_seller/outcome_target_vendor_metric`, and `media_buy_seller/outcome_target_event_cost`.

The storyboard changes affect grading, not the wire.

## Already shipped in 3.2.2, 3.2.3, and 3.2.4

These merged on `main` during the 3.3 cycle and were also released on the 3.2 line. They appear again in the 3.3.0 changelog but are not new to 3.2.4 adopters.

* **3.2.2:** the account-reference clarification and the trust-docs consistency fixes ([`v3.2.2`](https://github.com/adcontextprotocol/adcp/releases/tag/v3.2.2)).
* **3.2.3:** the A2A operation-resolution security errata ([GHSA-2pm6-6mc8-8xcm](https://github.com/adcontextprotocol/adcp/security/advisories/GHSA-2pm6-6mc8-8xcm)) with hardening at SHOULD, the `adagents.json` agent-URL clarification, the evaluator feature-membership fix, storyboard capability gates for wholesale discovery and finalize replay, the polling-based `sales-guaranteed` path, the `validate_input` gates, and the acceptance-policy sandbox account ([`v3.2.3`](https://github.com/adcontextprotocol/adcp/releases/tag/v3.2.3)).
* **3.2.4:** the experimental `REVISION_UNREADABLE` reporting issue, `requires: [controller]` on controller-seeded storyboards and five storyboard fixes, request-signing step-1 vectors with the `negative/026` re-code, complete `profile-3.2` mirrors and step-5 canonicalization vectors, envelope composition and the bundled provenance hoist, the product channel-declaration guidance, and the principal-layer buyer walkthrough ([`v3.2.4`](https://github.com/adcontextprotocol/adcp/releases/tag/v3.2.4)).

## What requires adopter attention

| If you are… | Review before advertising 3.3 |
| - | - |
| A seller that provisions accounts lazily | Stop provisioning on discovery tasks. |
| A seller with a media-buy, account or creative revision | Advance it on every committed change from any origin, including `sync_creatives` assignments and ingested connected-platform changes; add `origin` to `history` entries. |
| A buyer that passes `revision` on updates | Expect `CONFLICT` after seller, connected-platform or `sync_creatives` changes; re-read and retry with the new `revision`. |
| A signing or verifying implementation | Resolve agents by canonical URL from `identity.brand_json_url`, publish every pinned key in your JWKS, apply the A2A hardening clauses, and raise the brand.json cap to 2 MiB. |
| A seller sending delivery webhooks | Echo `reporting_webhook.operation_id`, and send nothing to a registration without one. |
| A seller returning proposals | Pin covered third-party definitions for 3.3 callers, and advertise only measurement terms you accept on replay. |
| A fixed-price, non-guaranteed seller | Claim `sales-fixed-rate`; keep a held buy in `pending_start` until you confirm or reject it. |
| A seller that wants to send proposals after the first response | Opt in to `media_buy.open_opportunities`: advertise `list_proposals` first, then `later_proposals` with a `max_open_duration`, and honor buyer consent and limits. |
| A linear TV, print, or DOOH seller | Adopt the delivery fields you can populate; gate 3.3-only rows and fields on the negotiated version. |
| An SDK maintainer | Generate from the signed beta.0 tarball and check the [SDK-facing changes](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#sdk-and-code-generator-maintainers). |
| A seller that returns account IDs | Return `account_id` from `sync_accounts`; declare `account.stable_account_id` once it is accepted on every account-scoped task and never changes. |
| A buyer that sends natural keys after provisioning | Store the returned `account_id` and send it to sellers that declare `stable_account_id`; natural-key references are deprecated ahead of 4.0. |
| A seller reporting event source or audience platform IDs | Emit `platform_id` and the deprecated `seller_id` alias with identical values, including discovery responses. |
| A buyer consuming event source or audience platform IDs | Prefer `platform_id`, fall back to `seller_id` when absent, and keep using buyer object IDs in AdCP requests. |
| A seller with a catalog intake | Declare `catalog_ingestion` if buyers need your limits, and reject out-of-declaration requests before mutation. |
| A seller advertising `account.change_feed` | Include `changed_paths` on every `adcp` and `seller_operator` record; optionally echo `idempotency_key` on `adcp` records, to the sending principal only. |
| A buyer or SDK maintainer | Adopt the 4 MiB response-size default; size your aggregate budget, not just the per-call one, if you fan out across agents. |
| Any agent operator | Measure `tools/list`, `get_adcp_capabilities`, and your agent card. Oversized discovery makes you unreachable, and oversized capabilities also breaks signing-key discovery. |
| A buyer operating a webhook or push-notification receiver | Bound the request body (4 MiB default) before signature verification, and answer an over-limit request with 413. |
| A compliance operator | Treat beta.0 as an implementation input. Do not issue a 3.3 badge from beta.0. |

## In review for 3.3

Open 3.3 proposals are not part of any beta until they merge. Five working-group decisions are ratified, and their normative text has merged:

* **Agent identity is an origin ([DR-0023](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0023-agent-identity-is-an-origin.md)).** Merged: the [Web Bot Auth profile](/dist/docs/3.3.0-beta.0/building/by-layer/L1/wba-profile) [#7894](https://github.com/adcontextprotocol/adcp/pull/7894), Web Bot Auth identities and the deprecation of the RFC 9421 brand.json profile [#8162](https://github.com/adcontextprotocol/adcp/pull/8162), first-contact binding [#8168](https://github.com/adcontextprotocol/adcp/pull/8168), the buyer walkthrough and migration guide [#8172](https://github.com/adcontextprotocol/adcp/pull/8172), the experimental production security profile [#8155](https://github.com/adcontextprotocol/adcp/pull/8155), seller onboarding posture [#8170](https://github.com/adcontextprotocol/adcp/pull/8170), and the R7/R8 erratum [#8219](https://github.com/adcontextprotocol/adcp/pull/8219). Open: `request_account` [#8293](https://github.com/adcontextprotocol/adcp/pull/8293).
* **Responses conform to the served release ([DR-0024](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0024-responses-conform-to-served-release.md), [#8117](https://github.com/adcontextprotocol/adcp/pull/8117)).** Merged. The rule is in [Serving an older pin](/dist/docs/3.3.0-beta.0/reference/versioning#serving-an-older-pin); grading is open in [#8156](https://github.com/adcontextprotocol/adcp/pull/8156).
* **Demand-side grants ([DR-0025](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0025-demand-side-grants-in-trust-json.md)).** Merged: [#8157](https://github.com/adcontextprotocol/adcp/pull/8157), [#8169](https://github.com/adcontextprotocol/adcp/pull/8169).
* **JWS artifacts use the Web Bot Auth key directory ([DR-0026](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0026-jws-artifacts-use-the-wba-key-directory.md), [#8299](https://github.com/adcontextprotocol/adcp/pull/8299)).** Merged. It amends DR-0023: governance contexts, designated-task response signatures, and rights attestations from a listed origin verify against its key directory in 3.3.
* **Seller revisions advance on every committed change ([DR-0031](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0031-seller-revision-any-origin.md), [#8159](https://github.com/adcontextprotocol/adcp/pull/8159)).** Merged; recorded in [#8389](https://github.com/adcontextprotocol/adcp/pull/8389). See [Tightened rules](#tightened-rules).

Proposed records DR-0027 to DR-0030 (mutation outcome, `sales-fixed-rate`, delivery projection, and lineage) describe surfaces merged for beta.0 and await ratification. The open proposals are listed in the [3.3 beta program](/dist/docs/3.3.0-beta.0/reference/3-3-beta#in-review-for-3-3).

## Start here

1. Read the [3.3 beta program](/dist/docs/3.3.0-beta.0/reference/3-3-beta).
2. Follow [Migrating from 3.2 to 3.3](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3).
3. Choose the exact package and support level in [Choose your SDK](/dist/docs/3.3.0-beta.0/building/by-layer/L4/choose-your-sdk).
4. Use the [Release Notes](/dist/docs/3.3.0-beta.0/reference/release-notes#version-3-3-0) for the cumulative record.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.