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

# Experimental Status

> How AdCP marks surfaces that are in the spec but not yet frozen. What experimental means for implementers, what changes inside 3.x, and how an experimental surface graduates to stable.

Some AdCP surfaces are published in a release but not yet frozen. They are shipped so implementers can begin building against them, but they carry a weaker stability contract than stable surfaces. This page defines that contract.

Experimental status is the escape valve that keeps the [3.x stability guarantees](/dist/docs/3.3.0-beta.0/reference/versioning#3x-stability-guarantees) credible. A surface is either stable — in which case it cannot break inside 3.x — or explicitly experimental, in which case it can. There is no undeclared middle ground. For a list of the protocol's non-goals and deferred items, see [Known Limitations](/dist/docs/3.3.0-beta.0/reference/known-limitations).

***

## What counts as experimental

An AdCP surface is experimental when both of the following are true:

1. Its schema carries `x-status: experimental` at the schema root or on the specific property.
2. A seller implementing it declares the surface in `experimental_features` on its `get_adcp_capabilities` response.

Both markers are required. The first tells the ecosystem the surface is not frozen; the second tells a specific buyer that this specific seller has opted in to the experimental contract for this surface.

A seller that implements any experimental surface MUST list it in `experimental_features`. Sellers that do not list an experimental surface MUST NOT implement it — there is no "silently experimental" mode.

An experimental feature id covers a cluster of related tasks. A seller that implements any task in the cluster (e.g., `get_rights` but not `acquire_rights` or `update_rights`) MUST still declare the cluster's feature id (`brand.rights_lifecycle`). Partial implementation is allowed; silent implementation is not.

> [!NOTE]
>
> `x-status: experimental` is a schema-local annotation. It is not inherited through `$ref` — a stable schema that references an experimental sub-schema does not automatically become experimental. The `experimental_features` declaration on `get_adcp_capabilities` is the authoritative runtime signal; `x-status` is an authoring hint for schema readers and tooling.

## Contract for experimental surfaces

**Inside 3.x, experimental surfaces MAY change in ways that stable surfaces cannot:**

* Fields may be renamed, removed, or have their type changed
* Required fields may become optional and vice versa
* Enums may have values removed or renamed
* Task names may be renamed or removed
* Error codes introduced for an experimental surface may be renamed or removed

**Notice requirements for breaking changes to experimental surfaces:**

* At least **6 weeks** published in release notes and the changelog before the change lands
* A migration note describing the change, with before/after examples where possible
* Where feasible, an alias accepting both old and new forms in the release that introduces the change

This is a deliberate relaxation of the [6-month deprecation notice](/dist/docs/3.3.0-beta.0/reference/versioning#deprecation-policy) that applies to stable surfaces.

> [!TIP]
>
> **Why experimental exists.** The architecture committee uses this label on surfaces that are genuinely part of the core protocol but not yet field-tested. Without an iteration path, AdCP would either ship rigid schemas nobody has deployed or hold features back until they are perfect. Neither serves implementers.

**What does not change for experimental surfaces:**

* Authentication, transport, and core security requirements. These are version-level concerns and never change inside 3.x, experimental or not.
* Idempotency semantics. A seller's declared idempotency contract applies to experimental surfaces the same way it applies to stable ones.
* Error envelope shape. Experimental surfaces return errors using the same envelope as stable surfaces; only the specific codes may shift.

## Graduation to stable

An experimental surface graduates to stable when ALL of the following are met:

| Criterion | Requirement |
| - | - |
| **Production signal** | At least one implementation running in **production** (not sandbox) for **≥45 days**. |
| **Cross-party validation** | Either (a) a second implementation exists and has been running for ≥45 days, with at least one of the two in production, OR (b) at least one buyer has successfully integrated against the surface in production. Solo-implementer graduation without buyer integration is not allowed. |
| **Schema stability** | No open breaking-change issues against the surface for **≥30 days** prior to graduation. |
| **Deliberate promotion** | A graduation PR removes `x-status: experimental` from the schema and removes the feature id from the canonical experimental list, called out in the release notes for the 3.x release that carries the change. |

Two implementers is a lower bar than one because cross-implementation friction is what shakes out spec ambiguity. A single implementer can match their own schema by reflex; two cannot. When only one implementer is ready, buyer-integration signal substitutes — that signal covers the buyer-side ergonomic bugs that a solo implementer would otherwise miss.

Graduation is never automatic. The architecture committee reviews graduation PRs and may require additional cycles if the surface still shows signs of instability.

### Graduation cadence

The architecture committee reviews experimental surfaces at each 3.x release. Every release's notes include, for each experimental surface:

* Current status (still experimental / on track to graduate / under active breaking revision)
* A list of changes the next release is expected to carry
* A pointer to the most recent breaking-change notice for the surface, when applicable

Enterprise procurement teams can subscribe to release notes to track experimental surfaces on a predictable review cadence; there is no separate mailing list or ticketing process.

## Client behavior

Buyers integrating against AdCP sellers SHOULD:

* **Inspect `experimental_features` before relying on experimental surfaces.** A seller that does not list an experimental surface is asserting it does not implement that surface.
* **Pin to specific 3.x releases** when depending on experimental surfaces, or subscribe to release notes for the features they consume.
* **Design retry and error handling to tolerate new error codes** added to experimental surfaces between releases.
* **Treat experimental surfaces as unsuitable for regulated workflows** without additional vendor assurance. Experimental is not a claim of compliance-grade stability.

### Buyer-side refusal

Buyers that do not want to interact with experimental surfaces — typically for regulated workflows, compliance-sensitive deployments, or procurement policies that forbid non-frozen features — enforce this client-side. The pattern:

1. **At capability discovery**, read `experimental_features` from the seller's `get_adcp_capabilities` response.
2. **Filter before invocation.** Do not call tasks that belong to experimental feature ids your policy rejects. The list of tasks per feature id is published in the canonical experimental-surfaces list below.
3. **Short-circuit upstream.** When an orchestrator or upstream caller requests behavior that would require an experimental surface, return a policy-level error (e.g., the caller's own `POLICY_EXPERIMENTAL_REFUSED`) rather than attempting the call. The refusal is the buyer's concern, not the seller's — sellers MUST NOT be expected to infer buyer policy.

There is no general wire-level refusal field in 3.0. Buyer-side filtering remains the rule for accepting or refusing experimental behavior. The experimental [`sync_principal`](/dist/docs/3.3.0-beta.0/protocol/sync_principal) task adds a deliberately narrower reciprocal surface for durable connection resources: callers can declare supported reporting destination paths and webhook registrations, but it does not mirror the seller capability document or carry a generic feature-refusal policy.

## Current experimental surfaces

Schemas marked with `x-status: experimental` are the authoritative source. The canonical list of feature ids for `experimental_features` in AdCP 3.x:

| Feature id | Surface | Why experimental |
| - | - | - |
| `protocol.principal` | [`sync_principal`](/dist/docs/3.3.0-beta.0/protocol/sync_principal), [`get_principal`](/dist/docs/3.3.0-beta.0/protocol/get_principal), `adcp.principal` capability discovery, and the caller-scoped reusable reporting destination schemas | Introduces a durable authenticated-principal relationship layer between global seller capabilities and advertiser accounts. Stable-principal mapping, key rotation, optimistic concurrency, destination proof, suspension/revocation timing, and multi-account destination reuse need cross-party implementation experience before freezing. |
| `account.change_feed` | The account change feed: [`list_account_changes`](/dist/docs/3.3.0-beta.0/accounts/tasks/list_account_changes) (schemas: `account/list-account-changes-request.json`, `account/list-account-changes-response.json`), the `account.change_recorded` notification type and its `core/account-change-recorded-webhook.json` payload, the `account.change_feed` capability block on [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities), and the `CURSOR_EXPIRED` error code | Durable, ordered account-scoped change feed for shared advertiser accounts, shipped in 3.2 while [RFC #6810](https://github.com/adcontextprotocol/adcp/issues/6810) is still open. Production evidence is arriving but is not yet complete. Scope3 is building the first cross-party production use: an embedded seller agent that produces the feed (`account.change_recorded` and `list_account_changes`) for `media_buy` (packages coalesced under the buy) and `creative`, with changes from AdCP tasks, seller operators, and its connected ad server, and a storefront consumer that drains the feed and rereads with `get_media_buys` and `list_creatives`, with scheduled polling as the fallback. The [production-signal and buyer-integration criteria](#graduation-to-stable) are met only once the producer has run in production for 45 days with the storefront integrated; that clock starts when the producer reaches production, and the dates will be posted on [RFC #6810](https://github.com/adcontextprotocol/adcp/issues/6810). Two changes are folded in before graduation, because requiring `changed_paths` after graduation would be breaking: `adcp`-origin change records echo the originating request's `idempotency_key`, visible only to the principal that sent the request, and `changed_paths` is required for `adcp` and `seller_operator` origins (best-effort for `seller_system` and `connected_platform`). Graduation targets 3.3 GA if the clock has run by then and the schema-stability window is met after these changes; otherwise the feed stays experimental into 3.4. Requiring `changed_paths` tightens the 3.2 experimental surface, so it carries the 6-week notice above, and buyers should tolerate its absence from a 3.2 seller. Record shape, resource-type coverage beyond `media_buy` and `creative`, and cursor semantics may still change until it graduates. |
| `account.agent_onboarding` | The [`account.agent_onboarding`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities#accountagent_onboarding) block on `get_adcp_capabilities`, with `core/agent-onboarding.json` and its mode and requirement-kind enums ([#8113](https://github.com/adcontextprotocol/adcp/issues/8113)), and the buyer posture `core/buyer-onboarding-posture.json` in the trust.json `profiles.adcp.onboarding` slots, on an agent entry and at record level ([#8114](https://github.com/adcontextprotocol/adcp/issues/8114)) | Seller onboarding posture is new, and the mode and requirement vocabulary may change as sellers publish it. The `open` mode is usable only with the experimental Web Bot Auth profile. |
| `media_buy.open_opportunities` | Open opportunities: [`list_proposals`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/list_proposals) (schemas: `media-buy/list-proposals-request.json`, `media-buy/list-proposals-response.json`), `opportunity.later_proposals` consent and its `core/later-proposals-state.json` echo, the `proposal.created` notification type and its `core/proposal-created-webhook.json` payload, the `proposal-disposition` and `later-proposal-reason` enums, explicit `opportunity.status: "open"` on `accept_proposal` and `buy_products`, an empty `decline_proposals` `declines` array with an `opportunity` update, and the `media_buy.open_opportunities` capability block — see [Open opportunities and later proposals](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/proposal-negotiation#open-opportunities-and-later-proposals) | Seller-initiated proposals after a task completes are new to AdCP, proposed in [#8096](https://github.com/adcontextprotocol/adcp/issues/8096). The default consent limits (5 proposals, 1 day apart), the disposition vocabulary, and the 30-day terminal retention are proposed values that may change once sellers and buyers run it. |
| `brand.rights_lifecycle` | [`get_rights`](/dist/docs/3.3.0-beta.0/brand-protocol/tasks/get_rights), [`acquire_rights`](/dist/docs/3.3.0-beta.0/brand-protocol/tasks/acquire_rights), [`update_rights`](/dist/docs/3.3.0-beta.0/brand-protocol/tasks/update_rights); the `brand.rights`, `brand.right_types`, `brand.available_uses`, and `brand.generation_providers` capability fields on `get_adcp_capabilities`; the `right-use` and `right-type` enums that these surfaces reference, and the advisory `channels[]` and `excluded_channels[]` restriction on `core/rights-constraint.json` with its `RIGHTS_CHANNEL_VIOLATION` advisory code (#5542) | Legal-construct surface added late in the 3.0 cycle. First enterprise deployments will expose edge cases in partial rights, sublicensing, revocation, and dispute resolution. The two enums are marked experimental because their values are expected to evolve as new licensable-use categories surface (e.g. embodiment, hologram, generative-music-style). The `channels` / `excluded_channels` restriction is advisory (SHOULD NOT place) in 3.3 and may tighten to a hard MUST NOT once enforcement patterns emerge; a `platforms` axis is deferred. A creative agent or seller that enforces a rights constraint it received, including by emitting `RIGHTS_CHANNEL_VIOLATION`, is not implementing the rights lifecycle and does not declare `brand.rights_lifecycle`. |
| `governance.campaign` | [`sync_plans`](/dist/docs/3.3.0-beta.0/governance/campaign/tasks/sync_plans), [`check_governance`](/dist/docs/3.3.0-beta.0/governance/campaign/tasks/check_governance), [`report_plan_outcome`](/dist/docs/3.3.0-beta.0/governance/campaign/tasks/report_plan_outcome), [`get_plan_audit_logs`](/dist/docs/3.3.0-beta.0/governance/campaign/tasks/get_plan_audit_logs), the cross-role `adcp.governance_enforcement` capability and signed-context consumption contract, and [budget periods](/dist/docs/3.3.0-beta.0/governance/campaign/tasks/sync_plans#budget-periods) (`budget.periods[]` and the `governance.supports_budget_periods` capability, added in 3.3) | Multi-party governance semantics (buyer vs service approval conflicts, audit provenance verification, task-scoped enforcement, and tie-breaking under Embedded Human Judgment) are not yet settled. |
| `measurement.core` | The `measurement` capability block and seller `media_buy.performance_feedback` block on [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities), compact performance-feedback assertion and receipt fields, and the `measurement` value in `supported_protocols` | Measurement currently exposes vendor metric catalog discovery and task-based compact feedback production. Attribution, pricing/coverage, seller application disposition, and baseline compliance storyboards are not frozen, so the surface remains experimental in 3.1. |
| `measurement.gateway` | The `measurement_gateway` capability block on [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities#measurement_gateway) and its task-based provider interchange contract | The buyer-orchestrator gateway initially reuses `get_media_buy_delivery` and `provide_performance_feedback`. Authorization, identifier mapping, and cross-seller disclosure need implementation experience before the role can freeze; webhook and offline paths are explicitly deferred. |
| `trusted_match.core` | [TMP](/dist/docs/3.3.0-beta.0/trusted-match/) | Privacy architecture is thinly specified relative to what a regulator deep-dive will demand. Exposure tokens, country-partitioned identity, and Offer creative data are expected to change. |
| `trusted_match.verified_identity` | The `attestation` object on `identity-match-request` entries, the top-level `sealed_credentials[]` array, the `world_id_nullifier` value in the `uid-type` enum, the `attestation-claim` enum, and `brand.json` `identity_relying_parties[]` — see [Verified Identity Attestation](/dist/docs/3.3.0-beta.0/trusted-match/specification#verified-identity-attestation) | Verifiable proof-of-personhood / age forwarded into Identity Match so buyers verify rather than trust an assertion. Issuer-agnostic, but only the World ID scheme is specified so far; the `signal_binding` freshness policy, the issuer/scheme registry-vs-free-form decision, and the `brand.json` variant placement are WG-open. The widening of the otherwise-`additionalProperties:false` identity-match-request schema is contract-bearing and may be revised under experimental. |
| `security.profiles` | The `security_profiles` capability on `get_adcp_capabilities` and the [`adcp-prod-security-3.3` profile](/dist/docs/3.3.0-beta.0/building/by-layer/L1/production-security-profile) ([#7066](https://github.com/adcontextprotocol/adcp/issues/7066)) | The profile's requirements and admission preconditions may change as its seller and buyer conformance storyboards land. It admits both signing profiles. It graduates once a second implementation passes the storyboards and has run for the period this page requires. Profile ids are immutable, so a changed requirement ships under a new id. |
| `sponsored_intelligence.core` | [`si_get_offering`](/dist/docs/3.3.0-beta.0/sponsored-intelligence/tasks/si_get_offering), [`si_initiate_session`](/dist/docs/3.3.0-beta.0/sponsored-intelligence/tasks/si_initiate_session), [`si_send_message`](/dist/docs/3.3.0-beta.0/sponsored-intelligence/tasks/si_send_message), [`si_terminate_session`](/dist/docs/3.3.0-beta.0/sponsored-intelligence/tasks/si_terminate_session); the `sponsored_intelligence` capability field on `get_adcp_capabilities`; the SI identity, capability negotiation, and UI component surfaces defined in the [SI specification](/dist/docs/3.3.0-beta.0/sponsored-intelligence/specification) | Conversational brand experiences are a new advertising model. Session lifecycle, UI components, identity/consent object shape, and capability negotiation are expected to evolve as first-party AI hosts and brand agents integrate. Planned changes track the [3.1.0 roadmap](https://github.com/adcontextprotocol/adcp/issues/2201). |
| `creative.evaluator` | The `evaluator` input on [`build_creative`](/dist/docs/3.3.0-beta.0/creative/task-reference/build_creative), the per-leaf `eval` block on the build response, and the `creative.supports_evaluator` capability field on `get_adcp_capabilities` (schema: `core/evaluator-spec.json`) | New gate-then-rank creative-feature-oracle surface (#5241 / #5311), not yet field-tested across parties. Evaluator ranking intentionally reuses the existing stable creative-feature catalog rather than minting a parallel evaluator catalog: `rank_by`, `feature_requirement`, and `eval.features[]` all refer to feature IDs from `governance.creative_features`. Evaluator sources are `exemplars` or an allowlisted `agent_url`; the earlier account-arranged `evaluator_id` form was removed in 3.3 (see [Migrating from 3.2 to 3.3](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#experimental-creative-evaluator-drops-evaluator_id)). A separate `supports_evaluator_gate` capability and a hard MUST-enforce-gate semantic are reserved follow-ons that may reshape the evaluator fields. The `evaluator_id` removal in 3.3 waives the 6-week pre-landing notice: beta.0 is the notice vehicle, and GA ships no earlier than 6 weeks after the beta.0 tag. |
| `creative.signal_fanout` | The `signal_conditions[]` and `selection_strategy` inputs on [`build_creative`](/dist/docs/3.3.0-beta.0/creative/task-reference/build_creative), the `creatives[].signal_condition` / `selection_strategy_applied` / `estimate.conditions_total` fields on its response, the `creative.multiplicity.supports_signal_fanout` / `max_signal_conditions_limit` / `selection_strategies` capability fields on `get_adcp_capabilities`, the `enums/creative-selection-strategy.json` enum, and the `SIGNAL_TARGETING_INCOMPATIBLE` error code (#5240 / #5304, folds #5262) | New signal-driven creative fan-out surface introducing a cross-agent reject-at-trafficking MUST (`SIGNAL_TARGETING_INCOMPATIBLE`) spanning creative agent + sales agent — not yet field-tested across parties. The numeric (`value_type: numeric`) condition-compatibility comparison (range-overlap vs exact-match) is still WG-open, and the `proximity` selection strategy's geo-input binding is not yet settled — both stay revisable under experimental. Condition identity itself is resolvable today (`signal_agent_segment_id` / `signal_ref` via `get_signals`), so there is no frozen-identifier problem. |
| `media_buy.audience_activation` | The [`audience_activation`](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/media-products#audience-activation) declaration on products, the `audience_targeting.supported_activation_methods` capability field on [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities), the `audience_activation_methods` product filter on [`get_products`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_products), and the `core/audience-activation-method.json` schema (#4324). The cluster also covers [external audience source references](/dist/docs/3.3.0-beta.0/media-buy/task-reference/sync_audiences#external-audience-sources-experimental) on `sync_audiences` — the `source` request field (`core/audience-source.json`), the response `source` echo with `access_status`/`columns_read`, and the `SOURCE_ACCESS_FAILED` error code (#6540). | New activation-path discovery surface (how audience data moves: dataset sharing, clean rooms, platform distribution, file transfer) — not yet field-tested across parties. Pattern-specific field shapes (`consumer_identities[]` qualifiers, `bind_expiry_days` semantics), the grantee-identified admissibility boundary, and filter matching semantics all need integration experience with real Snowflake/Databricks/LiveRamp pipelines before freezing. The runtime leg (#6540) may reshape the declaration fields it consumes. |
| `media_buy.execution_requirements` | The experimental `Product.execution_requirements` declaration on [`get_products`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_products) and [`list_products`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/list_products) results (schema: `core/product-execution-requirement.json`), and the `error-details/execution-requirement-unmet.json` details shape for the resulting `VALIDATION_ERROR` on `create_media_buy` and `update_media_buy` (#7763) | First, account-independent half of the execution-readiness RFC. The requirement kinds and their binding points reuse existing request fields, but the vocabulary is expected to grow (lead forms, messaging destinations) and per-account readiness — which resources an account has and which one to use — is planned for 3.3 and may reshape how requirements and readiness compose. |
| `media_buy.product_identity` | The experimental `Product.identity` declaration on [`get_products`](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/media-products) and [`list_products`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/list_products) results, plus reach-unit coherence in delivery reporting | Product-level identity availability, the boundary between modeled and identifier-backed reach, and the methodology disclosure remain new cross-channel interoperability semantics. The field is deliberately product-scoped so mixed addressable and non-addressable inventory remains truthful while implementers validate the disclosure and reporting behavior. |
| `media_buy.installment_lifecycle` | The `installment_status` and `publication` fields on `by_installment[]` rows of [`get_media_buy_delivery`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_media_buy_delivery), the `core/installment-publication.json` schema, the `available_installment_statuses` declaration in product `reporting_capabilities`, the `publication` value in `enums/available-metric.json`, and the `installment_delivery` param of `simulate_delivery` in `comply_test_controller` (#8088; see [Installment lifecycle and proof of publication](/dist/docs/3.3.0-beta.0/media-buy/media-buys/optimization-reporting#installment-lifecycle-and-proof-of-publication)) | Installment lifecycle and proof of post for creator posts, newsletter editions, and podcast episodes, parallel to `media_buy.spot_lifecycle`. Validated so far by one adopter, Availnet, a creator marketplace. The publication record is seller-reported evidence; a notification when an installment publishes is planned for 3.4 and may reshape how buyers learn of publication. |
| `media_buy.spot_lifecycle` | The `spot_status`, `scheduled_at`, `replaces_spot_id`, and `break_position` fields on `by_spot[]` rows of [`get_media_buy_delivery`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_media_buy_delivery), the `enums/spot-status.json` enum, and the `available_statuses` and `supports_break_position` declarations on `supports_spot_breakdown` in product `reporting_capabilities` (#5683, #8009; see [Spot lifecycle, makegoods, and break position](/dist/docs/3.3.0-beta.0/media-buy/media-buys/optimization-reporting#spot-lifecycle-makegoods-and-break-position)) | Report-time half of linear-TV preemption and makegoods, validated so far by one Dutch linear TV pilot and one US broadcast operator. Contract-time preemption criteria and an interactive replacement-offer flow are planned for 3.4 and may reshape the status vocabulary, the makegood linkage, and how plan rows reconcile with broadcast as-run logs. |
| `media_buy.delivery_projection` | The optional `projection` object on top-level `by_package[]` rows of [`get_media_buy_delivery`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_media_buy_delivery#delivery-projection) (schema: `core/delivery-projection.json`) and the `delivery-projection-basis` and `delivery-projection-end-state` enums (#5850) | Advisory forward-looking projection of a package's end-of-flight delivery, with one production adopter so far. The `complete` / `early_exhaustion` materiality split was authored during implementation rather than ratified in the brief, and the `basis` method-class vocabulary is expected to grow. Sellers declare the feature id in `experimental_features`; there is no capability field to gate it, because the object appears only on delivery responses. |
| `media_buy.reporting_delivery` | **Reliable Reporting 1.0**: [`get_reporting_status`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_reporting_status), opt-in [`sync_reporting_status`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/sync_reporting_status), [`sync_reporting_receipts`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/sync_reporting_receipts), `sync_accounts.reporting_delivery_configs[]`, reporting notifications, and the `media_buy.reporting_delivery` capability block | Proper-name AdCP 3.2 reporting reliability surface (#6911), explicitly discovered through `reliable_reporting_version: "1.0"`. Core, Managed Delivery, and Reconciled Billing have separate capability-gated conformance storyboards. The [consumer-status migration](/dist/docs/3.3.0-beta.0/reference/migration/reliable-reporting-status-loop) is an active breaking-change notice: current source adds an opt-in task, which becomes required Core only in the next eligible minor after October 24, 2026. Its `content_mismatch` status, stale-`received` grace window, buyer posting deadline, issue lifecycle fields, escalation contact, the reserved `authoritative_party` field ([#7440](https://github.com/adcontextprotocol/adcp/issues/7440)), and the optional report-definition `source.custody` field, new in 3.3 ([#8185](https://github.com/adcontextprotocol/adcp/issues/8185)) are all additive within that experimental surface. [Superseded snapshot compaction](/dist/docs/3.3.0-beta.0/reference/migration/3-2-to-3-3#superseded-reporting-snapshots-may-be-compacted) ([#8081](https://github.com/adcontextprotocol/adcp/issues/8081)) is a second active breaking-change notice: sellers may compact older superseded snapshot content only in the next eligible minor after November 20, 2026. Multi-party production operation and provider-specific compatibility still need implementation experience before freezing. |
| `media_buy.hold_extension` | `action: "extend_hold"` on [`refine_proposals`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/refine_proposals#extend-a-hold-experimental) and the `media_buy.proposal_refinement.hold_extension` capability on [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities#proposal_refinement) ([#8086](https://github.com/adcontextprotocol/adcp/issues/8086)) | New committed-hold extension for scheduled media, with one named adopter so far: Availnet, a creator marketplace. When the committed proposal carries the experimental `hold_policy` (`media_buy.hold_policy`, [#7661](https://github.com/adcontextprotocol/adcp/issues/7661)), its `extendable` (default `false`) and `max_total_duration` bound extension, measured from the original `hold_placed_at`; absent it, limits are seller policy expressed through `hold_unavailable`. Applies only to committed proposals that hold inventory: an entry whose effective policy is terms-only fails `extend_hold` with `INVALID_STATE`. A successor lists the same per-installment `holds` (`media_buy.installment_holds`) as its source. |
| `creative.broadcast_loudness` | The optional `loudness` object (`target_lufs`, `tolerance_db`, `max_true_peak_dbfs`, `standard`) on the `video_hosted` canonical format params (schema: `formats/canonical/video_hosted.json`), documented in [Broadcast creative](/dist/docs/3.3.0-beta.0/creative/channels/broadcast#loudness-experimental) (#8011) | New broadcast-television delivery requirement with very few adopters so far. The `standard` enum (`ebu_r128`, `atsc_a85`, `custom`) is expected to grow, and the object shape may be reconciled with the flat `loudness_*` fields on `audio_hosted` in a later 3.x release. The `mxf` container and the `mpeg2` / `avc_intra` / `xavc` codec values added alongside it are stable additive enum values, not part of this experimental surface. |
| `media_buy.daypart_granularity` | The `start_time` / `end_time` clock-time fields on `core/daypart-target.json` (and so on every `daypart_targets` entry), the `time_granularity` field in `overlay_support.daypart_targets` and `required_overlay_support.daypart_targets`, and the `enums/daypart-time-granularity.json` enum ([#6707](https://github.com/adcontextprotocol/adcp/issues/6707)). See [Minute-resolution dayparts](/dist/docs/3.3.0-beta.0/media-buy/advanced-topics/targeting#minute-resolution-dayparts-experimental). | Minute-level schedules for linear TV (programme-junction breaks, overnight broadcast days) arrive with one named adopter and are expected to be reshaped by the network/station targeting work in [#5679](https://github.com/adcontextprotocol/adcp/issues/5679). The `HH:MM` representation, the overnight rule (a window belongs to its start day), the three-value granularity ladder, and the error code for an unsupported granularity (today `UNSUPPORTED_FEATURE`, which may be superseded by the targeting-dimension codes in [#6978](https://github.com/adcontextprotocol/adcp/issues/6978)) may change before they freeze. The whole-hour `start_hour` / `end_hour` fields stay stable, although they are no longer individually schema-required. |
| `media_buy.lineage` | Forward-only buy-level lineage: the `predecessor_media_buy_id` and `lineage_reason` fields on [`create_media_buy`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/create_media_buy), [`buy_products`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/buy_products), and [`accept_proposal`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/accept_proposal) requests and on [`get_media_buys`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/get_media_buys) items (also `core/media-buy.json`), the `predecessor_media_buy_id` filter on `get_media_buys`, and the `enums/media-buy-lineage-reason.json` enum (#5849; see [Media Buy Lineage](/dist/docs/3.3.0-beta.0/media-buy/specification#media-buy-lineage)) | One production sales agent has run equivalent lineage operations for months, and IAB AAMP seller-agent 2.0 (`parent_deal_id`) is prior art for the same idea in deal-scoped form, not convergence evidence. The `lineage_reason` vocabulary is closed and may grow, and the `UNSUPPORTED_FEATURE` rejection and the same-account scope may change as more sellers implement it. |
| `media_buy.delegated_composition` | `criteria.product_ids_exclusive` on [`request_proposals`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/request_proposals#binding-the-product-universe-with-product_ids_exclusive) and proposal refinement, the `media_buy.supports_exclusive_product_ids` capability, and `media_buy.proposal_refinement.hold_semantics` (`terms_only`) with its `committed`, `expires_at`, and `accept_proposal` semantics, described in the [delegated composition profile](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/delegated-composition) | Zero validated adopters so far, and `terms_only` reinterprets what `committed` means for a capability-gated seller. The acceptance-only `accept_proposal` variant, the governance trigger when the MediaBuy is created on the requester, and a reference-based product universe are still open and may reshape these fields. A `terms_only` seller must not return `committed` proposals to callers below 3.3. |
| `media_buy.hold_policy` | The `hold_policy` object (schema: `core/hold-policy.json`: `available`, `min_duration`, `max_duration`, `extendable`, `max_total_duration`) as a planning hint on products (`core/product.json`, `core/canonical-product.json`) and as the binding policy on canonical proposals (`core/canonical-proposal.json`), the committed proposal's `hold_placed_at`, the per-entry resolution of non-holdable drafts to terms-only finalize, and its role overriding the agent-level `hold_semantics` default, described in [Hold policy](/dist/docs/3.3.0-beta.0/media-buy/task-reference/refine_proposals#hold-policy-experimental) ([#7661](https://github.com/adcontextprotocol/adcp/issues/7661)) | One named adopter so far: Availnet, a creator marketplace, where each creator's upcoming-video slot can be held while the creator confirms. `rankable` belongs to `media_buy.hold_ranking`, per-installment readback to `media_buy.installment_holds`, and `extendable` and `max_total_duration` bound `extend_hold` (`media_buy.hold_extension`). Reuses the `terms_only` semantics of `media_buy.delegated_composition` without requiring that feature id. Both fields are omitted for callers below 3.3. The `comply_test_controller` scenario `force_hold_unavailable` ([compliance test controller](/dist/docs/3.3.0-beta.0/building/by-layer/L3/comply-test-controller#force_hold_unavailable)) and its `forced.arm: "unable"` response echo ride on this feature id and carry no feature id of their own. |
| `media_buy.hold_ranking` | `hold_policy.rankable` (`core/hold-policy.json`) and the committed proposal's `hold_rank` (`core/canonical-proposal.json`): advisory readback of the buyer's own position in a seller's queue of holds, described in [Hold ranking](/dist/docs/3.3.0-beta.0/media-buy/task-reference/refine_proposals#hold-ranking-experimental) ([#8086](https://github.com/adcontextprotocol/adcp/issues/8086)) | One named adopter so far: Availnet, a creator marketplace. Ranking is advisory only: no right-of-first-refusal deadline, no rank-change webhook, and no read of a committed proposal, so `hold_rank` is a snapshot that a buyer refreshes through an `extend_hold` successor. Whether buyers need a fresher readback, and whether sellers will report exact queue depth, needs field experience. `available: true` without `rankable: true` keeps its exclusive, first-position meaning. Requires `media_buy.hold_policy`; omitted for callers below 3.3, for whom the seller treats `rankable` as `false`. |
| `media_buy.collection_catalog` | [`list_collections`](/dist/docs/3.3.0-beta.0/media-buy/task-reference/list_collections) (schemas: `media-buy/list-collections-request.json`, `media-buy/list-collections-response.json`), its `collections_version` / `if_collections_version` tokens, and the `collection_card.updated`, `collection_card.removed` and `collection_catalog.bulk_change` webhook event types (branches of `core/wholesale-feed-event.json`, delivered in `core/wholesale-feed-webhook.json` and listed in `wholesale_feed_webhooks.event_types`) ([#8183](https://github.com/adcontextprotocol/adcp/issues/8183)) | Standalone catalog read and push channel for collection cards, with one adopter behind the card surface so far (Availnet, a creator marketplace) and no emitting agent yet. Requires `media_buy.collection_cards`, because the response carries card fields; a seller can serve cards in-band without it. Webhooks are optional within the feature and declared per type. The filter set, the reuse of the wholesale feed envelope with `collections_version` in `wholesale_feed_version`, and the bulk threshold for follower sweeps may change. Not served to callers below 3.3. Storyboards and a `seed_collection` controller scenario wait for training-agent support ([#8181](https://github.com/adcontextprotocol/adcp/issues/8181)). |
| `media_buy.installment_holds` | The committed proposal's `holds` array (`core/canonical-proposal.json`): `product_id`, `installment_ref`, and, under a rankable policy, `hold_rank` for each installment the hold covers, described in [Installment holds](/dist/docs/3.3.0-beta.0/media-buy/task-reference/refine_proposals#installment-holds-experimental) ([#8086](https://github.com/adcontextprotocol/adcp/issues/8086)) | One named adopter so far: Availnet, a creator marketplace, where the held unit is a creator's specific upcoming video. Readback only: entries describe one all-or-none hold and share the proposal's `expires_at`, so there are no partial holds. Whether entries need their own `expires_at`, which only makes sense if partial holds are ever allowed, needs field experience. Requires `media_buy.hold_policy`; omitted for callers below 3.3. |
| `identity.trust_json` | The `trust/v1/trust.json` and `trust/v1/trust-acknowledgements.json` schemas, described in [trust.json (experimental)](/dist/docs/3.3.0-beta.0/reference/trust-json) ([RFC #7809](https://github.com/adcontextprotocol/adcp/issues/7809), [#7819](https://github.com/adcontextprotocol/adcp/pull/7819)). In 3.3 its reader is the experimental Web Bot Auth signing profile, which derives a trust record from an agent's origin ([Web Bot Auth identities](/dist/docs/3.3.0-beta.0/building/by-layer/L1/security#web-bot-auth-identities)); grants are read at `sync_accounts` and on the freshness schedule ([Grants in trust records](/dist/docs/3.3.0-beta.0/building/by-layer/L2/accounts-and-agents#grants-in-trust-records-experimental), [DR-0025](https://github.com/adcontextprotocol/adcp/blob/main/governance/decisions/DR-0025-demand-side-grants-in-trust-json.md)). No one is required to publish `/.well-known/trust.json`, and publishing one is not implementing a task, so publishers declare nothing in `experimental_features`. | The document shape for agents, grants, and acknowledgements is published ahead of the behavior that would use it, so implementers can review it. Agents are identified by origin, one per origin, and the record carries no keys ([`specs/agent-identity-3-3.md`](https://github.com/adcontextprotocol/adcp/blob/main/specs/agent-identity-3-3.md)). The document name and its `/.well-known` path may change before graduation: the JournalList `trust.txt` naming outreach is still open. The record's location is derived from the agent's origin, so no capability pointer is planned. Resolution and no-downgrade rules are in the Web Bot Auth identities section of the security page. |
| `media_buy.collection_cards` | The `images`, `sample_content` and `url` fields on `core/collection.json`, the `brand_ref` field on `core/talent.json`, the `sample_content` role on `core/product-card-reference-asset.json` (#8092), and the `followers` field on `core/collection-distribution.json` entries, a `core/audience-size.json` count (#8098); the top-level `collections` array (`core/response-collection.json`) on the `get_products`, `list_products`, `request_proposals` and `refine_proposals` responses, and the `include_collections` request flag that opts into it (#8137). See [collection cards](/dist/docs/3.3.0-beta.0/media-buy/product-discovery/collections-and-installments#collection-cards-experimental). | Display and identity slice of the creator-card RFC, with a single adopter so far (Availnet, a creator marketplace) and no field-testing across parties yet. The array bounds, the use of `published-post` references for samples, the `brand_ref`-over-`brand_url` precedence, the opt-in flag, and the closed list of fields (`images`, `sample_content`, `url`, `description`, `season`, `cadence`, `distribution[].followers`) on which a response copy wins over `adagents.json` may change. `adagents.json` publishers cannot declare `experimental_features`, so consumers treat the collection fields as experimental wherever they appear. Sellers that emit the `sample_content` role or response `collections`, or accept `include_collections`, declare the id. Whether a follower count belongs on the distribution entry, and how sellers report platform-rounded counts, may change. Audience composition (`audience_evidence`) and average views (forecast `views`) reuse existing surfaces and are not part of this surface. |
| `brand.collection_links` | The `collections` field on the [`get_brand_identity`](/dist/docs/3.3.0-beta.0/brand-protocol/tasks/get_brand_identity) response and its `collections` value in the request `fields` and response `available_fields` lists, plus `publisher_domain` on `brand.json` brand-level collection links (#8137) | Brand-side half of the creator-card work: lets a buyer go from a talent's `brand_ref` to the person's channels and confirm the link from both sides. One adopter so far (Availnet, a creator marketplace). The link shape, the public visibility level, and whether `seller_agent_url` stays on the link may change. `brand.json` publishers cannot declare `experimental_features`, so consumers treat `publisher_domain` there as experimental. Brand agents that return `collections` declare the id. |
| `signals.signal_lifecycle` | The optional `signal_status` (`enums/signal-status.json`: `processing`, `ready`, `failed`; absent means `ready`) and `source_audience_id` fields on [`get_signals`](/dist/docs/3.3.0-beta.0/signals/tasks/get_signals) results, the matching `fields` projection values, and the `signals.features.signal_lifecycle` capability flag on [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities) (#5409; 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)) | Readiness and seed lineage for segments a signal agent builds on demand, driven so far by a single named adopter. The wholesale-feed-version and buyer-scoping rules, and the `processing` vocabulary shared with `audience-status`, may change once more signal agents build segments. |
| `media_buy.collection_lists` | The `collection_lists` and `collection_lists_exclude` fields on `targeting.json` and `targeting-input.json`, and the matching `overlay_support` / `required_overlay_support` keys with `max_references` ([#7834](https://github.com/adcontextprotocol/adcp/issues/7834)). See [Combining several collection lists](/dist/docs/3.3.0-beta.0/governance/collection/index#combining-several-collection-lists-experimental). | One buyer-side adopter so far, and the WG has not ratified the intersection/union semantics or the `max_references` shape. The singular `collection_list` fields are stable and unchanged. |
| `signing.web_bot_auth` | The [Web Bot Auth request-signing profile](/dist/docs/3.3.0-beta.0/building/by-layer/L1/wba-profile): the `web-bot-auth` value in `request_signing.profiles` and `webhook_signing.profiles` on [`get_adcp_capabilities`](/dist/docs/3.3.0-beta.0/protocol/get_adcp_capabilities), and `signing_profile` on every webhook registration, adopted by DR-0023 | The profile follows an IETF draft that is still changing. The draft revision it pins and the `Signature-Agent` form may change before graduation. |
| `media_buy.offline_delivery_metrics` | The `ooh_metrics` delivery block on `core/delivery-metrics.json` (panels, posting periods, posting records, share of voice, modeled `estimated_impressions` with `estimation_basis`; added in 3.2 and documented in [Out-of-home](/dist/docs/3.3.0-beta.0/creative/channels/ooh)), and the `print_metrics` delivery block (`page_delivered`, `position_delivered`, `circulation_delivered`, `circulation_basis`, `evidence`; added in 3.3 and documented in [Print creative](/dist/docs/3.3.0-beta.0/creative/channels/print#delivery-evidence-and-circulation)). Both carry `x-status: experimental`, both are addressable as `ooh_metrics` / `print_metrics` in the `available-metric` enum, and both reuse the channel-neutral `core/placement-evidence.json` artifact. | Delivery reporting for channels with no play or impression event — static OOH posting records and print proof-of-insertion with circulation — rests on one named adopter per channel and on contract conventions (OAAA proof of performance, tearsheets, circulation audits) that have not been field-tested across parties. `ooh_metrics` shipped in 3.2 without a registry row; this row registers it with `print_metrics` as a clarification, so a seller on 3.3 that reports either block declares the id. A seller on a 3.2 schema that already reports `ooh_metrics` is not made non-conformant retroactively. Field shapes, the `estimation_basis` / `circulation_basis` tier vocabularies, and the shared evidence artifact may change before they freeze. |

Graduation progress and notice of upcoming breaking changes will be called out in the [release notes](/dist/docs/3.3.0-beta.0/reference/release-notes) for each 3.x release starting with 3.0 GA.

## Relationship to extensions

Experimental status is not the same as an [extension](/dist/docs/3.3.0-beta.0/reference/versioning#extensibility). Extensions live in the `ext.{namespace}` field and are governed by the extension registry; they are permanently out-of-band for the core protocol. Experimental surfaces are in the core protocol — they are candidates for promotion to stable, not third-party additions.

A surface should be experimental when the architecture committee intends it as part of the core protocol but is not yet willing to freeze it. A surface should be an extension when it is domain-specific, maintained outside the core protocol, or unlikely to apply to the broader AdCP ecosystem.


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