Skip to main content

AdCP 4.0 compatibility checks

AdCP 4.0 removes fields and tightens requirements that 3.x agents depend on today. The compliance suite checks a 3.x agent against each of these changes, so the agent learns what to fix before a 4.0 buyer stops working with it.
These checks are advisory throughout 3.x. A failing check never fails a 3.x conformance run. Each one is graded inside a storyboard step that already runs, so it adds no new calls and no new ways to fail.The checks ship in compliance bundles from 3.3 onward. Released bundles never change, so an agent graded against an earlier bundle shows every check as not observable until it is graded against a bundle that carries them.

Reading the results

Each check has a stable id. The registry at universal/v4-compatibility.yaml in the compliance bundle names the storyboard step and validation, or the runner notice, that observes it. A report joins a run’s output against that registry and shows one of three results for each check: In raw runner output, a check observed by a validation appears as a validation_result whose id is the check id. Checks added only for 4.0 carry severity: "advisory". A check observed by a notice appears as a notice whose code is the check id; a notice is only evidence of a pass from a runner known to emit that code.

Checks

Products declare canonical format options

Check id: format_ids_removed_in_4_0 · Change: removal Detects: a product returned by get_products declares format_ids without format_options. 4.0 removes the exact plural format_ids fields. format_options[] becomes the only way a product declares the creative formats it accepts, so a 4.0 buyer sees no formats on a product that carries format_ids alone. Fix: author canonical format_options[] on every product. You can keep projecting format_ids for older 3.x buyers until 4.0. See Canonical formats migration. The check inspects every product in the media_buy_seller brief response, which returns up to five products. It uses the all_fields_present check kind; a runner that does not implement it reports the check as not observable.

Capabilities declare release-precision versions

Check id: major_versions_removed_in_4_0 · Change: removal Detects: get_adcp_capabilities declares adcp.major_versions without adcp.supported_versions. 4.0 removes adcp.major_versions and the request field adcp_major_version. A 4.0 buyer reads adcp.supported_versions only. Fix: list every release you speak in adcp.supported_versions, as release-precision strings such as "3.2". Keep emitting adcp.major_versions through 3.x. See Versioning. 3.2 certification already requires supported_versions, so this check adds no new failure: it labels an existing requirement as one 4.0 depends on.

Responses echo the served release

Check id: adcp_version_echo_required_in_4_0 · Change: new requirement Detects: the response envelope does not echo the served release in adcp_version. The echo is SHOULD-level in 3.x. 4.0 makes it a MUST, and buyers lose the major-version fallback. Fix: echo the release you served in adcp_version on every response envelope. 3.2 certification already requires the echo.

Capabilities do not claim the signed-requests specialism

Check id: signed_requests_specialism_deprecated · Change: removal Detects: get_adcp_capabilities lists signed-requests in specialisms. 4.0 removes the signed-requests specialism enum value. Request signing is a capability, not a specialism. Fix: drop signed-requests from specialisms and advertise request_signing.supported: true. See Signed requests.

Sellers verify signed requests

Check id: request_signing_required_in_4_0 · Change: new requirement Detects: get_adcp_capabilities does not advertise request_signing.supported: true. Request signing is optional in 3.x. 4.0 requires it on spend-committing operations. Fix: verify RFC 9421 request signatures, advertise request_signing.supported: true, and register the compliance runner’s test key before the 4.0 cut. See Signed requests.

Webhooks do not fall back to HMAC

Check id: legacy_hmac_fallback_removed_in_4_0 · Change: removal Detects: get_adcp_capabilities advertises webhook_signing.legacy_hmac_fallback: true. 4.0 removes the HMAC-SHA256 webhook fallback. Fix: sign webhooks with RFC 9421 only and stop advertising legacy_hmac_fallback. See Webhooks.

Changes not checked yet

A check is added once its 4.0 change is decided. These changes are still proposals or under working group review, so the suite does not grade them yet:
  • channels required on every product (#7869)
  • duration_ms required on hosted video assets (#5668)
  • the account_id from sync_accounts as the only account reference after provisioning (#7850)
  • nested status renamed to media_buy_status (#4905)
The schemas also mark 46 deprecated fields with x-removed-in: "4.0.0". The registry lists each one, either under the check that covers it or in schema_removals_not_checked with the reason no check covers it yet. Most uncovered fields are sent by buyers, so a seller run can’t observe them. A few are seller-emitted and checkable but not graded yet: flat valid_actions, response-wide delivery currency and aggregated_totals, inline_creative_management, and the format-level build and pricing surface that list_transformers replaces. The full list of planned 4.0 work is the 4.0 milestone.

Adding a check

Every 4.0 issue that removes or tightens something an agent relies on declares a stable check id and a one-line detection rule. When the change is accepted, the same PR:
  1. Adds the observation. Prefer an advisory validation on a step that already makes the needed call, with id set to the check id, severity: advisory, and permanent_advisory. Don’t use expires_after_version, which promotes the check on runner version rather than on the spec version the agent is graded against. A check the runner already reports as a canonical notice with effective_version: "4.0" uses the notice code as its id.
  2. Adds the entry to universal/v4-compatibility.yaml, with the removed schema nodes in schema_sites.
  3. Adds a section here with an <a id> anchor that matches the check id.
A schema node that 4.0 removes is marked "deprecated": true and "x-removed-in": "4.0.0", and the registry lists it once: in a check’s schema_sites, or in schema_removals_not_checked with its 4.0 tracking issue and a reason. Marking a node therefore forces the decision of whether a 3.x agent can be checked for it, and gives every removal a tracking issue. scripts/lint-v4-compatibility-registry.cjs fails the compliance build when the registry, the storyboards, the notice codes, the schema markers, and this page disagree.