/find
The three AdCP 3.1 facade tasks next to the seven compact tools added in AdCP 3.2, with the removed status field and new error rules

AdCP 3.2 for sellers: what changed and how to migrate from 3.1

Sharad Yadav
Founder, BidCliq

AdCP 3.2 has been generally available since 30 September 2026, and the latest patch is v3.2.8 (28 October). For a sales agent on 3.1, nothing breaks if you do nothing: buyers on 3.2 fall back to the 3.1 release you advertise. When you do advertise 3.2, a short list of changes becomes mandatory, and the new compact media-buy tools stay optional.

This post covers what changed for the sell side between 3.0, 3.1 and 3.2, and ends with a migration checklist. If you are earlier in the process, start with making your inventory agent-ready for AdCP.

Where do AdCP versions stand today?

  • 3.2 is the active line. The first stable artifact is 3.2.1; the number 3.2.0 was never released. Peers negotiate the wire value "3.2", never a patch number. Patches 3.2.2 to 3.2.8 shipped through October.
  • 3.1 and 3.0 are maintained. The 3.1 line is still getting patches (v3.1.30 landed on 28 October), and the spec says 3.1 integrations can stay pinned to "3.1" for as long as they need.
  • 3.3 is in beta. v3.3.0-beta.1 was tagged on 29 October. The versions page targets 4.0 for early 2027.
  • SDKs. TypeScript @adcp/sdk@14.0.0 and Python adcp==8.0.0 embed 3.2.1 and still call and serve 3.0 and 3.1 peers. Go and Java support for final 3.2 is listed as a planned follow-up.
  • Prebid Sales Agent. The open-source agent’s latest release is still v2.0.0, and its docs pin AdCP 3.1.1 through adcp==6.6.0.

What changed between 3.0 and 3.1?

3.1 was additive over 3.0: no required field was removed. The parts a seller notices:

  • Version negotiation. Requests carry a release-precision adcp_version such as "3.1". Sellers list every release they serve in adcp.supported_versions and echo the one they served.
  • Action discovery. Products advertise allowed_actions[]; live buys return available_actions[], so buyers can see which changes are valid before calling.
  • Proposal status. Proposals carry proposal_status: draft must be finalized through get_products refine, committed can go to create_media_buy before expires_at. An update that exceeds the quoted terms returns REQUOTE_REQUIRED.
  • Health and finality. Buys expose health and impairments[] when a dependency goes offline, and delivery rows carry is_final and finalized_at.
  • Canonical formats. Products can declare formats by canonical format_kind.

Remember also what v3 removed: list_authorized_properties is gone, and publisher domains now sit in the portfolio section of get_adcp_capabilities.

Which tasks are new in 3.2?

The headline is the compact lifecycle: one small tool per step of a buy, replacing the overloaded modes of the old facades. The project reports 71 to 94% smaller MCP schemas for the compact pairs than for the 3.1 facades they replace.

3.2 compact toolWhat it does3.x facade it maps to
list_productsLists published offers, no side effectsget_products
request_proposalsSeller writes non-binding plans from a briefget_products
refine_proposalsrevise creates a new snapshot; finalize commits terms and holds inventory until expires_atget_products
decline_proposalsRecords buyer feedback; the proposal can no longer executenone
buy_productsBuys a published offer directlycreate_media_buy
accept_proposalTurns a held snapshot into a new buy, an amendment or a negotiated cancellationcreate_media_buy
control_media_buyChanges delivery inside the accepted terms, guarded by revisionupdate_media_buy

The mapping column comes from the legacy_fallback entries in the 3.2.8 schema manifest. Three rules matter for sellers:

  • Advertise what you serve. List your compact tools in get_adcp_capabilities.media_buy.lifecycle_tools. When the field is absent, buyers use the facades.
  • Keep the facades. get_products, create_media_buy and update_media_buy stay available through 3.x. The task reference now labels the last two as deprecated compatibility facades, but a seller that exposes only compact tools cannot serve an unchanged 3.1 buyer.
  • Proposals carry typed terms. Each proposal has commercial_terms and an RFC 8785 terms_digest. Changes inside the accepted terms go through control_media_buy; anything that changes the terms needs a new snapshot.

