Why this shape. Capabilities are organized into ~14 top-level domain keys
(one per protocol plus identity and signing infrastructure), with feature
flags nested under each domain’s
features/execution/etc. sub-namespace. We
rejected a flat capability list — it forces every implementer to scan an
unbounded surface, and it removes the discoverability that comes from related
flags sitting next to each other. New capability flags belong under existing
domains, not in new top-level keys; declarations are commitments, not
advertisements (the conformance runner probes them). → Capabilities
explorer walks the tree before you
propose. → Design principle: capabilities are
commitments.- AdCP discovery - Does this agent support AdCP? Which versions?
- Protocol support - Which protocols (media_buy, signals, governance, sponsored_intelligence, creative, brand)?
- Auth model - Does this seller trust the agent directly, or must each operator authenticate independently?
- Detailed capabilities - Features, execution integrations, geo targeting, portfolio
Per-caller authorization is NOT reported here.
get_adcp_capabilities
returns the seller’s surface — everything it could do for any authorized
caller. To discover what you are allowed to do on a specific account (which
tasks are callable for your identity, which request fields are modifiable, any
named scope like attestation_verifier), read the authorization object on
per-account entries in sync_accounts
and list_accounts responses. See
Caller authorization for the
full shape and semantics./schemas/3.2.0-beta.0/protocol/get-adcp-capabilities-request.json
Response Schema: /schemas/3.2.0-beta.0/protocol/get-adcp-capabilities-response.json
Tool-Based Discovery
AdCP uses native MCP tool discovery and the AdCP A2A Profile Extension v3 on A2A 1.0. The presence ofget_adcp_capabilities in an agent’s tool or skill list indicates that runtime AdCP discovery is available.
- Uses native MCP discovery or A2A 1.0’s standard extension mechanism
- Always returns current capabilities (not stale metadata)
- Single source of truth for all capability information
params member is omitted or empty. Do not place AdCP versions, domains, or feature flags there: get_adcp_capabilities remains the single runtime authority for those values. The unversioned v2 adcp-extension.json capability payload remains removed.
:::
Version Negotiation
Sellers declare which major versions they support viaadcp.major_versions in the response. Buyers declare which version they’re using via adcp_major_version on the request.
adcp_major_version is an optional field on every AdCP request schema. Buyers SHOULD include it on all requests when interacting with a multi-version seller.
Seller behavior:
- If
adcp_major_versionis provided and supported → respond using that version’s schemas - If
adcp_major_versionis provided but unsupported → returnVERSION_UNSUPPORTED(buyer should call withoutadcp_major_versionto discover supported versions) - If
adcp_major_versionis omitted → assume the highest supported version
experimental_features and may change inside 3.x after the required notice. A seller at 3.1 can otherwise serve a buyer at 3.0 without negotiation. The capability model handles feature-level differences — buyers check specific capabilities (targeting systems, features, extensions) rather than version numbers to determine compatibility.
Request Parameters
Response Structure
adcp
Core AdCP protocol information:idempotency
Declares whether this seller honorsidempotency_key replay protection. AdCP requires keys on mutating requests. In the compact AdCP 3.2 product lifecycle, request_proposals, refine_proposals, and decline_proposals require keys; list_products and the legacy 3.x get_products facade leave the key optional. See security.mdx § Idempotency. Clients MUST NOT assume a default; a seller without this block is non-compliant and should be treated as unsafe for retry-sensitive operations.
idempotency.supported: true is a trust-bearing claim that enables buyers to safely retry spend-committing operations. A compromised or buggy seller could advertise true while silently ignoring keys, causing buyer double-spend on retry. Buyers and conformance runners SHOULD probe the declaration with a deliberate payload-mutation replay: send two requests with the same idempotency_key but different canonical payloads — a conformant seller MUST return IDEMPOTENCY_CONFLICT on the second. Sellers declaring supported: true MUST pass this probe as part of the baseline compliance storyboard before the declaration is considered verified.
capability_changes
Declares how consumers should cache and invalidate this agent’s capability document. Capabilities are agent-wide and usually stable, so buyers and registries can cache them; this block gives them a bounded TTL, an opaque revision token, and an optional push signal for material changes. Whennotifications.supported: true, sellers MUST include cache_ttl_seconds and capabilities_version. The webhook is the fast path; the TTL and opaque revision marker are the recovery path when delivery is missed or delayed. last_modified remains useful human-readable metadata, but it is not sufficient as the notification fence.
require_operator_auth, supported billing, account resolution mode, supported protocol versions, task availability, reporting delivery methods, creative-library support, targeting support, and any feature gate a buyer checks before sending a request.
Non-contract operational changes that do not alter the get_adcp_capabilities response body do not require a revision or webhook fire.
capabilities.changed webhooks are invalidation signals, not replacement documents. The payload identifies the agent, change time, reason, required post-change capabilities_version, and optional advisory changed_paths[]; receivers SHOULD re-run get_adcp_capabilities and replace their cached snapshot from the fresh response. Sellers MUST publish the new capability snapshot before firing the webhook so the webhook’s capabilities_version is observable on read. If a receiver reads before the webhook revision is observable, it SHOULD retry with normal transient-error backoff and retain the prior cached snapshot until a matching or newer authoritative snapshot is available. The payload schema is /schemas/3.2.0-beta.0/core/capabilities-changed-webhook.json.
adcp.governance_enforcement
Declares cross-role enforcement of buyer governance for consequential tasks. This core capability is intentionally separate from the top-levelgovernance block: governance describes an agent that provides governance services, while adcp.governance_enforcement describes a media, signal, brand, creative, or other service that consumes governance authorization before committing state.
governance.campaign surface, so an implementing service also lists governance.campaign in top-level experimental_features. signed_context is defined for every governed role. online_execution_check is available for the legacy create_media_buy / update_media_buy facades and the compact buy_products, accept_proposal, and control_media_buy lifecycle, where planned_delivery provides a standardized prepared-result shape. Proposal acceptance binds both proposal_id and proposal_terms_digest. Online checking always implies signed_context; the state transition follows prepare → check → commit and commits atomically only when the response is approved.
Advertising a task also commits the service to deterministic applicability. It resolves the commercial account from the request or existing resource before the side effect; when it cannot do so, it returns ACCOUNT_REQUIRED. It never treats a missing token as evidence that the buyer is ungoverned. Conditional task annotations use trigger_overrides_exemption: any commitment-increasing part of a mixed atomic update requires governance.
AdCP 3.2 conformance selects role-specific governance workflows from exact
entries in adcp.governance_enforcement.tasks[]. The legacy
media_buy.governance_aware boolean remains a compatibility signal for older
runners, but it is not the 3.2 certification gate.
adcp.attestations
Declares the portable attestations this agent is prepared to evaluate. The block is shared across protocol roles and therefore lives underadcp: a seller may evaluate an attestation directly, while a governance agent may evaluate the same presentation for a governance action.
The authoritative shape is attestation-capabilities.json. See Portable attestations for the normative resolution and verification procedure.
Changing an attestation allowlist can change whether future requests are accepted and whether cached evaluations remain reusable. It is therefore a material capability change and SHOULD update
adcp.capability_changes.capabilities_version and fire capabilities.changed when notifications are enabled.
The rights-grant claim URI is a domain profile, not a globally trusted issuer list. A seller that advertises media_buy.rights_attestations also lists https://adcontextprotocol.org/claims/rights/grant here and configures each acceptable rights-agent issuer, resolver, proof format, and credential origin. Buyer-supplied values cannot expand that policy.
supported_protocols
AdCP protocols this agent supports. This is the single capability axis — each value both (a) declares which tools the agent implements and (b) commits the agent to pass the baseline compliance storyboard at/compliance/{version}/protocols/{protocol}/. The runner maps JSON snake_case → URL kebab-case (media_buy → /compliance/.../protocols/media-buy/).
media_buy, creative, signals, governance, brand, sponsored_intelligence.
See the Compliance Catalog for every protocol’s scope. Support for the compliance test controller is declared via the separate compliance_testing capability block (below), not as a protocol value.
specialisms
Optional specialization claims. Each entry corresponds to a narrow storyboard at/compliance/{version}/specialisms/{id}/. Every specialism rolls up to one protocol in supported_protocols — claiming sales-guaranteed requires media_buy. The runner rejects a specialism whose parent protocol is missing.
oauth
Introduced in AdCP 3.2. Declares OAuth support for the agent’s inbound transport. This is separate fromaccount.authorization_endpoint, which is specifically an operator credential-acquisition URL.
oauth.supported: true opts the agent into the universal oauth_setup storyboard. The agent must publish RFC 9728 protected-resource metadata for its endpoint and valid RFC 8414 metadata for every authorization server named there. Agents that authenticate only with static Bearer keys, HTTP Basic, mTLS, or RFC 9421 omit the block or set supported: false.
Capability slot gaps
SDK helpers such asdefinePlatform can project a platform implementation into narrower capability slots. Treat those slots as commitments: only declare a slot when the agent can execute the corresponding task path end to end.
If a storyboard or local test vector targets a slot the agent does not declare, the expected conformance outcome is not_applicable, not failure. Until runner-side enforcement lands in adcp-client#2244, implementers running custom or prerelease suites should add explicit skip gates for vectors outside the declared slot scope. Do not work around a missing slot by declaring it and returning placeholder responses; that turns an honest coverage gap into a failed capability claim.
account
Account and authentication capabilities. All sellers should declare this section — buyers read it before callingsync_accounts, list_accounts, or any authenticated task. Even simple publishers need account management to handle billing relationships and sandbox testing.
account.notifications
Declares whether the seller supports durable account lifecycle invalidation webhooks. This is the capability gate foraccount.status_changed, including billing-related status transitions such as payment_required, suspended, recovery to active, and terminal closed.
supported: false or absent, buyers MUST NOT assume durable account status webhooks are available. They can still use the one-shot sync_accounts.push_notification_config callback for the initial provisioning result when offered, and poll list_accounts for later account status changes.
See Provision a seller-mediated account for the complete discovery, registration, human setup, webhook, and repair sequence.
account.timezone
Account timezone is an immutable operational default, not an assumption that every upstream clock is identical. Aseller_fixed seller advertises one fixed_timezone and buyers omit timezone during provisioning. An account_fixed seller returns a timezone on every account; when account_selection is buyer_selected, buyers MUST provide one advertised value to sync_accounts, and that value participates in the natural account key. When it is seller_assigned, buyers omit the field and discover the value from sync_accounts or list_accounts.
Calendar-day features inherit Account.timezone only when their capability says so. Product reporting continues to use reporting_capabilities.timezone, account financials use the timezone returned by get_account_financials, and daily caps use budget_capping.timezone_basis. This prevents a seller from claiming that distinct reporting, billing, and delivery clocks are aligned when the upstream platform does not align them.
account.identity_updates
Declares whether the seller accepts a complete desiredoperator_identity on an existing account through sync_accounts settings-update mode.
operator_unit_name covers display-name-only changes within the current operator. operator_unit covers adding, removing, or changing the stable unit ID within the current operator and also implies name changes. operator covers an inter-entity operator-domain handoff and encompasses the complete replacement identity, including any simultaneous unit addition, removal, or change; a seller does not also need to advertise operator_unit for that cross-operator replacement. Operator-domain handoffs always require seller-mediated approval of the current account authority, verified brand authorization, destination-operator acceptance, and operator-scoped billing and grants. Sellers declaring support MUST return account revision from sync_accounts and list_accounts, require and atomically enforce a submitted revision, preserve account identity and account-scoped resources during rekeying, expose any pending or rejected transition as identity_change, and return identity_change_preview for dry_run: true. When the capability is absent or supported: false, buyers MUST NOT submit operator_identity; sellers reject it with UNSUPPORTED_FEATURE.
See sync_accounts identity reconciliation for replacement, approval, collision, and stale-key semantics.
Auth models
Buyer-declared accounts (require_operator_auth: false) — The seller trusts the agent’s identity claims. The agent authenticates once with its own bearer token, and account-scoped calls use that credential plus the advertiser natural key (brand + operator + optional operator_unit, fixed currency, optional buyer-selected timezone, and sandbox). brand.countries[] may qualify the commercial advertiser identity without targeting delivery. Most sellers expose sync_accounts so the buyer can declare the relationship and select billing or other settings before use. A seller MAY instead auto-provision on the first account-scoped request when those settings are unambiguous from capabilities or onboarding defaults; in that mode it MUST expose list_accounts as the recovery read and MUST keep accepting the natural key. Auto-provisioning is not conformant when buyer input is needed to resolve billing, timezone, terms, sandbox setup, notifications, or other account settings before the operation.
Account-id namespaces (require_operator_auth: true) — Each operator must authenticate with the seller directly. The agent obtains a credential per operator — via OAuth using authorization_endpoint, or out-of-band — opens a per-operator session, and passes seller-assigned account_id values on subsequent requests. OAuth is credential acquisition, not an account taxonomy axis. Two namespace patterns use the same wire reference: upstream-managed sellers expose list_accounts, making explicit account resolution mandatory before account-scoped calls; seller-defined namespaces without list_accounts provide account IDs out-of-band. SDKs SHOULD lazily call list_accounts when first needed, auto-select a singleton, cache it per credential/session, and still send explicit AccountRef values on required-account calls.
For sandbox, the path follows the account namespace: account-id namespaces discover pre-existing test accounts via list_accounts or out-of-band setup; buyer-declared accounts send sandbox: true through sync_accounts or, for a lazy-provisioning seller, in the natural-key account reference.
See Accounts and Agents for full workflows and seller patterns for common combinations of auth model and billing support.
media_buy
Media-buy protocol capabilities. Only present ifmedia_buy is in supported_protocols. Sellers declaring media_buy should also include account (with supported_billing) and media_buy.portfolio — buyers need both to establish billing and understand inventory coverage. Compliance testing validates their presence.
lifecycle_tools
AdCP 3.2 sellers uselifecycle_tools to advertise any supported subset of get_products, list_products, request_proposals, refine_proposals, decline_proposals, buy_products, accept_proposal, and control_media_buy. When absent, buyers use the legacy get_products, create_media_buy, and update_media_buy facades. The compact tools share the authorization framework with their legacy peers, but grants remain task-specific and each stateful tool has its own idempotency identity: retry with the same tool name and payload. SDKs use the release manifest’s legacy_fallback metadata to distinguish a direct one-call translation from a stateful orchestration or an unsupported fallback; see Same-major tool replacements.
proposal_refinement
Whenlifecycle_tools includes refine_proposals, proposal_refinement optionally advertises which typed revision dimensions the seller can parse and mechanically validate:
alternatives.count has a protocol maximum of 10. max_alternatives may accompany alternatives to publish a lower pre-flight count ceiling and therefore cannot exceed 10. A request whose alternatives.count exceeds that declared ceiling MUST fail at task level with VALIDATION_ERROR; error.field identifies the offending refinements[i].alternatives.count. Sellers MUST NOT silently clamp the count or reinterpret the ceiling as an alternatives_unavailable result.
An explicit supported_dimensions list is authoritative, including an empty list meaning the seller supports ask-only refinement but no typed dimensions. Buyers SHOULD NOT send omitted dimensions, and sellers MUST reject them at task level with UNSUPPORTED_FEATURE. Such errors SHOULD carry the error-details/unsupported-refinement-dimension.json shape — details.unsupported_dimension and details.supported_dimensions — so an authorized buyer can remove or translate unsupported fields without another capability round trip. This task-level rejection applies to the complete request: no sibling refinement succeeds and no proposal is created, even when the unsupported dimension appears after otherwise supported entries. When proposal_refinement is absent, support is unknown; sellers report unsupported dimensions through partial or unable results instead. proposal_refinement is valid only when lifecycle_tools includes refine_proposals.
This capability is about parse and validation support, never commercial willingness. Free-text ask interpretation remains seller competence rather than a boolean capability. Multi-proposal finalization deliberately retains its separate failure-as-discovery model through MULTI_FINALIZE_UNSUPPORTED: it describes atomic infrastructure topology, while the core typed revision fields must be discoverable before a deterministic buyer constructs a request.
budget_capping
budget_capping advertises hard daily caps independently at media_buy and package scopes. A media-buy cap bounds aggregate daily spend without allocating it; package caps add subordinate ceilings and are never reservations. Sellers MUST reject an undeclared scope with UNSUPPORTED_FEATURE before mutation and MUST NOT reinterpret daily_budget_cap as a soft pacing target.
timezone_basis: "account" uses the selected Account.timezone, allowing two accounts on the same seller to have different cap days. timezone_basis: "fixed" requires fixed_timezone and uses that feature-specific boundary for every buy. A buyer override is media-buy-level and applies to every cap on that buy. The accepted effective timezone is echoed as budget_cap_timezone; DST transition dates remain one calendar day carrying the full cap. Billing and reporting timezones remain independently explicit and MUST NOT be inferred from the cap basis.
:::note 3.0 breaking changes
The following fields have been removed from the capabilities response:
media_buy.reporting— Reporting is implied bymedia_buy. Use product-levelreporting_capabilitiesinstead.features.content_standards— Replaced bymedia_buy.content_standardsobject. Presence of the object indicates support.features.audience_targeting— Replaced bymedia_buy.audience_targetingobject. Presence of the object indicates support.features.conversion_tracking— Replaced bymedia_buy.conversion_trackingobject. Presence of the object indicates support.execution.targeting.device_platform,device_type— Implied bymedia_buysupport.execution.targeting.audience_include,audience_exclude— Implied byaudience_targetingobject presence.execution.trusted_match.supported— Object presence indicates support.brand.identity— Implied bybrandinsupported_protocols.get_brand_identityis always available. :::
reporting_delivery_methods
Declares which push-based delivery methods are available across the seller’s product portfolio. Polling viaget_media_buy_delivery is a required task for all media_buy sellers regardless of this field.
When absent, only polling is available. Cadence and metrics are declared per product in
reporting_capabilities.
When offline is declared, also include offline_delivery_protocols to declare which cloud storage protocols are supported (s3, gcs, azure_blob). Buyers express a protocol preference via preferred_reporting_protocol in sync_accounts; the seller provisions the account’s reporting_bucket using a supported protocol.
For offline delivery, the seller provisions a per-account bucket and grants the buyer read access out-of-band. The bucket location (including file_retention_days) appears on the account object returned by sync_accounts as reporting_bucket. See Offline File Delivery for details.
performance_feedback
Presence declares that a seller accepts compact baseline/metric/provenance fields from a buyer orchestrator and returns afeedback_id for accepted assertions.
Because this compact contract is experimental, a seller declaring
media_buy.performance_feedback also lists measurement.core in top-level experimental_features. This does not make the seller a measurement provider or require measurement in supported_protocols.
See provide_performance_feedback and measurement_gateway below for the provider → orchestrator → seller flow.
creative_approval_mode
Declares the seller’s tenant-wide creative approval posture after creatives are assigned and automated validation passes. This is not a notification surface or a new approval workflow; it tells buyers and compliance runners whether human review can still block serving eligibility. Compliance runners use this declaration mainly to decide whether auto-approval-dependent storyboards such asmedia_buy_seller/pending_creatives_to_start apply.
Sellers with mixed approval policies SHOULD declare
require_human unless every product/account that can be reached by the advertised agent supports automatic eligibility after automated validation. When the field is absent, approval behavior is legacy-unspecified; runners SHOULD NOT treat omission as an affirmative auto_approve claim. ai_assisted is intentionally not a value until the protocol defines what assistance changes in observable behavior.
supported_indicator_types and relationship_notifications
Lists the seller interpretations available on media-buy resource relationships.indicator_types_evaluated.
supported_indicator_types declares polling readback and does not require webhook infrastructure. A poll-only seller exposes those types through get_media_buys and omits relationship_notifications. When a seller does declare relationship_notifications, indicators.changed requires supported_indicator_types; a seller without an indicator catalog may instead declare creative.assignment_changed alone for assignment and approval changes, including when it is inline-only. Every notification declaration names get_media_buys as the complete authoritative repair read. A creative-library seller may include list_creatives as a bounded reverse projection; it mirrors relationship identity and scoped approval, while evaluated indicator snapshots reconcile toward the strictly newer indicators_as_of. Because this optional block advertises outbound invalidations, webhook_signing MUST include supported: true, profile, algorithms, and legacy_hmac_fallback.
Subscriptions, when supported, are prospective: activation does not replay current conditions. Buyers establish a complete get_media_buys baseline by enumerating known IDs or requesting all seven statuses and following pagination to exhaustion, without indicator_types. Sellers then fire the applicable invalidation after observing a semantic change. Poll-only buyers simply repeat direct reads. See Indicators and Warnings.
An inline-only declaration is therefore valid with event_types: ["indicators.changed", "creative.assignment_changed"] and repair_tasks: ["get_media_buys"]. Conversely, a creative-library seller may advertise projection_tasks: ["list_creatives"] without the assignment event when it cannot detect those changes; that declaration also requires supported_protocols to contain creative. Both additions are independent of each other, and repair_tasks remains the complete repair contract.
features
Optional media-buy features. Boolean declarations are commitments when true. Structured declarations commit only to the explicitly advertised sub-capabilities.bidding_policy is intentionally not a boolean. Each media_buy or package scope contains independent fixed and/or seller_optimized profiles. Every profile’s modes lists standalone support from automatic, bid_amount, max_bid, cost_per, and roas. A profile advertising standalone cost_per also declares cost_per_strengths; roas similarly declares roas_strengths. Optional supported_combinations entries independently identify max_bid_with_cost_per or max_bid_with_roas and list the strengths supported in that combination; a combination-only component need not appear in modes. Presence of one scope, allocation context, mode, strength, or combination makes no claim about another.
content_standards
Content standards implementation details. Presence of this object indicates the seller supports content_standards configuration including sampling rates and category filtering. Gives buyers pre-buy visibility into local evaluation and artifact delivery capabilities.
Example:
supports_local_evaluation is false, the failures_only filter on get_media_buy_artifacts will return an empty result set — all verdicts will be unevaluated.
execution
Technical execution capabilities:axe_integrations
axe_integrations is an array of Agentic Ad Exchange (AXE) endpoint URLs that this seller can execute through. AXE is the real-time execution layer for AdCP campaigns — it connects buyer agents to programmatic inventory via standardized exchanges.
When a seller declares AXE URLs in their capabilities, buyers can:
- Route impression-level execution through the declared exchange
- Use the exchange’s targeting, optimization, and measurement capabilities
- Execute alongside the seller’s direct-sold inventory
get_adcp_capabilities and filter products to AXE-enabled sellers using required_axe_integrations on get_products.
creative_specs
targeting
Device platform and device type targeting are implied by
media_buy support. Audience include/exclude targeting is implied by the presence of the audience_targeting capabilities object.
Subdivision inclusion and exclusion are declared independently through geo_regions and geo_regions_exclude. Seller-wide structured values are individual routing claims within the capability response’s scope; they do not promise that multiple values are jointly composable or available through the same execution route or account. Only Product overlay_support supplies the binding set of executable targeting permissions for that Product. For other geographic levels that retain a combined legacy rollup, sellers SHOULD support both directions. For any targeting-overlay list dimension declared in this table — geo, collection_list, or property_list — if a seller only supports one direction, it MUST return a validation error for unsupported fields rather than silently ignoring them; silently dropping an exclusion is an unsafe failure mode. See Targeting Overlays for exclusion semantics.
geo_proximity specifies which proximity targeting methods are supported:
geo_metros specifies which metro classification systems are supported:
geo_postal_areas specifies which country-local postal code systems are supported. The preferred shape is keyed by ISO 3166-1 alpha-2 country, with each country listing supported systems:
postal_code for the normal postal code string in countries without a more specific registered local system. During the 3.x migration, sellers SHOULD emit equivalent deprecated aliases such as us_zip alongside native country keys where an alias exists. Buyers and SDKs SHOULD normalize both shapes before making capability decisions.
geo_places is keyed by place identifier system. Registered keys are geonames, google_ads, and microsoft_ads; private or additional catalogs use an owner-controlled absolute HTTPS URI. Each system declares exact country-to-place-type support, exact accepted versions, and a machine-readable resolver:
geo_places is absent, buyers MUST NOT assume place targeting is available. If present, the seller MUST honor only the explicitly declared country/type pairs and exact supported_versions, or return a validation error. current_version MUST appear in supported_versions and is applied when the buyer omits system_version on new targeting. supported_versions describes versions accepted for new targets and target-changing updates; removing a version MUST NOT silently mutate, drop, or invalidate existing packages already pinned to that version. Optional source identifies a dataset or derivative without creating a new ID namespace—for example, a MaxMind-derived catalog still uses system: "geonames". The resolver accepts an HTTPS GET with get-geo-place-resolution-request.json query fields and returns get-geo-place-resolution-response.json, including lifecycle status and replacement IDs. Unsupported or deprecated identifiers must be rejected rather than silently ignored or replaced. Display labels are never authoritative targeting keys.
Registered system semantics are exact:
Registered place types are semantic classes, not a universal hierarchy.
city, municipality, and post_town are distinct; likewise borough, neighborhood, quarter, and ward are not interchangeable. The resolver’s country-specific mapping is authoritative for the system/version it serves. Sellers MUST NOT claim a country/type pair unless their resolver returns that type and their execution platform can honor it.
Resolver calls use HTTPS GET. Supply exactly one of q for name search or value to refresh an existing identifier against a catalog version. For example:
auth: "seller_credentials" means the buyer uses the same authorization credentials as the seller’s AdCP endpoint and is valid only when the resolver has the same origin as that endpoint. Buyers MUST NOT forward seller credentials cross-origin and MUST apply normal SSRF protections to resolver requests. auth: "none" declares a public resolver. A URI-valued system is an opaque namespace identifier and is not automatically fetched. Results identify the exact system version and lifecycle state:
system MUST equal the capability-map key that advertised the resolver. Its version MUST equal the requested system_version, or the advertised current_version when omitted. The response echoes the normalized request, and every match MUST equal its country and any requested subdivision and place_type. canonical_name and parent_labels are required so same-named results remain distinguishable; subdivision is also required on a match when the request constrained it. Registered numeric systems reject non-numeric values and replacement IDs.
Successful searches, including zero matches, return 200 with Content-Type: application/json and the response schema above. Invalid queries return 400; missing or invalid credentials return 401 or 403; throttling returns 429; and resolver failures return an appropriate 5xx. Non-200 responses MUST NOT be interpreted as an empty result set. Pagination repeats the normalized original request and uses cursor/next_cursor.
Buyers MUST traffic only an unambiguous active result. removal_planned results may still describe an existing target but should not be used for a new buy. deprecated results are invalid for new targeting; replaced_by_values may guide a new resolution, but sellers MUST require the buyer to submit the replacement rather than silently changing intent. To refresh a persisted ID after catalog rollover, query value=<existing ID> against the current version. Existing packages remain pinned to their echoed applied version until the buyer intentionally changes targeting; unrelated updates preserve that overlay. If the seller can no longer execute it, get_media_buys MUST preserve the echoed target and return nonfatal PLACE_TARGET_UNAVAILABLE in response-level errors[], with recovery: "correctable", an exact package-target field path, and target identity in details, rather than silently changing geography.
rights_attestations
Declares how this seller evaluates portable rights-grant credentials carried in creativerights[]. Presence requires adcp.attestations, and its accepted_claim_types MUST include https://adcontextprotocol.org/claims/rights/grant.
AttestationReference values and never supplies a trusted outcome. The seller evaluates the exact reference, holder issuer, authorized rights-agent key, subject, grant digest, validity, and fresh revocation status and returns seller-produced rights_attestation_evaluations on creative readback. Sparse list_creatives reads request rights_attestation_evaluations; the seller automatically includes creative_id and rights so each result can be paired with the retained constraint. Neither capability mode permits fallback to rights_constraint.verification_url; that deprecated URL has no authorization meaning.
audience_evidence
Structured product audience-evidence support. Presence means the seller publishes immutableProduct.audience_evidence snapshots, evaluates the declared buyer policy modes in get_products.filters.audience_evidence_requirements, and retains digest-pinned package readback. This is discovery and planning support, not audience targeting.
get_products evidence requirements.
audience_targeting
Audience targeting capabilities. Presence of this object indicates the seller supports audience targeting, includingsync_audiences and audience_include/audience_exclude in targeting overlays. Describes what identifier types the seller accepts for audience matching, size constraints, and expected matching latency.
conversion_tracking
Seller-level conversion tracking capabilities. Declares what the seller supports forkind: "event" optimization goals.
portfolio
Inventory portfolio information. Media-buy sellers SHOULD declare both routing arrays. The existingprimary_* names are retained for 3.x compatibility, but
a present array is exhaustive for brief routing: buyers MAY skip the agent when
a brief’s requested countries or channels do not intersect it. Omission means
unknown scope, never global coverage. These are routing pre-filters—not promises
that a matching product is currently available.
primary_countries is not executable geo-targeting capability. It answers
whether the sales agent accepts a country-scoped discovery brief; the structured
fields under media_buy.execution.targeting and each product’s
overlay_support determine whether and how a returned product can execute
geographic targeting.
signals
Signals protocol capabilities. Only present ifsignals is in supported_protocols.
catalog_signals is deprecated. Existing 3.x agents may continue to emit it
for compatibility, but new agents SHOULD omit it and callers MUST NOT require
it before using signal_ref. Treat supported_protocols: ["signals"],
signals.data_provider_domains, signals.discovery_modes, and the actual
get_signals response as the capability surface.creative
Creative protocol capabilities. Only present ifcreative is in supported_protocols.
governance
Governance protocol capabilities. Only present ifgovernance is in supported_protocols. Governance agents declare capabilities across four domains: property evaluation, creative evaluation, content standards verification, and policy registry integration.
runtime_attestations
Signal-activation policy layered on the sharedadcp.attestations allowlist. Presence means this governance agent accepts check_governance.runtime_attestations[] when purchase_type is signal_activation.
See
check_governance runtime signal attestations for request, evaluation, signed-context, and audit binding.
property_features
Array of property features this governance agent can evaluate. See Property Governance.creative_features
Array of creative features this governance agent can evaluate. Same field schema asproperty_features. See Creative Governance.
Creative governance agents evaluate creatives for security, content categorization, and regulatory compliance. Buyers filter creatives by feature requirements — for example, blocking creatives flagged for auto_redirect or requiring registry:eu_ai_act_article_50 compliance.
content_standards
Content standards verification capabilities. See Content Standards.policy_registry
Policy registry integration capabilities. See Policy Registry.
Example governance agent response:
measurement_gateway
Experimental buyer-orchestrator role within the measurement protocol. Presence means the orchestrator exposes a controlled task boundary to providers without granting them seller credentials. Orchestrators implementing it includemeasurement in supported_protocols and measurement.gateway in experimental_features.
The first experimental tier deliberately has one interoperable path: providers pull buyer-approved delivery from the orchestrator’s get_media_buy_delivery task and return one compact assertion through its provide_performance_feedback task. Webhook and offline interchange remain future work until their registration, credential, payload, and receipt contracts are defined.
get_media_buy_delivery and provide_performance_feedback shapes without claiming supported_protocols: ["media_buy"]; the orchestrator is not a seller and does not commit to the seller compliance storyboard.
measurement
Experimental measurement protocol capabilities. Only present ifmeasurement is in supported_protocols; agents implementing it must also list measurement.core in experimental_features. The provider-side surface is currently scoped to catalog discovery plus declaration of compact performance-feedback output. Measurement agents exchange data with a buyer-controlled orchestrator gateway rather than receiving seller credentials. Additional provider tasks and a baseline compliance storyboard should land only for concrete workflows that cannot use the gateway’s existing delivery paths.
Scope. An agent claiming measurement computes one or more quantitative metrics about ad delivery, exposure, or effect (impression verification, viewability, IVT, attention, brand lift, incrementality, outcomes, emissions — vendors define the surface in metrics[]). It returns metric definitions and may declare optimizer-ready feedback production, not pricing or coverage (negotiated per buy via measurement_terms) or raw/live datasets. Per-buy measured values remain on delivery reports; compact decision signals use provide_performance_feedback.
Measurement agents publish a per-metric catalog so buyers know which metrics each vendor offers. This is the canonical source of truth — AgenticAdvertising.org crawls it to populate the federated measurement-vendor index.
Providers using the first gateway tier consume
get_media_buy_delivery and produce provide_performance_feedback; there are no method-negotiation arrays in this release.
metrics
Array of metrics this measurement agent computes.Response example
get_adcp_capabilities directly to see its current catalog (live, canonical, no staleness), or query AgenticAdvertising.org’s federated index for cross-vendor aggregation. The index trades a TTL refresh window for cross-vendor speed; live calls trade speed for currency. Both are valid — typically planning queries hit the index, settlement/audit queries hit the agent.
This is a discovery surface, not a rate card. The catalog tells buyers what a vendor measures and what standards/accreditations back it. Pricing per impression, minimum measurable inventory, attribution windows, geographic coverage, and data-freshness SLAs are negotiated per buy through the seller’s measurement_terms on create_media_buy — not through this catalog.
compliance_testing
Compliance testing capabilities. The presence of this block declares that the agent supports deterministic testing viacomply_test_controller. Omit the block if the agent does not support compliance testing.
Production deployments MUST NOT include this block. comply_test_controller is sandbox-only at the deployment level; advertising the capability on a production endpoint is non-conformant even if dispatch is gated. See Compliance test controller § Sandbox gating.
Storyboard runners check for the
compliance_testing block before running deterministic testing steps. If the agent does not include the block, controller-dependent storyboard steps cannot be validated.
Agents that implement comply_test_controller SHOULD include the compliance_testing capability block and list supported scenarios. Agents that only support a subset of scenarios (e.g., media buy status but not SI sessions) declare only those scenarios — the runner reports unsupported scenario coverage as skipped or partial rather than as a hidden pass.
:::note
Compliance testing is sandbox-only at the deployment level — production deployments MUST NOT advertise this block or expose comply_test_controller on any surface. FORBIDDEN is returned only when an in-sandbox caller passes params that reference a non-sandbox account; live-mode probes for the tool by name receive the transport’s standard unknown-tool error. See Sandbox gating.
:::
webhook_signing
Declares a seller’s webhook-signing posture. Any seller whose capability surface advertises mutating-webhook emission — including but not limited tomedia_buy.reporting_delivery_methods containing webhook, media_buy.content_standards.supports_webhook_delivery: true, media_buy.relationship_notifications.supported: true, wholesale_feed_webhooks.supported: true, adcp.capability_changes.notifications.supported: true, or account.notifications.supported: true — MUST include this block with supported: true. A seller that emits no webhooks at all MAY omit the block entirely; the absence of both mutating-webhook emission in other capabilities and this block is an unambiguous “does not emit webhooks” posture. Buyers read the block at onboarding to determine which algorithms to expect per the AdCP webhook-signing profile. Buyers integrating with a seller that advertises mutating-webhook emission while advertising supported: false or omitting this block MUST fail onboarding with a user-actionable error; silent integration with a non-signing-but-webhook-emitting seller is unsafe for any mutating-webhook use case.
Example:
request_signing (inbound) and the two blocks cover the two signing directions between buyer and seller. Buyers SHOULD validate both at onboarding; a seller that signs one direction but not the other has a lopsided security posture that operators need to notice explicitly.
extensions_supported
Array of extension namespaces this agent supports. Buyers can expect meaningful data inext.{namespace} fields on responses from this agent.
Extension schemas are published in the AdCP extension registry. When an agent declares support for an extension, buyers know to look for and process
ext.{namespace} data in responses.
Example:
- Responses may include
ext.iab_tcfwith IAB TCF consent data - Responses may include
ext.iab_gppwith IAB GPP (Global Privacy Platform) signals - Responses may include
ext.acmecorpwith vendor-specific data from Acme Corp
experimental_features
Array of experimental AdCP surfaces this agent implements. A surface is experimental when its schema carriesx-status: experimental — it is part of the core protocol but not yet frozen and may break between 3.x releases with 6 weeks’ notice. Sellers that implement any experimental surface MUST list its feature id here.
Buyers should inspect
experimental_features before relying on an experimental surface. A seller that does not list a surface is asserting it does not implement it — there is no “silently experimental” mode.
Example:
wholesale_feed_versioning
Conditional-fetch token capabilities forget_products and get_signals. Independent of wholesale feed webhooks: an agent MAY support cheap version probes without pushing change payloads, and an agent MAY push change payloads while still requiring reconciliation reads for repair.
Example:
wholesale_feed_webhooks
Per-agent wholesale product-feed and wholesale signals-feed webhook capabilities. Declared by sales agents (products) and signals agents (signals). Whensupported is true, consumers can register sync_accounts.accounts[].notification_configs[] entries for product.*, signal.*, and wholesale_feed.bulk_change events and receive the actual change payload in each webhook. See specs/wholesale-feed-webhooks.md for the full spec.
Terminology. Here “wholesale feed” means the agent’s buyable wholesale product feed and wholesale signals feed exposed by get_products and get_signals. It is distinct from sync_catalogs, which pushes buyer-provided campaign input feeds into a seller account for campaign execution.
Complementary to (and independent of) wholesale_feed_versioning: webhooks push changed products/signals or bulk-change summaries; version tokens give a cheap repair and reconciliation probe. Adopters MAY ship either, both, or neither.
Agents that declare supported: true MUST apply the same account/caller authorization and scope predicate used by the corresponding wholesale read before emitting each webhook. A caller that could not see a product, signal, price, or account overlay through get_products buying_mode: "wholesale" or get_signals discovery_mode: "wholesale" MUST NOT receive a webhook revealing that change. Agents unable to guarantee per-principal filtering MUST NOT declare support.
Capability consistency. Agents listing any product.* value in event_types[] MUST declare and support wholesale get_products (media_buy.buying_modes includes "wholesale"). Agents listing any signal.* value MUST declare and support wholesale get_signals (signals.discovery_modes includes "wholesale"). Agents listing wholesale_feed.bulk_change MUST have at least one of those wholesale repair paths, and each bulk-change payload’s affected_entity_type MUST name only a feed family the agent can repair through a declared wholesale read.
Consumer precedence. When more than one mechanism is declared, consumers SHOULD prefer them in this order: (1) wholesale_feed_webhooks when maintaining a long-lived mirror (lowest latency, lowest seller cost); (2) wholesale_feed_versioning conditional fetch for occasional polling and webhook repair; (3) wholesale enumeration via buying_modes / discovery_modes for cold start, wholesale_feed.bulk_change, or any missed/distrusted push.
Example (sales + signals agent):
The Capability Contract
If a capability is declared, the seller MUST honor it.media_buy.execution.targeting.geo_postal_areas.UScontainszip→ Buyer can send{ country: "US", system: "zip", values: [...] }, seller MUST honor itmedia_buy.execution.targeting.geo_postal_areas.us_zip: true→ Buyer can send the deprecated{ system: "us_zip", values: [...] }form, and SDKs can backfill the native{ country: "US", system: "zip", values: [...] }formmedia_buy.execution.targeting.geo_postal_areas.ZAcontainspostal_code→ Buyer can send normal South African postal codes, seller MUST honor themmedia_buy.execution.targeting.geo_metros.nielsen_dma: true→ Buyer can send DMA codes, seller MUST honor themmedia_buy.execution.targeting.demographics.supported: true→ At least one product supports canonical demographic targeting; this rollup does not authorize the field on every product, so buyers MUST inspectProduct.demographic_targetingmedia_buy.execution.targeting.collection_list: true→ At least one product supports collection inclusion; inspect that product’soverlay_support.collection_listbefore selecting values latermedia_buy.execution.targeting.collection_list_exclude: true→ At least one product supports collection exclusion; inspect that product’soverlay_support.collection_list_excludemedia_buy.execution.targeting.property_list: true→ At least one product supports property inclusion; inspect that product’soverlay_support.property_listmedia_buy.execution.targeting.property_list_exclude: true→ At least one product supports property exclusion; inspect that product’soverlay_support.property_list_excludemedia_buy.execution.targeting.placement_selection: true→ At least one product supports purchased-placement selection; inspect that product’s targetable placements andoverlay_support.placement_selectionmedia_buy.content_standardsobject present → Seller MUST apply content standards when providedmedia_buy.audience_targetingobject present → Seller MUST supportsync_audiencesand audience targeting overlaysmedia_buy.conversion_trackingobject present → Seller MUST supportsync_event_sourcesandlog_event- AXE URL in
media_buy.execution.axe_integrations→ Seller can execute through that exchange (legacy — new integrations use TMP)
false or omit it.
Common Scenarios
Basic Capability Discovery
Check multi-protocol support
Filter sellers by capability
Use Capabilities to Build Targeting
Seller capabilities are a routing rollup. Userequired_overlay_support to
request the product-scoped targeting surface that must be selectable later, and
targeting_overlay for concrete constraints that must affect discovery:
- Digital inventory: Use
countries+required_geo_targeting(capability), apply fine-grained targeting increate_media_buy - Local inventory: Use
metros/regions(coverage) to find products with coverage in your target markets
Local Inventory Example (Radio, DOOH)
For locally-bound inventory, products ARE geographically specific. A radio station in NYC DMA only covers NYC.Response Example
- AdCP versions: Version 1
- Protocols: Media buy only
- Auth model: Agent-trusted (
require_operator_auth: false) — authenticate once and use natural-key accounts, normally declared viasync_accounts - Billing: Operator or agent billing; default is operator
- Country targeting: Available (ISO 3166-1 alpha-2:
US,GB, etc.) - Region targeting: Available (ISO 3166-2:
US-NY,GB-SCT, etc.) - Metro targeting: Nielsen DMA only (US market)
- Postal targeting: US ZIP, UK outward codes, Canadian FSA
- Audience targeting: Accepts hashed email, hashed phone, UID2, and RampID; minimum matched audience size of 500; matching latency 1–24 hours
- Conversion tracking: Accepts purchase, lead, add_to_cart, view_content events from website/app; no multi-source dedup
- Extensions: Vendor-specific data in
ext.acmecorp
Multi-protocol agent
An agent can implement multiple protocols from a single endpoint. This is common for sellers that manage both media buying and creative generation — the buyer calls all tasks on the same URL.- Media Buy Protocol: Product discovery, media buying, delivery reporting
- Creative Protocol: Creative library management, AI-powered creative generation, variant-level delivery analytics via
get_creative_delivery - Shared account: A single account established via
sync_accountsapplies to both protocols
supported_protocols includes "creative", inspect the creative capability block for the tasks and canonical formats this endpoint actually supports. list_creative_formats is deprecated in 3.2. See Creative capabilities on sales agents.
Geo Standards Reference
Migration from list_authorized_properties (v2)
Thelist_authorized_properties task was removed in v3. If migrating from v2:
New fields:
adcp.major_versions- Version compatibilitysupported_protocols- Which domain protocols are supportedmedia_buy.features- Optional feature supportmedia_buy.execution.axe_integrations- Ad exchange supportmedia_buy.execution.creative_specs- VAST/MRAID versionsmedia_buy.execution.targeting- Geo targeting granularity
Error Handling
Best Practices
1. Cache Capabilities Capabilities rarely change. Cache results for no longer thanadcp.capability_changes.cache_ttl_seconds when present, compare capabilities_version on refresh when present, and subscribe to capabilities.changed if the seller advertises notification support. When notifications are enabled, capabilities_version is the required read-after-notify fence; retry refresh if a webhook revision is not yet observable. Fall back to last_modified or legacy last_updated only when capability_changes.notifications.supported is absent or false.
2. Check Protocol Support First
Before accessing protocol-specific fields, verify the protocol is in supported_protocols.
3. Check Before Requesting
Don’t send postal areas for a system the seller doesn’t support. Don’t request features the seller doesn’t support.
4. Fail Fast on Incompatibility
If a seller doesn’t support required capabilities, skip them early rather than discovering failures later.
5. Read the Auth Model Before Proceeding
Check account.require_operator_auth immediately after discovery. Agent-trusted and operator-scoped flows diverge significantly: the former uses a single credential for all brands and operators, the latter requires per-operator credentials and sessions.
6. Use Protocol Version for Routing
Route requests to appropriate API versions based on adcp.major_versions.
Next Steps
After discovering capabilities:- Set up accounts: Follow the auth model from
account.require_operator_auth— see Accounts and Agents - Filter products: Use
get_productswith capability-aware filters - Validate properties: Fetch publisher
adagents.jsonfiles for property definitions - Create buys: Use
create_media_buywith supported features
Learn More
- Accounts and Agents - Auth models, account setup, billing
- adagents.json Specification - Publisher authorization files
- Product Filters - Capability-aware filtering
- Content Standards - Brand safety configuration