If you’re building the buy side — a DSP, planning tool, agentic client, or any application that calls AdCP agents to plan, buy, and report — start here. Caller-side L0–L3 is weeks of handler glue, not the 3–4 person-month build the agent side requires. The full-stack SDK in your language carries L0–L3; you write the calling logic, response handling, and whatever your application does with the data.Documentation Index
Fetch the complete documentation index at: https://agenticadvertisingorg-changeset-release-main.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Spec-level reference vs build-shaped guide. This page walks you through the build. The wire-level invariants — every rule that applies to every mutating call — live at Calling an AdCP agent. Read it once before going to production; refer back whenever you’re debugging a wire-shape error.
Install the SDK
The same SDKs that ship server primitives also ship the calling client. Install one and you have both.- JavaScript/TypeScript
- Python
- Go
ADCPMultiAgentClient instead — same call surface, indexed by agent id.Authenticate
Most agents require credentials before they’ll respond to anything beyondget_adcp_capabilities. The SDK accepts auth at construction:
- Bearer / API key
- Signed requests (RFC 9421)
AUTH_REQUIRED, the credentials aren’t reaching the agent — check the constructor option, not the request payload. See the L1 security implementation profile for the full credential model.
First call: discover the agent
Before calling tools by hand, ask the agent what it supports.get_adcp_capabilities returns the agent’s protocol coverage, AdCP version range, and feature flags. Use it to gate calls — if media_buy isn’t in supported_protocols, don’t call create_media_buy against this agent. See the get_adcp_capabilities reference for the full response shape.
For the rest of the discovery chain (agent card, tools/list, get_schema), see the Discovery chain section of Calling an agent.
Make a call
Typed methods on the client correspond to AdCP tools. The SDK validates your request against the bundled schemas before sending and parses the response into a typed value.- Generate a fresh
idempotency_keyper logical operation. Same key on retry → server replays the same response. Fresh key after a failure creates duplicate buys. See the Idempotency rules. accountis a discriminatedoneOf. Pick one variant ({account_id}fromsync_accounts/list_accounts, or{brand, operator}as the natural key —brand.domainis the buyer’s brand domain,operatoris the seller agent’s deployment hostname or brand.json identifier) and send only its required fields. Merging them fails both. SeeaccountisoneOf.
Handle the three response shapes
Every mutating tool returns one of three shapes. Handle them explicitly.webhookUrlTemplate and a status-change handler at construction; the SDK verifies the inbound webhook against the seller’s JWKS and fires your handler with the same result shape that synchronous responses carry — see Receive webhooks below.
If you must poll instead of using webhooks (e.g. inside a one-shot script), call tasks/get directly via the underlying transport. The Async responses section of Calling an agent has the wire contract.
Recover from errors
When you seeadcp_error in a response, read issues[] and act based on recovery:
issues[] is the actionable part: each entry has a JSON Pointer (pointer), an Ajv keyword (required, oneOf, enum, etc.), and — for oneOf failures — a variants[] array listing each variant’s required fields. See the Error recovery section for the full envelope and recovery semantics.
Receive webhooks
For async tasks, you can either poll or register a webhook. The webhook delivers the sameresult payload as a tasks/get with include_result: true. The SDK ships an RFC 9421 webhook verifier (createWebhookVerifier from @adcp/sdk/signing/server) that resolves keys via the seller’s brand.json, enforces the replay window, and surfaces structured errors for the webhook error taxonomy.
If you wire the multi-agent client with a webhookUrlTemplate and status-change handlers (per the @adcp/sdk README), incoming webhooks are verified and dispatched into your handlers automatically — your HTTP route is one line that hands the request to the client.
For the wire-level requirements your endpoint MUST satisfy regardless of how it’s wired (covered components, content-digest enforcement, dedup discipline), see L3 — Webhooks.
Ingest reporting
Reporting is read-only and follows the same call/response shape as everything else. Pull delivery for the buys you own and iterate on a windowed cadence:delivery object.
What you didn’t have to write
Caller-side L0–L3 is weeks of handler glue because the SDK already shipped:- L0 — typed request builders, response parsers, schema validation against the bundled schemas.
- L1 — outbound RFC 9421 signing (per-call), inbound webhook verification, key rotation.
- L2 — agent registry lookup, agent-card publication, credential composition.
- L3 — async-task polling, webhook receiver, idempotency-key generation helpers, error-recovery classification.
What’s next
- Calling an agent — the canonical wire-contract reference. Read once before going to production.
- Schemas — schema bundle, type generation, version pinning.
- Webhooks — push notifications, signing, retry, reliability patterns.
- Error handling — error categories, codes, recovery classification.
- Validate your agent — storyboards also exist for caller-side wire conformance; run them once your calls are working.