Migrating from 3.1 to 3.2
AdCP 3.2 is generally available (published 2026-09-30). The release
artifact is
3.2.1 and the wire pin is "3.2"; the number 3.2.0 was never
released. TypeScript @adcp/sdk@14.0.0 and Python adcp==8.0.0 ship
alongside 3.2.1 and embed it. Go and Java support for final 3.2 is planned as a
follow-up. See SDK versions for 3.2.get_products, create_media_buy, and
update_media_buy remain the 3.x compatibility facades. A caller opts into 3.2
only after the peer advertises "3.2" in supported_versions.
For the feature narrative, start with What’s New in AdCP 3.2.
If you pinned a beta or release candidate, see the 3.2 prerelease history for what changed between RC.7 and 3.2.1.
Start here
- Read 3.2 compatibility exceptions. They list the few places where 3.2 can reject a payload 3.1 accepted.
- If you sign requests, read Mixed-version request signing before any counterparty advertises 3.2 on an endpoint you already call.
- Pick your SDK line from SDK versions for 3.2.
- Work through the day-one checklist for your role.
- Check the wire changes from 3.1 to 3.2 against any hand-written validators, parsers, or code generators.
- If you buy or sell shared budgets, read Seller-optimized budgets. If your products report on a non-UTC clock, read Delivery dates on the reporting timezone.
The migration cost is intentional—and bounded
The compact lifecycle adds a second surface during the 3.x compatibility window because the old facades combine discovery, proposal mutation, commitment, creation, and operational changes behind overloaded modes. Those states cannot all be made safe merely by renaming one request. Use a maintained AdCP SDK for production wherever possible. The SDK can select an advertised compact tool, perform a proven direct translation, or run a purpose-built stateful adapter. It must fail with a typed unsupported-capability error when a legacy peer cannot preserve immutable proposal history, atomic holds, accepted-term readback, amendments, or idempotent resume. A generic adapter must never pretend those semantics exist. Existing 3.1 implementations remain valid. Adopting 3.2 is an incremental enterprise migration, not a flag day and not a requirement to reimplement both surfaces by hand.Upgrade checklist
3.2 compatibility exceptions
The 3.x stability guarantees say stable fields are not removed, and authentication and core security do not change, within 3.x. 3.2 has a bounded, recorded set of exceptions. The complete list is in 3.2 exceptions to 3.x compatibility:- One removed field. The deprecated body-level
statusoncreate_media_buy/update_media_buysuccess responses is removed (DR-0011). Readmedia_buy_status. - One request-signing security correction. 3.2 endpoints require
content-digestcoverage and RFC 8941 padded Base64. The endpoint selects the profile, so a signed 3.1 request to a shared endpoint that advertises 3.2 is rejected even when it pins"3.1". - Eight tightened request rules.
create_media_buyshape and currency,build_creativeroutes, image package dimensions,sync_governanceschemes, account notificationevent_types,preview_creativeinputs, and theadcp_versionpattern. Most encode rules 3.1 already documented; the versioning table records the basis for each. The Bearer-onlysync_governancerule also counts as an authentication exception. - Three producer-side tightenings. Preview
recommended_sandbox, committed-proposalpricing_option_id, and capabilityvast_versions/request_signinglist patterns.
Required to claim 3.2 behavior
Serve and echo the release
Advertise"3.2" in supported_versions only when you serve the 3.2
contract, keep advertising every earlier release you still serve, and echo the
release actually served. Do not treat a major-only declaration as evidence of
3.2 support. Prerelease pins ("3.2-rc.N", "3.2-beta.N") match exactly and
never resolve to "3.2", so a seller that still advertises only a prerelease
must move to "3.2" before stable buyers can reach it.
The 3.2 compliance posture makes missing supported_versions or a missing
response echo a blocking failure for a 3.2 claim, even though the fields remain
optional at the 3.x schema level for compatibility.
Use media_buy_status on create/update success
AdCP 3.2 removes the deprecated body-level MediaBuyStatus named status from
create_media_buy and update_media_buy success schemas. Root status is the
task-envelope state. Read and emit media_buy_status for the buy lifecycle.
Nested media_buys[].status and media_buy_deliveries[].status do not change
until 4.0. See Migrating to media_buy_status
for cross-version decoder code.
Bind every signed request body
Request signing is still optional in 3.2. When a 3.2 endpoint does support request signing, however, it must advertisecovers_content_digest: "required". Every accepted signature on a request with
a body covers content-digest; a signed body without coverage is rejected.
Keep legacy "either" or "forbidden" behavior on a separately configured
3.0/3.1 compatibility endpoint or disable signing for that endpoint. A field
inside an untrusted request body cannot select a weaker verifier posture.
The request-profile binary encoding also changes in 3.2. Emit Signature and
Content-Digest values as RFC 8941 sf-binary: standard RFC 4648 Base64 using
the + and / alphabet and required = padding inside the :<base64>: token.
The 3.0/3.1 request profile used unpadded Base64URL. A 3.2 verifier must reject
that legacy alphabet rather than retrying it through a permissive decoder.
Select the parser from the trusted negotiated endpoint and signing profile, not
from a version field inside the untrusted body. Keep an explicitly routed
3.0/3.1 request endpoint if legacy request signing is required. The separate
adcp/webhook-signing/v1 profile retains its legacy unpadded Base64URL binary
encoding throughout AdCP 3.x; do not apply the request-profile migration to
webhook receivers. See Signed requests.
Mixed-version request signing
The endpoint selects the request-signing profile. The request’sadcp_version
pin does not. The security specification
defines the rule in three parts:
- A shared endpoint that advertises a 3.2 release applies the 3.2 rule to every signed request with a body.
- A signer uses the legacy 3.0/3.1 encoding only on an explicitly negotiated 3.0/3.1 request-signing endpoint.
- A 3.2 verifier never retries a legacy token through a permissive decoder, and a client never retries unsigned after a signature failure.
Sellers. Adding a 3.2 release to
supported_versions on an existing URL
changes the verifier for every signed caller of that URL. If you have signed
3.1 counterparties, choose one of these paths:
- Keep the existing URL on the 3.0/3.1 posture and serve 3.2 from a
separately configured endpoint or origin. AdCP has no capability field that
points from one endpoint to another. The new endpoint is a distinct agent
URL that you publish, for example as its own
agents[]entry, or communicate directly. - Coordinate the cutover. Confirm that each signing counterparty signs with the 3.2 profile for your endpoint before you advertise 3.2 on the shared URL.
"3.1".
The TypeScript 14.x and Python 8.x migration guides describe choosing the
profile from the configured or negotiated wire version. If your client pins
"3.1" to an endpoint that advertises 3.2, set the 3.2 signing profile
explicitly for that peer. See SDK versions for 3.2.
Webhook signing (adcp/webhook-signing/v1) keeps its legacy encoding
throughout 3.x and is unaffected.
Populate recovery without rejecting legacy errors
AdCP 3.2 producers MUST populateerror.recovery on every error. AdCP 3.1
producers SHOULD populate it, and the shared 3.x schema deliberately continues
to require only code and message. Do not make recovery schema-required in
a shared decoder: stored responses and live 3.1 peers may validly omit it.
Consumers use wire recovery when present. When it is absent, use the
registered classification for a known code and the bounded transient
fallback for an unknown code. Determine that classification before consulting
retry_after; a delay never makes a correctable or terminal error eligible
for automatic retry.
SDK suites should consume the versioned error-recovery reference vectors, replacing latest with the exact protocol artifact version for release qualification. The vectors include the known/unknown decision table, semantic buyer_reason consistency, retry-budget exhaustion, and legacy fractional delays.
Emit integer retry delays
3.2 producers emiterror.retry_after as an integer number of seconds. Clients
that still receive a legacy fractional value should round up before applying
their bounded retry policy. Apply the delay only after classifying the error as
transient; never automatically retry a correctable or terminal error
merely because the field is present. Do not read retry_after from
error.data.
Move delivery reporting to row-level semantics
The response-widecurrency and aggregated_totals fields on
get_media_buy_delivery are deprecated in 3.2 and removed in 4.0. Sellers
SHOULD omit new aggregated_totals output. When retaining aggregated_totals,
sellers MUST also emit the legacy response-wide currency to denominate its
spend. Buyers MUST tolerate both fields being absent and MUST NOT otherwise
treat the legacy currency as an aggregation currency.
For a single-currency media buy, sellers SHOULD emit
media_buy_deliveries[].currency; package currencies MUST match it. For a
legacy or externally created mixed-currency buy, omit the row currency and
daily_breakdown, and omit monetary or money-derived values from row and
window totals. Report those values only on package rows (including window
package rows) with each package’s own currency. AdCP does not define currency
conversion.
Qualified standard delivery metrics move from the deprecated cross-buy
aggregated_totals.metric_aggregates array to
by_package[].metric_values. Reconcile committed_metrics, metric_values,
and missing_metrics on (scope, metric_id, qualifier). Vendor-defined
delivery continues to use by_package[].vendor_metric_values. During migration,
buyers MAY read legacy aggregate rows but SHOULD prefer package values and
calculate a higher-level result only after checking currency, qualifiers,
measurement windows, finality, and deduplication semantics.
When a qualified standard metric is present in metric_values, sellers MUST
omit its flat package scalar so consumers never see two sources of truth.
Version negotiation across 3.1 and 3.2
The negotiation rules do not change in 3.2. The seller advertisessupported_versions, and the buyer sends
adcp_version. The seller serves the exact release or the highest supported
release at or below the pin, then echoes the release it served. Prerelease pins
match exactly, and a release pin never resolves onto a prerelease.
3.x sellers keep the
get_products, create_media_buy, and
update_media_buy compatibility facades. A seller that exposes only the
compact tools cannot serve an unchanged 3.1 buyer.
Response shapes when serving "3.1". The spec requires the echo, and it
tells buyers to validate against the echoed release. It does not yet state
normatively that a seller serving "3.1" must produce a response valid under
the 3.1 schema. #7718
tracks that gap. Until then, follow the
non-normative guidance. These
3.2 shapes fail a strict 3.1 validator if a seller emits them under a 3.1 pin:
get_adcp_capabilities:media_buy.execution.targeting.geo_regionsand.languagecan be objects instead of booleans. This is the discovery call itself, so parse it tolerantly.core/pricing-option.json: newrevenue_sharearm.get_products: terminalstatus: "rejected"response withoutproducts.sync_accountsrows that carryaccountwithoutbrand/operator.get_media_buysavailable_actions[]canonical action objects.get_media_buy_deliverywithout rootcurrencyortotals.spend.
Adopt by capability
Plan anonymous catalog discovery
Before omitting caller credentials, readmedia_buy.anonymous_discovery for
list_products and discovery-mode get_products, or
signals.anonymous_discovery for get_signals. true means an anonymous call
can succeed; it does not mean the response is a complete seller catalog or that
authenticated buyers and accounts receive identical data. false means the
discovery call requires an authenticated principal. Absence is the 3.1 and
early-3.2 posture: treat the requirement as unspecified, probe if appropriate,
and handle AUTH_MISSING without assuming a seller defect.
Presented credentials are always validated. An invalid credential does not
fall back to anonymous discovery. Mutations and private or account-scoped reads
remain authenticated by protocol rule and do not use these discovery flags.
Compact product and MediaBuy lifecycle
Readget_adcp_capabilities.media_buy.lifecycle_tools before choosing a tool.
Use:
list_productsfor published offer listing;request_proposals,refine_proposals, anddecline_proposalsfor immutable proposal negotiation;buy_productsfor direct purchase;accept_proposalfor committed new-buy, amendment, or negotiated-cancellation terms;control_media_buyfor operational controls inside accepted terms.
Scope idempotency to mutations
AdCP 3.2 requires durable replay for state-mutating requests, not guaranteed pure reads. Read-tool wrappers still accept an optionalidempotency_key, but
the handler may ignore it and execute normally. Buyers must not interpret
adcp.idempotency.supported: true as a promise of byte-stable read replay.
Buyer SDKs should omit keys on pure reads. Generic wrappers that attach one
must treat every poll or state re-read as a fresh request and must not reuse the
key from the mutation whose state they are reading. Sellers that voluntarily
cache keyed reads follow the complete replay, durability, rate-limit, and
encryption rules and document the resulting freshness behavior.
The 3.x get_products facade leaves the key optional on every arm for wire
compatibility. A seller may ignore a supplied key on a guaranteed
side-effect-free synchronous read. Buyers should supply a key whenever the
request may allocate a task, finalize a proposal, or otherwise change observable
state. When supplied and the seller declares adcp.idempotency.supported: true, the
seller applies replay protection before that effect. If the key is omitted or
the seller declares adcp.idempotency.supported: false, an ambiguous result has no portable
at-most-once retry guarantee. New callers should use the compact tasks so the
read/mutation boundary is explicit.
Resolve product, proposal, and live action rights
Use productallowed_actions[] only to select offers. Binding rights live in
accepted commercial_terms.change_terms[]; the live buy’s
available_actions[] is the authoritative current-state subset. A 3.2 buyer
uses available_actions[].change_term_id to resolve the accepted proposal
term, including its allowed_statuses, constraints, mode, and processing SLA.
The available_actions[].terms_ref field shipped in 3.1 and remains valid but
opaque. Continue parsing it for 3.1 peers. A 3.2 seller may echo a
change_term_id there for an older consumer, but new integrations emit and
prefer change_term_id; if both are used as term links, they must agree.
Remove the alias only with AdCP 4.0.
Targeting-aware discovery
Move structured delivery constraints from briefs and legacy filters intotargeting_overlay. Use required_overlay_support only for dimensions whose
values will be supplied later. Treat returned configured product IDs as scoped
to their declared lineage, account, cache scope, and expiry.
Follow the complete field map in Targeting-aware product discovery.
Canonical creative discovery
For new integrations:- sales agents expose accepted
format_options[]on products; - creative agents expose
creative.supported_formatswith stable capability IDs and supported operations; - build and transformer calls select the canonical capability;
- buyers do not require
list_creative_formatswhen canonical discovery is available.
format_ids is deprecated in 3.2 for removal in 4.0; singular legacy
format_id mappings retain their separate compatibility path.
Secured assets
Stop producing inlineservice_account.credentials. Prefer a short-lived
asset-scoped signed URL, pre-authorized workload identity, or a bounded bearer
token when the origin requires an Authorization header. Continue parsing the
legacy shape for 3.x compatibility, but never activate received credentials
automatically. See Migrating secured asset access.
MediaBuy-level frequency caps
3.2 adds a rootfrequency_cap on create_media_buy and buy_products. It is
a maximum-impression cap with one counter shared across every package in
the buy. Package caps (packages[].targeting_overlay.frequency_cap) keep their
independent per-package counters.
- Sellers advertise
media_buy.aggregate_frequency_cappinginget_adcp_capabilities. Each participating product declaresmedia_buy_support.frequency_cap, plus any narrowerfrequency_cap_constraints. Reject an unsupported root cap withUNSUPPORTED_FEATUREbefore any mutation. Never drop, soften, or clamp it. Products can also declare structured package-cap support onoverlay_support.frequency_cap_support. - Buyers send a root cap only when the seller advertises
aggregate_frequency_cappingand every selected product declares compatiblemedia_buy_support. Userequired_media_buy_supportin product discovery to find those products. The root cap requiresmax_impressionsand does not acceptsuppressorsuppress_minutes. It is not accepted when executing a committed proposal: thecreate_media_buyschema forbidsfrequency_capalongsideproposal_id+total_budget. - Live buys change the cap through the
update_media_buy_frequency_capaction whenavailable_actions[]offers it.
create_media_buy schema has no root frequency_cap and allows
additional properties, so a 3.1 seller can ignore the field without an error.
Gate on the capability before relying on the cap.
Seller-optimized budgets: core contract and package controls
A seller-optimized buy (budget_allocation.mode: "seller_optimized") lets the
seller allocate one shared total_budget across packages against
budget_allocation.optimization_goals. In 3.2 the capability is split so a
platform that supports only shared budgets can declare it honestly. All four
flags live in get_adcp_capabilities.media_buy.features
(core/media-buy-features.json):
A seller that implements every control declares all four:
- Sellers. Declare a sub-capability only with
seller_optimized_budget: true; the capabilities schema rejects one without the parent. Without a given sub-capability, reject a seller-optimized request that carries that control withUNSUPPORTED_FEATURE, before any over-subscription check or provider mutation. Never drop or coerce it. Accept omitted media-buypacing(it defaults toevenwhentotal_budgetis present) andpacing: "even". You may rejectasaporfront_loadedwithUNSUPPORTED_FEATURE(error.field: "pacing"), but never coerce them toeven. If you declaredseller_optimized_budget: trueagainst a release candidate and honor package caps, minimum-spend targets, or package pacing, add the matching sub-capabilities. - Buyers. Send
budget_allocationexplicitly:{"mode": "fixed"}or aseller_optimizedblock. Omission still means fixed allocation, but it hides intent. When the principal’s instruction doesn’t say whether the budget is one shared pool or split per package, ask the principal instead of guessing. Before sending package caps, minimum-spend targets, or package pacing on a seller-optimized buy, check the matching sub-capability.required_featuresfilters in product discovery can request a sub-capability on its own.
Delivery dates on the reporting timezone
3.1 described everyget_media_buy_delivery period as UTC, while
reporting_capabilities.timezone could name another zone. 3.2 resolves the
conflict in favor of the seller’s reporting clock:
start_date,end_date, and buy-level and package-leveldaily_breakdown[].dateare calendar dates in the reporting timezone, which is the in-scope products’reporting_capabilities.timezone. They are UTC days only when that timezone isUTC.reporting_period.startandendstay RFC 3339 instants: where the requested dates begin in the reporting timezone, for example2026-04-15T00:00:00-04:00, as a start-inclusive, end-exclusive interval. Windoweddaily,weekly, andmonthlyslices use the same boundaries.- The new optional
reporting_period.timezoneechoes the zone applied. Sellers SHOULD return it on reads withoutreporting_revision_id. - A dated request, or a request with
time_granularitydaily,weekly,monthly, orquarterly, whose in-scope packages span more than one reporting timezone MUST be rejected withVALIDATION_ERROR. Narrowmedia_buy_ids, or omit both dates andtime_granularityfor lifetime totals. - Sellers serving a
"3.1"pin may keep their existing 3.1 delivery-date behavior; the reporting-timezone semantics andreporting_period.timezoneapply to"3.2"(see Serving an older pin).
reporting_period.timezone, and reject mixed-timezone dated
requests. Buyers: interpret dates in the echoed or declared reporting
timezone and don’t assume UTC midnight. Sellers whose products report in
UTC see no change.
Reliable Reporting (experimental)
Reliable Reporting 1.0 is an experimental, separately discovered surface (media_buy.reporting_delivery, reliable_reporting_version: "1.0"). It adds
expected-period obligations, immutable revisions, and get_reporting_status
readback. Optional tiers add Managed Delivery and Reconciled Billing
(sync_reporting_receipts). Nothing changes for 3.1 integrations that do not
opt in.
- Sellers publish the
media_buy.reporting_deliverycapability block for the tiers they implement and listmedia_buy.reporting_deliveryinexperimental_features. - Buyers configure delivery through
sync_accounts.reporting_delivery_configs[]. Derive expected periods independently. Do not treat a missing report as zero delivery. - Consumer-status loop.
sync_reporting_statusis opt-in in 3.2. Sellers advertiseconsumer_status_taskonly when it is implemented. An active breaking-change notice makes it required for Reliable Reporting Core no in the next eligible minor after October 24, 2026. See the consumer-status migration.
Authenticated principals (experimental)
The experimentalprotocol.principal surface
(sync_principal and
get_principal) stores configuration that
belongs to an authenticated caller’s standing relationship with a seller. That
covers caller-level webhook subscriptions, reusable reporting destinations,
and declarations of the async versions, signing algorithms, and experimental
features the caller can consume.
- It never grants advertiser-account authority. Every account and reporting-feed binding is still authorized independently.
- Discover it through the
adcp.principalcapability. Callget_principalto repair cached state after aprincipal.changednotification. - 3.1 integrations need no change. Per-account
notification_configsonsync_accountskeep working.
list_account_changes, gated by
account.change_feed.supported) is also experimental in 3.2, under feature id
account.change_feed. Adopt it only behind its capability declaration.
New sales specialisms
3.2 adds four seller specialisms thatget_adcp_capabilities.specialisms can
claim. See the compliance catalog
for storyboards and grading.
3.2 also adds preview buyer specialisms (
buyer-discovery,
buyer-activation, buyer-negotiation, buyer-monitoring, buyer-recovery)
and orchestrator-multi-agent. Buyers that exhaustively switch on
specialisms must tolerate these new values.
Experimental governance
If you implementgovernance.campaign, update authenticated caller binding,
task-scoped enforcement, intent/execution separation, payload and commitment
binding, and outcome reconciliation together. Do not partially adopt the new
authorization semantics under an old capability declaration.
See Cross-role governance enforcement.
SDK versions for 3.2
The SDK major version tracks the AdCP minor it embeds. Upgrading the SDK major is a separate step from adopting the 3.2 wire. SDK 14 and SDK 8 still call and serve 3.0/3.1 peers.
Go module versions are not AdCP versions.
adcp/v3@v3.2.1 is an SDK release
that embeds the 3.2.0-rc.1 schemas and defaults to the "3.1" wire pin. It
is not “AdCP 3.2.1”. Treat Go as a 3.1 production SDK with preview 3.2 types
until a Go release embeds final 3.2 schemas. Java support for 3.2 is also
planned as a follow-up.
Recommended rollout. Upgrade the SDK and keep the wire pin at "3.1".
Deploy and verify. Then opt into 3.2 one peer at a time, after each peer
advertises it. Sellers keep advertising every release they still serve.
SDK changes that need attention during the upgrade. Details are in each
SDK’s guide.
- TypeScript 13 → 14:
- Requires Node
^20.19.0 || >=22.12.0and@a2a-js/sdk1.x. - Upgrade durable idempotency storage (the
retain_untilcolumn and the atomic store methods) before serving traffic. Retries that hit an SDK 13 idempotency entry returnIDEMPOTENCY_CONFLICT. - Servers separate
adcpVersion(the supported ceiling) fromdefaultAdcpVersion(used for unversioned callers). - Media-buy handlers return
media_buy_status. accounts.resolution: 'derived'becomes an upstream-managed account-id namespace.
- Requires Node
- Python 7 → 8:
handle_webhook()rejects unsigned callbacks by default.- Low-level
sign_request()requires an explicitsigning_profile_version. ADCPClientderives the signing profile from its trusted wire pin.
Day-one checklists by role
Each checklist has two parts. “If you do nothing” is what happens when a counterparty moves to 3.2 and you stay on 3.1. “Day one on 3.2” is the minimum to adopt 3.2 yourself.Seller (sales agent)
If you do nothing: 3.2 buyers downshift to your advertised 3.1 release and use the 3.x facades. Nothing breaks. Buyers still pinned to a 3.2 prerelease getVERSION_UNSUPPORTED and must re-pin to "3.2".
Day one on 3.2:
- Decide how signed 3.1 callers keep working before you add a 3.2 release
to
supported_versionson a shared URL (Mixed-version request signing). - Keep the 3.0/3.1 handlers and
get_products/create_media_buy/update_media_buyfacades. Advertise every release you serve, and echo the served release. - Emit
media_buy_statusand no body-levelstatuson 3.2 create/update success. - Emit
error.recoveryon every error and integerretry_after. - If you advertise request signing, advertise
covers_content_digest: "required"and verify RFC 8941 Base64. - Declare only the capabilities you implement:
lifecycle_tools,aggregate_frequency_capping,anonymous_discovery, and specialisms. - When serving
"3.1", project or omit 3.2-only shapes (guidance). - Move delivery reporting to row-level currency and
by_package[].metric_values.
Buyer
If you do nothing: A 3.2 seller that retains its 3.1 release keeps serving you. There are two exceptions:- Signed requests fail once the seller advertises 3.2 on the endpoint you call.
- Strict parsers can fail on 3.2 capability or response shapes if the seller does not project them.
- Upgrade to a 3.2-capable SDK line (SDK versions)
with your pin still at
"3.1". - Sign with the 3.2 profile for every endpoint that advertises a 3.2 release.
- Read
supported_versions. Pin 3.2 only for peers that advertise it, and validate against the echoed release. - Read
media_buy_statuson create/update success. - Classify errors with
error.recovery, and fall back to the code registry when it is absent. Applyretry_afteronly totransienterrors. - Gate compact tools on
media_buy.lifecycle_tools, and the rootfrequency_caponaggregate_frequency_capping. - Fix request shapes that 3.2 rejects:
create_media_buypackages versusproposal_id, uppercasetotal_budget.currency, andpreview_creativeinputs (wire changes). - Read delivery currency per media buy or package, and tolerate a missing
root
currencyortotals.spend.
Creative agent
If you do nothing: Buyers that callbuild_creative with no target route,
or with both manifest and library inputs to preview_creative, are rejected by
3.2 validators, not by you. Your 3.1 preview renders fail 3.2 validation if
embedding.recommended_sandbox is non-empty.
Day one on 3.2:
- Emit
embedding.recommended_sandbox: "". Never grant iframe sandbox capabilities. - Publish canonical
creative.supported_formats[]capability IDs and supported operations. - Accept exactly one
build_creativetarget route, and accepttarget_capability_id(s)as well as legacytarget_format_id(s). - Isolate named-format (
format_id,list_creative_formats) handling at a compatibility boundary. Named formats are deprecated in 3.2.
Signals agent
If you do nothing: No 3.2 change breaks a 3.1 signals agent. Buyers still discover and activate signals on the 3.1 contract. Day one on 3.2:- Advertise and echo the exact release you serve.
- Declare
signals.anonymous_discoveryonly if an anonymousget_signalscall can succeed. - Emit
error.recoveryon every error. - Claim only the attestation, targeting, or feedback capabilities you implement.
Governance agent (experimental)
If you do nothing: Campaign governance is experimental, and its 3.2 revision changes request and outcome shapes. 3.2 closesreport_plan_outcome.delivery and requires target_agent in
check_governance tool+payload mode, so 3.1-shaped governance calls fail 3.2
validation. Governance parties migrate together.
Day one on 3.2:
- Migrate caller binding, task-scoped enforcement,
target_agent, and outcome reconciliation together, under thegovernance.campaignexperimental declaration. - Accept
report_plan_outcome.deliveryin its closed 3.2 shape:observation_id,source,observed_at,reporting_period,cumulative_spend, andcurrency. - Register Bearer credentials only.
sync_governancerejectsHMAC-SHA256. - Follow Cross-role governance enforcement.
Role-based minimums
Wire changes from 3.1 to 3.2
This table compares the3.1.24 schemas with the 3.2.1 release. It lists changes that can break an existing
3.1 implementation or that need a code change. Purely additive optional fields
and new tasks are omitted.
Direction key:
- Sender: a 3.1 request is rejected.
- Parser: a strict 3.1 parser may reject a 3.2 response.
- Producer: a 3.1 producer’s output fails 3.2 validation.
- Deprecation: still accepted in 3.x.
Experimental surfaces (changed under the six-week notice contract; affect
only implementations that declare the feature)
comply_test_controller force_task_completion results are also narrowed to a
small set of task-completion shapes. That affects only sandbox controller
authors.
Rollback
Keep the 3.1 handler and schema bundle available while you roll out 3.2. If a 3.2 integration fails:- Stop advertising
"3.2"on the affected endpoint. - Re-pin the peer to
"3.1"only if it advertises 3.1. - Route through the 3.x compatibility facades and 3.1 schemas.
- Preserve the failed payload and exact artifact version for diagnosis.