3.2 also adds tasks on experimental surfaces: get_reporting_status, sync_reporting_status and sync_reporting_receipts for Reliable Reporting, sync_principal and get_principal for authenticated principals, and list_account_changes for an account change feed. Treat them as opt-in and pin an exact release if you adopt them.

What was removed or tightened?

3.2 records a bounded set of exceptions to 3.x compatibility. The ones that touch a sales agent:

  • One removed field. The deprecated body-level status on create_media_buy and update_media_buy success responses is gone. Emit media_buy_status; root status is the task-envelope state only.
  • Request signing. Signing is still optional. If a 3.2 endpoint verifies signatures, it must require content-digest coverage and accept RFC 8941 padded Base64 rather than the unpadded Base64URL of 3.0 and 3.1. Webhook signing keeps its old encoding through 3.x.
  • Errors. 3.2 producers must populate error.recovery on every error, and retry_after is an integer number of seconds.
  • create_media_buy shape. A request sends either packages without proposal_id, or proposal_id plus total_budget without packages, and total_budget.currency must be an uppercase ISO 4217 code.
  • Producer-side rules. Committed proposals need allocations[].pricing_option_id, and the capability vast_versions list is a closed enum.

What is deprecated?

Deprecated items still work in 3.x and are scheduled for removal in 4.0:

  • Named formats. list_creative_formats, core/format-id.json, core/format.json and the plural format_ids fields. Sales agents expose accepted formats as format_options[] on each product.
  • Bid fields. bid_price and pricing-option max_bid give way to a bidding block (bid_amount, max_bid, cost_per, roas). Sellers reject a package that sends both forms.
  • Delivery totals. The response-wide aggregated_totals and root currency on get_media_buy_delivery. Report currency per media buy or package, and put qualified metrics in by_package[].metric_values.
  • Creative checklists. format_ids_to_provide and format_ids_pending remain for older peers; 3.2 adds formats_to_provide[] and formats_pending[] on packages.

Which new 3.2 fields matter most to publishers?

Most of the 3.2 surface is optional. These are worth a decision:

  • Reporting timezone. In 3.2, get_media_buy_delivery dates are calendar dates in the products’ reporting_capabilities.timezone, echoed in reporting_period.timezone. A dated request spanning more than one reporting timezone must fail with VALIDATION_ERROR. If your ad server reports in Asia/Kolkata, your day boundaries are IST midnight. When serving a "3.1" pin you may keep your 3.1 date behaviour.
  • Seller-optimized budgets. The capability is split into seller_optimized_budget plus three sub-capabilities for package budgets, minimum-spend targets and package pacing. Declare only what you honour and reject the rest with UNSUPPORTED_FEATURE, never by silently dropping it.
  • Buy-level frequency cap. A root frequency_cap counts once across every package. Advertise media_buy.aggregate_frequency_capping only if your ad server can enforce it.
  • Declines and pricing. Sellers can return a coarse decline_reason, get_products gains a terminal status: "rejected" response, and pricing gains a revenue_share model.
  • Anonymous discovery. media_buy.anonymous_discovery says whether an unauthenticated list_products or discovery-mode get_products call can succeed.
  • Specialisms. 3.2 adds sales-dooh (stable) plus sales-exchange, sales-retail-media and sales-streaming-tv (preview). Claim only what you implement.

How do you serve 3.1 and 3.2 from one agent?

Negotiation rules are unchanged. You advertise supported_versions; the buyer sends adcp_version; you serve that release, or the highest one below it, and echo it. A buyer pinned to "3.2" against a seller advertising only ["3.0", "3.1"] is served 3.1.

