What is enforced today
Routing buys by declared features is being rolled out. Today, when a buy has a property list, we send the list only to Agents that declare property-list support. We may still return Products from an Agent that does not declare support, and may send that Agent a buy without the property list. Declare every feature your Agent honours so the routing can apply it correctly. The seven-day behaviour baseline below is our published requirement, but we do not yet calculate or enforce it automatically. We are rolling out automated checks for it; today, our team reviews the calls we make to your Agent with you. Do not treat a missing automated check as permission to skip a requirement.How we assess an Agent
We use evidence from our own calls to your endpoint. That includes theget_adcp_capabilities, sync_accounts, and get_products calls we make, as
well as requests made while discovering inventory and handling buys. We measure
the response your Agent sends, its timing, task progress, and whether returned
products honour the request. We do not accept a self-reported claim as proof
that an Agent behaves this way.
Required declarations
AdCP 3
What it is. Yourget_adcp_capabilities response must include major
version 3 in adcp.major_versions. Responses must validate against the schema
for the version we negotiate.
Why buyers care. A buyer needs the same contract that your Agent says it
supports, so a discovery result or buy does not fail when it reaches your
system.
How we measure it. We call your capabilities endpoint and validate the
responses we receive at the negotiated version.
A supported billing model
What it is. Declareagent, operator, or both in supported_billing.
This is a seller-wide declaration, selected for each account in
sync_accounts. We review advertiser billing case by case.
Why buyers care. The billing model determines who can operate the buy and
settle it without a manual intervention after the buyer is ready to transact.
How we measure it. We read the billing declaration from the account and
capability responses we call, rather than relying on a separate statement from
your team.
A creative kind we supply
What it is. At least one Product must accept one of the creative kinds we supply informat_options: display_tag, video_vast, or audio_daast.
Why buyers care. A buyer can only place a buy if Apostra can deliver a
creative that the Product accepts and can measure.
How we measure it. We inspect the Products returned by our own
get_products calls.
Per-buy features
Property-list targeting
What it is. Property lists are a per-buy feature. In AdCP 3.1, declaremedia_buy.features.property_list_filtering and, for each applicable Product,
property_targeting_allowed. If your Agent negotiates AdCP 3.2, also declare
media_buy.execution.targeting.property_list and
property_list_exclude, plus overlay_support.property_list on each
applicable Product.
Why buyers care. A property list lets a buyer direct a buy to the intended
publishers, stations, or networks. It applies to every channel, including
linear TV and radio.
How we measure it. We read these declarations from the capability and
Product responses we call. On buys that include a property list, we also check
that the returned Products honour the property list, channels, and countries
we sent.
Property-list support is a per-buy requirement that is being rolled out; it
does not block an Agent. Today, we send a property list only to an Agent that
declares support. We may still return Products from an Agent that does not
declare it and send that Agent a buy without the list. As feature routing rolls
out, a buy that needs a property list will go only to Agents that declare
support, while Agents that do not declare it can still receive buys that do not
need it. Declare every feature your Agent honours.
Required behaviour
We assess these behaviours over the preceding seven days. A failure in this baseline applies to the Agent as a whole, not to one Product or one use case.
Repeated means three or more events within the seven-day window. For this
baseline, that applies to stale async handoffs and breaches of the request.
Persistent means that the flagged condition appears on three or more
separate days within that window.
Async tasks
AdCP 3.1 has no capability field for async tasks. We therefore assess them by behaviour, not declaration. If a request cannot finish in time, returnsubmitted or working with a task handle. Then complete the task, or send a
status update, before its deadline through polling or webhook. The
responsiveness and async-completion rows above are how we assess that handoff.
What happens when we find a problem
A flag tells you what we observed and how to fix it. A blocker stops new buys for every use case on the Agent. Running buys continue in both cases. This protects buyers from starting another buy while preserving an active buy that needs to complete, report, or be stopped safely. Automated flags and blockers for the behaviour baseline are not live yet. Until they are, our team reviews the evidence from our calls with you. The thresholds on this page remain the standard we use for that review and for the automated checks now being rolled out.Choose the sandbox account to use for certification
Before live-traffic certification can run its test buys for an Agent source, choose one account that the Sales Agent currently returns fromlist_accounts
as an active sandbox account. The setting uses the same
seller-account authorization as other inventory-source changes. It allows a
principal acting in a Seller Account, including signed-in seller users, staff
switched into the seller account, connected chat assistants acting through MCP OAuth, user-owned API
keys, and agent, hosted-runtime, acting-user, or agent-registration contexts
when they carry an attributed user. The principal type does not change this
seller-account check.
Every change must also identify a user for the audit record. Seller-scoped
organisation API keys and other machine credentials without an attributed user
cannot choose or clear the certification sandbox account. Buyer and parent
account contexts are refused by the same seller-account authorization used for
other source changes. System credentials and SuperAdmins receive the normal
seller-account role bypass, but still need an attributed user to make this
change. Callers from another seller tenant cannot access that seller’s Source.
Use the REST API at
/api/v2/storefront/inventory-sources/{sourceId}/certification-sandbox-account,
or by asking a connected chat assistant, which uses save_inventory_source.
The certification sandbox account records the specific account used for
certification. Before every certification buy, we check that the Sales Agent
still reports it as active and sandbox: true. This
prevents test buys from being sent to an account that the seller has not
explicitly identified as safe for certification.
Use POST /api/v2/storefront/inventory-sources/{sourceId}/certification-sandbox-account
with { "accountId": "seller-sandbox" }. GET on the same path returns the
certification sandbox account, including its verification time and the user who
last chose it, plus the sandbox accounts currently reported by the Source. Use
DELETE on the same path to clear the certification sandbox account.
In v3, call save_inventory_source with the existing Source id and
certificationSandboxAccountId, for example
{ "id": "my-sales-source", "certificationSandboxAccountId": "seller-sandbox" }.
Set certificationSandboxAccountId to null to clear the certification
sandbox account.
Read it back with get({ kind: "inventory_source", id: "my-sales-source", include: ["certificationSandboxAccount"] }).
Managed sales-agent sources do not use this setting. Certification uses the
certification buyer’s admitted sandbox storefront account instead. The account
must be active and marked sandbox: true, and it must match the buyer’s
operator and the certification advertiser’s brand. We send the buy and any
creative sync through the normal managed path, which resolves the managed
sales-agent account when it creates the buy. There is nothing for the seller to
choose or clear on a managed source.
If there is no matching active sandbox storefront account, certification skips
that family with sandbox_buyer_account_missing. This includes an account with
the matching operator and brand that is not marked as a sandbox account.
For managed certification, name a no-charge test advertiser in your ad server.
The certification buyer’s sandbox storefront account is mapped to that advertiser
through the normal Buyer Account Mapping decision as an active, dedicated binding.
The buy runs on your real serving path; the platform never bills it, and you
provide the no-charge test placement. Certification does not use a shared default,
an unbound native account, or a not_required binding.
Best practices
These practices are not separate eligibility requirements, but they make an Agent easier to integrate and recover when something fails.Return AdCP error codes
What it is. Return the applicable AdCP error code whenever an operation fails. Why buyers care. A structured error lets buyer software decide whether to retry, correct the request, or show the buyer the next action. How we measure it. We classify the errors returned by our calls. An error we cannot classify is visible in the behaviour review above.Return an account ID from sync_accounts
What it is. When sync_accounts creates or confirms an account, return
its account_id on that account’s row. Apostra stores the ID and sends
account: { account_id } on later get_products and create_media_buy
calls for that account, instead of the brand and operator.
Keep the ID stable for the life of the account. A response row that names a
different brand_id from the one we sent, or reports a failed action, is not
taken as the account’s ID.
Why buyers care. An ID names exactly one account. If the same brand and
operator match more than one account on your side, the brand and operator
alone return ACCOUNT_AMBIGUOUS, and the buyer’s discovery or buy fails.
How we measure it. We read the account_id from the account rows in your
sync_accounts responses, and the account-resolution results of the calls
that follow.
Hand off long work quickly
What it is. Returnsubmitted quickly when work needs more time, with a
task handle that callers can poll or receive by webhook.
Why buyers care. The buyer gets a durable acknowledgement instead of
waiting for a request that will exceed the response window.
How we measure it. We record the initial response time, task handle, and
later task status from our calls.
Declare AdCP channels on every Product
What it is. Every Product declares the AdCP media channels it sells inchannels, such as display, olv, ctv, or streaming_audio. A Product
that sells different channels through different formats can instead declare
applies_to_channels on each format option. A format type on its own, such as
a video or audio format, is not a channel, because several channels share a
format.
Why buyers care. Buyers filter discovery, route proposal requests, and
report delivery by channel. A Product with no channel is missing from
channel-filtered discovery, and its delivery reports with no channel.
How we measure it. We read channels, then applies_to_channels, on the
Products returned by our get_products calls. Storefront readiness counts the
Products that declare neither (see
Diagnostics), your Agent page
shows the same count as an advisory note under Catalog Product Quality, and live-path
certification skips such a Product with the reason missing_channels rather
than certifying it on a guessed channel. When a Product relies on
applies_to_channels and only some of its format options declare it, the
other formats are skipped with the reason missing_channels:<format_kind>. Today this is a best practice: a
missing channel produces a warning and never blocks your Agent. Channels will
become required for external Agents’ Products in a later change, announced
before it takes effect.