Argued Agentic Ad Lab
AdCP vs AAMP: Which Standard to Implement
Back AdCP for the campaign path, and count the missing pieces on both sides: what each stack does not do, the two conditions that flip the call, and the AGPL exposure in ARTF.
18 min read 8 chapters
A judgement, signed. The evidence is checkable; the conclusion is mine to defend.
Back AdCP. If you have one integration budget for the next two quarters, spend it there and keep AAMP as a watch item with a named owner and no engineers attached.
The call is narrower than the operation counts make it look, because both stacks have holes and the holes are not all of one kind. AAMP ships no measurement object on the wire, no governance contract beyond the endpoints one reference agent happens to expose, and creative operations that exist but return mock data: agentic-direct serves Creative and Assignment CRUD over MCP, and its handlers call generateMockResponse. AdCP ships no priced negotiation, no measurement operation group and no normative consent tag on the campaign path, its own limitations page’s phrase; the single consent object in the specification is optional and rides the experimental identity_match request.
Three blanks each, and then a fourth item on the AdCP side that is a different kind of defect: its serve-time layer is shipped rather than missing, and all twelve of its schemas carry x-status: experimental. The call still goes to AdCP, and it turns on a property of the blanks rather than a count of them: AdCP’s are dated, and you can watch them move.
dist/schemas/latest.json read 3.1.13 on 11 August and reads 3.1.14 today. Diff the two manifests and nothing an integration touches has changed: 64 tools in each, the same 64 names, 92 error codes, 21 specialisms, none added and none removed. Freeze the directory, run a conformance suite against it, re-run the same suite next quarter against a byte-identical artifact. A version number that moves while the operation set holds still is what you write into a contract, and any reader can re-run that diff in two requests.
AAMP’s buyer-to-seller wire contract lives in iab-agentic-primitives. Its README, read on 16 August 2026, tells you to “pin an exact tag when depending on it” and then, in the next clause, that “APIs, schemas, and package layout may still change between releases until a 1.0 IAB Tech Lab standardization”. Pin which number, though. The library tags v0.5.1; the OpenAPI document inside it declares info.version: 0.1.0 over 13 operations and 48 JSON Schemas, and nothing reconciles the two. A supply contract needs a conformance clause, and that sentence will not carry one.
The umbrella version does not close the gap. IAB Tech Lab announced AAMP 2.3 on 30 July 2026 and the number matches no tag, no release and no version field in any of the eight repositories; the protocol map works through why an umbrella number is not a pin.
A counterparty that publishes only an AAMP agent card flips the call, because you implement what they serve. So does serve-time work.
ARTF, the Agentic Real Time Framework, in the agentic-rtb-framework repository, lets a third-party agent patch the bid object while the auction clock is running, inside somebody else’s OpenRTB auction under tmax, and what AdCP has at that layer is the twelve experimental schemas above. AdCP’s own experimental contract says such surfaces may have fields “renamed, removed, or have their type changed” and task names renamed inside 3.x, on six weeks of notice against the six months a stable surface gets. That work goes to your general counsel before it reaches an engineer: the Go implementation is AGPL-3.0 under Index Exchange copyright.
Your first move, by side
If you sell inventory, publish two static documents this week. adagents.json and brand.json at /.well-known/ make you discoverable to a buying agent before you implement a single operation, and the reason to publish them now is that they cost an afternoon and can be withdrawn, not that a buyer is known to read them: no buying agent has been observed fetching either at decision time (what the files carry). The AAMP equivalent is an agent card plus a registry entry to resolve it, which costs more and reaches fewer buyers today.
If you buy, run one HTTP request per counterparty domain before the protocol argument starts. Does the domain serve /.well-known/adagents.json, or hand you an agent card and a registry to resolve against? The responses decide your order of work. If nothing resolves across your top twenty partners, you are early: put a date in the calendar and spend the budget elsewhere.
The blanks run both ways
AAMP has no single surface to cite, so its column names repositories: naming operations would imply a coherence that is not there.
| Job to be done | AdCP 3.1.13, operation set unchanged in 3.1.14 | AAMP, by repository | What it costs you |
|---|---|---|---|
| Agent discovery | get_adcp_capabilities, plus adagents.json and brand.json at /.well-known/, hosted on the domain itself | GET /.well-known/agent.json, plus POST /registry/agents/discover in iab-agentic-primitives | Two static files on your own origin, against a registry entry somebody else grants |
| Trust | Five graded values computed by the consumer, never issued: inline, mutual_assertion, one_sided_brand, one_sided_house, standalone, left to deployer policy | Five states issued by the registry, Agent.trust_status in iab-agentic-primitives: unknown, registered, approved, preferred, blocked, written by PUT /registry/agents/{agent_id}/trust on seller-agent | Advisory on one side, price-affecting on the other |
| Inventory discovery | get_products, with a required buying_mode of brief, wholesale or refine; list_creative_formats | GET /products, GET /products/{product_id}, POST /products/avails; media kit and package endpoints on seller-agent | The one job both stacks do, and the only one a vendor demo will show you |
| Negotiation | No priced multi-round negotiation. Nearest surface is buying_mode: "refine", carrying a natural-language ask | Negotiation.json in iab-agentic-primitives, served by seller-agent at POST /api/v1/negotiations/messages, carrying action, buyer_price and round_number, returning concession_pct | A concession budget on one side, a seller you trust to re-price on the other |
| Transaction | create_media_buy, five required fields (idempotency_key, account, brand, start_time, end_time), returns media_buy_id; update_media_buy is PATCH | Two steps, typed in iab-agentic-primitives and served by seller-agent: POST /api/v1/quotes mints a quote_id, POST /api/v1/deals books it; /api/v1/change-requests amends | Two round trips where AdCP takes one, and a second idempotency surface to test |
| Creative | Eight operations, build_creative through validate_input | None. Creative and CreativeApproval are objects only; agentic-direct’s creative handlers call generateMockResponse | Creative review stays a manual process sitting beside the AAMP agent |
| Governance and consent | 22 operations, a third of the surface: property and collection list CRUD, list_content_standards, calibrate_content, check_governance, get_plan_audit_logs. No normative consent tag; the one consent object is optional, on the experimental identity_match | No governance operation in iab-agentic-primitives. seller-agent carries the deployment-level equivalents: PUT /registry/agents/{agent_id}/trust, /approvals/{approval_id}/decide, /api/v1/change-requests/{cr_id}/review. ConsentContext carries eight fields, among them gpp_string, tcf_string, us_privacy and gdpr_applies, optional everywhere it appears | An AdCP campaign integration carries no consent string, so EU sign-off is built beside the protocol rather than in it; AAMP gives you the field and requires nothing to fill it |
| Signals and audiences | get_signals, activate_signal, sync_audiences | agentic-audiences, a draft embedding exchange using application/vnd.ucp.embedding+json; v=1; its joining schema specs/v1.0/schema/agent_interface.schema.json is zero bytes | Any AAMP audience delivery date is a date for somebody to write the empty file first |
| Serve-time decisioning | Trusted Match: context_match and identity_match over direct HTTP, no auction. 12 of 12 schemas experimental | ARTF v1.0: RTBExtensionPoint.GetMutations(RTBRequest) returns JSON-Patch-shaped mutations keyed on an Intent enum with eight defined intents plus an unspecified zero, applied under tmax | Counsel on one side, a six-week change window on the other |
| Measurement | No measurement operation group. get_media_buy_delivery, provide_performance_feedback, log_event, report_usage, plus four core objects: measurement-terms, measurement-readiness, measurement-window, outcome-measurement | No measurement object in iab-agentic-primitives. Reporting is per implementation: /gam/report and /api/v1/orders/report on seller-agent, /reports/{job_id} on buyer-agent | A per-vendor reporting integration either way |
Two groups made different bets about which part of a media transaction is the hard part. AdCP built the campaign record and left the price conversation in prose. AAMP built the price conversation and left creative, governance and measurement to whoever deploys the reference agents. How a machine buys media traces one purchase at the wire level; AAMP Explorer breaks the right-hand column out repo by repo.
The trust row is the one that decides money. AdCP keeps authorisation and grading apart. What authorises a transaction is an adagents.json declaration plus RFC 9421 request signing, normative in 3.1, with AAO Verified as an out-of-band conformance mark. The grade is separate and touches no price: the consumer computes it, matching a brand’s house_domain in brand.json up against the house portfolio’s brand_refs[] pointing back down, with each side required to name the other. AAMP’s five are issued, and the schema says what they do: “Registry-verified trust status. Caps the effective AccessTier; never self-asserted by the agent.” The trust status entry puts both enums side by side.
Measurement is the blank they share. AdCP carries the exposure records and outcome signals that feed attribution “but it does not specify an attribution model”, and says it “is not MRC-accredited and does not seek accreditation”; AAMP’s wire contract has no measurement object at all. On the question a CFO asks first, both stacks hand the problem back and reporting stays a per-vendor integration. What neither stack standardises has the rest.
AAMP’s blanks sit next to real work, which is what keeps it a watch item rather than vapour: 13 operations and 48 JSON Schemas in iab-agentic-primitives, 74 OpenAPI paths on the seller agent, a 534-line ARTF specification with a protobuf contract. Most of that is one team’s application, and it moves on the next minor release.
The parts that would make it a standard rather than a codebase are the thin ones. registry-agent-example is a 22-line agent.ts. Counting only what sits under specs/, four files in agentic-audiences are zero bytes, among them the schema that would join the embedding format to either agent, while the specification with content in it titles itself “Draft v0.1” from inside a directory named v1.0. The seller agent talks to the AAMP agent registry when AAMP_REGISTRY_URL is set and falls back to what its own source calls “the legacy stub clients” otherwise, which is the default. Discovery is where AAMP is least finished; the AAMP page has the repo-level verdicts.
AdCP’s full surface, by contrast, is documented field by field against one version number: 761 schema files and 344 documentation pages in the checkout cited here, so an engineer can answer “what does this field mean, and what happens if I omit it” out of the specification. AAMP’s repositories are just as public, and every count on this page was read from them at a cited commit; what is missing is not access but a field reference, so for most of the surface the answer is in a reference implementation’s source. AdCP’s conformance suite is bigger and points inward, testing AdCP against AdCP. iab-agentic-primitives also ships a standards gap report whose stated rule is the best sentence in either corpus: “‘We model a field named after a standard’ is never treated as ‘we verified conformance against the published standard’.”
Negotiation, and the caps you cannot read
The transports compose and the object models do not. An AdCP media_buy and an AAMP Deal are unrelated types with unrelated lifecycles, so an agent that already speaks MCP is adding a vocabulary, while a buyer who wants both stacks is buying two integrations and two conformance suites to keep green. Negotiation is where that costs money.
AdCP negotiates in sentences. A buyer who wants a cheaper plan sends refine with ask: "reduce total by 10%" and lets the seller re-price. AAMP negotiates in numbers, and returns concession_pct and cumulative_concession_pct so both sides can see the budget draining. AdCP’s model is more expressive and much harder to test, and on price I want the numbers.
The numbers are not in the wire contract. Negotiation.json carries buyer_tier and a round history and no caps at all, and its own description says why: the seller’s floor price, base price, strategy and concession limits are “seller-internal guardrails and are deliberately absent from the shared schema”. The caps a deployment gets are four Python constants in the reference seller agent, three rounds at 3% per round and 8% cumulative at the tightest setting, six rounds at 6% and 20% at the loosest. Run seller-agent and you inherit those four tiers by not choosing them; buy against it and you cannot read one of them off any published schema (AAMP Explorer reproduces the table).
Nor is the tier assigned the way the endpoint’s shape suggests. post_negotiation_message claims a tier from the buyer’s own buyer_identity, advertiser first, then agency, then seat, then public, and hands that claim to a verifier that caps it at a ceiling keyed off the API key; an anonymous self-assertion floors to public. The buyer claims, the seller caps, and a publisher about to expose a rate card wants that settled before the first counter arrives.
A retried message also spends a round, because the handler never reads the idempotency_key its own schema makes required (the diligence question has the mechanism). On the public tier that is one of your three rounds and 3 of your 8 cumulative points gone to a timeout nobody logged.
Campaign path or auction path
A priced quote-and-book flow is not what the industry’s summary of this rivalry says AAMP is for. AdCP’s own FAQ files the rivalry away in one line: “Put simply: AAMP is agentic bidding; AdCP is agentic buying.” ARTF fits that sentence. The rest of AAMP does not, because its wire contract exposes /products, /api/v1/quotes, /api/v1/deals, /api/v1/change-requests and /api/v1/negotiations/messages over OpenDirect 2.1, which is quote, negotiate, book and amend, the campaign layer AdCP occupies. The same table, stamped “As of April 2026”, calls AAMP’s public schemas “Being defined”; there are 48.
The two stacks do not even share a noun for the sell side. AdCP’s glossary defines a sales agent as “an MCP server that exposes publisher inventory for discovery and purchase”; AAMP calls the same role a seller agent and named a repository after it. That matters when your RFP asks a vendor whether they support agentic buying and both sides answer yes. The term map lines the two sets of nouns up.
Craig Tuck’s objection, that “the biggest risk we see with an innovation like AdCP is decreasing transparency and control”, and Paul Bannister’s claim that agentic trading “puts the buyer directly in touch with the publisher’s ad server and removes other middlemen”, are both true, of different planes. The deployment ledger adjudicates the pair against the campaigns that have actually run. The campaign path is buyer to publisher, with a record of who agreed what. The auction path is a mutation applied to somebody else’s bid inside somebody else’s auction under a timeout. Which path you buy on decides which of the two you get.
Governance, licensing and the AGPL exposure
Which body stands behind each path, and on what licence terms, is the other half of that decision.
| AdCP | AAMP | |
|---|---|---|
| Steward | AgenticAdvertising.org (AAO), a pending 501(c)(6) Delaware trade association | IAB Tech Lab |
| Governance documents | CHARTER.md and IPR_POLICY.md in the repository, with Bylaws, Membership Agreement and Antitrust Policy at agenticadvertising.org | Four bullet points in the hub README: contributions to the child repository, proposals to the hub, cross-cutting changes discussed first, IAB Tech Lab policies apply |
| Release model | One semantic version, dist/schemas/latest.json as the oracle, wire pins at release precision ("3.1") | “Each repository uses independent semantic versioning. Cross-repository alignment occurs via governance coordination.” |
| Version oracle | Published and machine-readable | None. Eight git tag outputs, four of them empty |
| Licence | Apache-2.0 across the repository | Mixed. Apache-2.0 for the hub, buyer-agent, seller-agent, agentic-direct and iab-agentic-primitives; ARTF’s Go implementation AGPL-3.0, copyright Index Exchange, its specification CC BY 3.0; agentic-audiences CC BY 4.0 and Apache-2.0, copyright LiveRamp; registry-agent-example no licence file at all |
| Reference implementation | Handed to the Prebid community on 29 January 2026. AAO owns the specification, Prebid owns the software | The reference implementations are the deliverable. buyer-agent and seller-agent are where the protocol currently lives |
“AAMP is Apache-2.0” is a reasonable assumption and it is false. ARTF’s LICENSE file is the GNU AGPL v3 text and the README names the holder, Index Exchange Inc. Vendor that Go implementation into a hosted exchange and section 13 puts your users in scope, reaching every buyer that hits your endpoint. Whether it reaches them in practice is a reading for counsel rather than a fact off a file, and no published opinion from either body, or from Index Exchange, addresses it. That belongs in the first vendor call.
Anthony Katsur’s objection to standards proliferation is right, and the integration bill is where it shows up. He is right too that “when you remodel the kitchen, you don’t burn down the house” — AAMP is built on OpenDirect 2.1, AdCOM and OpenRTB, all IAB Tech Lab work. What the metaphor hides is that his remodel shipped as eight rooms with eight release schedules and no plan covering the house.
Andrew Casale calls the category “a soup of confusion” and the evidence backs him, though the soup is thickest inside AAMP: eight repositories, four with no tag at all, a press-release version that matches none of them, and one component that nobody can route around shipped under a licence that reaches its host’s users. Casale said it to ExchangeWire on 14 January 2026 as CEO of Index Exchange, which is the company on the copyright line of that licence.
AAO’s interim board is half one vendor and its own FAQ says so: four interim directors, two of them Scope3-affiliated, and a first Annual General Meeting dated 6 May 2026. That is more than a body still calling its own incorporation pending has to publish. I price that concentration in and take the disclosure, because a published imbalance is one you can write a contract clause against. IAB Tech Lab wrote OpenRTB, AdCOM, OpenDirect and GPP, and both stacks stand on those. Neither fact shows up in a schema diff, and both matter more to a five-year bet than any operation count.
What each stack costs you every month
AdCP will cost a person’s attention every month, permanently. It cut five patch releases in the first eleven days of August, 3.1.9 on the 3rd through 3.1.13 on the 11th, then 3.1.14 and a 3.0.23 for the maintained line on the 15th: seven releases in fifteen days. It also dates its removals in advance, publishing deprecation notices at least six months before anything is removed and never removing a feature inside a major version. Two are dated now: format_ids deprecated in 3.2 and removed in 4.0, package bid_price deprecated in 3.2 in favour of bidding. It leaves its mistakes visible, with 3.1.3 marked “Withdrawn. Do not use.” and the reason attached in the tree. I would take that trade every time, and I would put the owner’s name on it before the first integration ships.
AdCP is stale about itself too. docs/reference/versions.mdx names 3.1.12 as current stable while dist/schemas/ in the same checkout carries 3.1.13, and the AAMP comparison table in docs/faq.mdx still calls AdCP “3.0 GA (released April 2026)”. Both projects drift from their own code in their own prose. The difference is that one of them publishes an oracle you can fetch and diff the prose against.
The press release version number is worth pinning down, because the hub is where a buyer would look for one. The hub’s stated job is to reference stable releases for ecosystem clarity; it has zero tags and zero releases, its last commit is dated 16 April 2026, three and a half months before the AAMP 2.3 announcement, and its README omits the wire contract that both reference agents pin in their pyproject.toml.
The right-hand column below came from the GitHub releases API on 16 August 2026. The 30 July column is a reading taken that day, and it is the one claim on this page you cannot re-run, because no public archive holds those release pages.
| Repository | Tag on 2026-07-30 | Tag on 2026-08-16 | Listed in hub README |
|---|---|---|---|
AAMP (hub) | none | none | is the hub |
iab-agentic-primitives | v0.5.0, tag only, no release | v0.5.1, published 2026-08-10 | no |
seller-agent | v2.3.3, published 2026-07-29 | v2.4.1, published 2026-08-05 | yes |
buyer-agent | v2.3.0, published 2026-07-22 | v2.4.1, published 2026-08-10 | yes |
agentic-rtb-framework | v1.0, published 2026-07-20 | v1.0 | yes |
agentic-direct | none | none | yes |
agentic-audiences | none | none | yes |
registry-agent-example | none | none | yes |
The closest things to 2.3 are the buyer agent’s v2.3.0, already out for eight days when the announcement landed, and the seller agent’s v2.3.3. Both are one team’s application tag and both are gone, superseded by three independent releases inside twelve days with no number covering any two of them. ARTF, the one row that has not moved, has the same trouble at single-artifact scale: a lightweight tag over a commit dated 14 July, a release published 20 July, and a specification document inside reading “Released November 12, 2025”. The per-repository breakdown has the rest.
What is running in public
Neither corpus carries an adoption figure, and none of the published volume measures deployed traffic. What is measurable from outside is thin and real: of the 23 agents in AdCP’s public registry on 12 August, 13 completed an anonymous MCP handshake and three sales agents returned a product catalogue to a caller with no credentials (the full sweep).
Three sales agents handing a product catalogue to an unauthenticated caller is a security finding as much as an adoption one. Early deployments are running open, which is itself an argument for moving now, while the norms about who gets to see a rate card are still being set.
AAMP has tooling in the field and no transaction anyone has published. Kochava took its StationOne AI Workspace out of closed beta on 24 March 2026 built on IAB Tech Lab’s AAMP Buyer Agent SDK, and the announcement describes no media bought through it. Every named agentic buy that has run in public so far ran on AdCP or on raw MCP, none of it is large, and that ledger is a floor rather than a census (the deployment ledger).
What would change this analysis
The two conditions in the opening reverse the call for one buy: a counterparty serving only an agent card, or work that has to happen at serve time. The list below is what would move AAMP off watch-item status for everybody, and each item is a file or a tag rather than an announcement.
iab-agentic-primitivestags at 1.0 or above, with the OpenAPIinfo.versionmoved to match. That moves AAMP from implementations-with-an-emerging-contract to contract-with-implementations, and it is the trigger to watch.- A first tag on the hub. The umbrella carries no tags at all, which is what the whole pinning argument above rests on.
- A non-empty
agentic-audiences/specs/v1.0/schema/agent_interface.schema.json, the join between AAMP’s data plane and everything else. seller-agent’sAAMPRegistryClientdefaulting to a real registry client instead of the stub, which registry-mediated discovery needs before a buyer can rely on it.- An IAB Tech Lab repository referencing AdCP. Only this direction is still open: AdCP names AAMP already, in the
docs/faq.mdxline quoted above and the comparison table beside it. Across the eight IAB Tech Lab repositories at the commits cited here, read on 16 August 2026, the stringadcpappears in zero files. The firstadcpstring in an IAB Tech Lab repository would be the first sign that anyone intends the two to interoperate.
If you would rather not watch them yourself, that is the work I sell.