16 Oct 2026 · 7 min read
How Does AdCP Verify Which Agent Is Asking? Request Signing, Key Publication and Idempotency Explained
Before a seller acts on an AI agent's request to commit budget, it needs to know which agent sent it, whether it was altered in transit, and whether it has already been executed. AdCP, the Ad Context Protocol, answers the first two with request signing, built on HTTP Message Signatures (RFC 9421) and public keys the agent publishes on its operator's domain, and the third with idempotency keys. A valid signature identifies the agent. It does not prove the agent may spend for the brand it names; the AdCP documentation treats that as a separate check.
TL;DR. According to the AdCP documentation, a buyer agent signs each state-changing request, and the seller verifies it against a public key listed through the operator's brand.json file. Every mutating task, including create_media_buy, carries an idempotency_key, so a retry returns the original result instead of placing a second buy. In AdCP 3.2, the current general release, signing is optional and declared per operation; the documentation states that version 4.0 makes it mandatory for spend-committing operations.
Why does agent identity matter when software commits budget?
In a traditional buy, a person reads the insertion order before money moves. In an agent-to-agent buy, the request is the commitment. The AdCP security model puts it directly: "In agentic advertising, the agent is the human."
Two failures matter most. Impersonation: a request that claims to come from an agency's buying agent but was sent with a stolen credential, or changed in transit. Duplication: an agent times out, retries, and creates two buys where the advertiser wanted one. The AdCP documentation counts replay protection for retried buys among the controls agentic advertising adds to ordinary API security.
How does AdCP request signing work?
AdCP narrows RFC 9421, the IETF standard for HTTP Message Signatures, to one fixed profile so that independent implementations agree. According to the AdCP documentation, a signature covers the HTTP method, the full target URL, the host, the content type and a digest of the exact request body. From version 3.2, every signed request with a body must cover that digest, so nobody in the middle can swap one instruction for another under a valid signature.
Each signature carries six required parameters: creation time, expiry time, a random single-use value (the nonce), the key identifier, the algorithm, and the fixed tag adcp/request-signing/v1. Expiry can be no more than five minutes after creation, and only two algorithms are accepted: ed25519 and ecdsa-p256-sha256.
Where does a buyer agent publish its keys?
According to the documentation, the operator hosts brand.json at /.well-known/brand.json; each entry in its agents list gives the agent's URL and a jwks_uri; that address serves a JSON Web Key Set holding the public keys. Each key must be labelled for request signing (adcp_use: "request-signing") and carry its own identifier.
Publishers get an extra control. In adagents.json, the file listing the sales agents allowed to sell its inventory, a publisher can pin the keys each agent may sign with. Pins are required for agents that can perform mutating operations, and a pin overrides whatever the agent's own domain publishes, limiting the damage if that domain is compromised.
Keys rotate by overlap, with the old key removed after 24 to 48 hours. A compromised key goes on a revocation list, which invalidates every request ever signed with it.
How does a seller verify a signed request?
The AdCP documentation gives sellers an ordered checklist that stops at the first failure. The seller checks the parameters, tag, algorithm and time window; matches the key identifier to exactly one agent entry in a published brand.json, rejecting signatures it cannot tie to a specific agent; checks the key's purpose and revocation status; verifies the signature and body digest; and rejects any key and nonce pair it has already seen.
Passing proves something narrow, and the documentation says so: "A valid signature alone proves only that the key signed the request." Whether the agent's operator may act for the named brand is answered separately, by the brand's own brand.json, which lists its authorised operators, and for inventory by the publisher's adagents.json. The protocol also carries no check that an organisation's identity has been verified; that sits with membership and account onboarding.
How do idempotency keys prevent duplicate buys?
An idempotency key is a unique identifier a buyer attaches so the seller can recognise a retry. According to the AdCP documentation, mutating tasks including create_media_buy, update_media_buy, sync_creatives and activate_signal must carry an idempotency_key in UUID format.
The same key with the same request returns the original response, marked replayed: true, and nothing executes twice. A fresh key is a new operation, whatever the request says; the documentation calls generating a new key after a failed attempt "the most common way naïve callers create duplicate media buys". The same key with a different body is rejected with IDEMPOTENCY_CONFLICT. A retry that arrives while the first request is still running gets IDEMPOTENCY_IN_FLIGHT and should be retried later with the same key.
In a hypothetical example, a buying agent's £40,000 create_media_buy request times out. Without a key, it must retry and risk booking twice, or abandon a buy that may already exist. With one, it retries with the same key and receives the original confirmation.
Sellers declare how long they remember keys through replay_ttl_seconds: at least one hour, 24 hours recommended, seven days at most. Keys are scoped to the authenticated agent and account.
Is request signing mandatory in AdCP?
Not in version 3.2. Each seller's get_adcp_capabilities response lists the operations it verifies (supported_for), monitors without enforcing (warn_for) and requires (required_for). Sellers may instead authenticate agents with mutual TLS or API credentials issued at onboarding. The documentation states that AdCP 4.0 makes signing mandatory for spend-committing operations.
The documentation is candid about one limit. Keys are discovered from each counterparty's own infrastructure, so an attacker controlling an agent's domain could serve their own keys. It calls the 3.x position "trust-on-first-use with continuity", recommends alerting on unexpected key changes, and lists a key-transparency layer as work for version 4.0.
What should buyers and publishers ask a vendor?
These questions draw on the pre-launch checklist in the AdCP security model:
How does your agent authenticate, and for which operations does it sign requests?
Where are your public keys published, and how do you rotate and revoke them?
Which operations does your capabilities response list under
required_for?What replay window do you declare, and does your idempotency store survive a restart?
For publishers: have you pinned signing keys in
adagents.jsonfor every agent that can write on your behalf?
The same questions apply under IAB Tech Lab's AAMP framework, where agent discovery runs through the Agent Registry in which companies list the agents they bring to market. Alkimi operates a neutral agentic advertising marketplace that works within the AAMP framework today, is being built to be AdCP compatible, and checks that each connecting agent is authorised by the buyer or publisher it represents; agreed deals go on a shared DealSheet both parties hold, with humans keeping approval rights at the deal level.
Frequently asked questions
Does a valid AdCP signature prove an agent may spend for a brand?
No. According to the AdCP documentation, a signature proves which key signed the request. Whether the agent's operator may act for the brand is a separate check against the brand's brand.json and, for inventory, the publisher's adagents.json.
What happens if a buying agent retries a media buy in AdCP?
With the original idempotency_key and the same request, the seller returns the original response marked replayed: true. A fresh key creates a new buy.
Is request signing required in AdCP 3.2?
No. Each seller declares which operations require it. The AdCP documentation states that version 4.0 makes signing mandatory for spend-committing operations.
What is the difference between a nonce and an idempotency key?
A nonce is a single-use value that stops one signed message being sent twice. An idempotency key identifies the business operation, so a retry signed with a new nonce still returns the original result.