Two traps:

  1. Signing is chosen by endpoint, not by pin. Once a URL advertises 3.2, a request signed with the 3.1 profile is rejected even if it pins "3.1". If you have signed 3.1 counterparties, either serve 3.2 from a separate endpoint or confirm each signer has moved to the 3.2 profile first.
  2. 3.2 shapes can break strict 3.1 parsers. Examples: object-valued geo_regions and language in capabilities, the revenue_share pricing arm, the rejected get_products arm and delivery without root currency. When serving "3.1", project or omit them.

Checklist: moving a sales agent from 3.1 to 3.2

  1. Upgrade the SDK, keep the pin. Move to adcp==8.0.0 or @adcp/sdk@14.0.0 with the wire pin still at "3.1", deploy and verify.
  2. Decide the signing path for signed 3.1 callers before adding "3.2" to supported_versions on a shared URL.
  3. Advertise and echo. List every release you serve, "3.2" included, and echo the served release on every response.
  4. Switch to media_buy_status on create and update success, with no body-level status.
  5. Emit error.recovery on every error and integer retry_after. Keep decoders tolerant of 3.1 errors without it.
  6. Fix reporting. Row-level currency, by_package[].metric_values, no new aggregated_totals, dates on your reporting timezone.
  7. Move formats to format_options[] on products, and keep list_creative_formats behind a compatibility boundary.
  8. Accept the bidding block and reject packages that mix it with bid_price.
  9. Declare capabilities honestly. lifecycle_tools, budget sub-capabilities, aggregate_frequency_capping, anonymous_discovery and specialisms only where implemented.
  10. Keep the facades. Leave get_products, create_media_buy and update_media_buy working, and add compact tools one at a time.
  11. Grade against the 3.2.1 compliance bundle, and keep the 3.1 handler and schema bundle ready for rollback.
  12. Watch 3.3. The migration guide says sync_reporting_status becomes required for Reliable Reporting Core in the next eligible minor, no earlier than 24 October 2026. It only applies if you adopt Reliable Reporting.

BidCliq builds header bidding and agentic tools for publishers, and our sales agent is verified by AgenticAdvertising.org against AdCP 3.1. For how 3.2 sits against IAB Tech Lab’s work, see AAMP and AdCP compared.

Frequently asked questions

Do I have to implement the new AdCP 3.2 compact tools?

No. get_products, create_media_buy and update_media_buy remain the 3.x compatibility facades. Advertise only the compact tools you actually serve in media_buy.lifecycle_tools; when that field is absent, buyers use the facades.

What is the latest AdCP release?

As of 29 October 2026 the latest stable patch is v3.2.8, released 28 October. 3.2.1 was the first stable 3.2 artifact (3.2.0 was never released), the wire value is "3.2", and a 3.3.0-beta.1 prerelease was tagged on 29 October.

Was anything removed in AdCP 3.2?

One stable field: the deprecated body-level status on create_media_buy and update_media_buy success responses. Sellers now carry the buy's lifecycle state in media_buy_status, and root status means only the task state.

Can one sales agent serve both 3.1 and 3.2 buyers?

Yes. Advertise every release you serve in adcp.supported_versions and echo the one you served. If you verify signed requests, decide first how signed 3.1 callers keep working, because a URL that advertises 3.2 applies the 3.2 signing rules to every signed request.

Is list_creative_formats gone in 3.2?

It is deprecated, not removed. New integrations discover formats through format_options on each product, and the plural format_ids fields are deprecated for removal in AdCP 4.0.

Sharad Yadav

About the author

Founder, BidCliq

Sharad Yadav is the founder of BidCliq, a publisher-first ad monetization platform that helps publishers and ad ops teams run header bidding, Prebid and programmatic across display, video, app and CTV. Before BidCliq, he led AdTech and product at GeeksforGeeks, where he built an in-house ads product that doubled programmatic revenue within nine months and an anti-adblock solution that lifted ad yield by 10%. He is a founding member of AdCP.