# AdBuyMCP > Public documentation for advertising planning, buying and measurement through an API, MCP and dashboard. > Buying channels: search, social, ctv, audio, tv, cinema, dooh. Documentation does not grant execution authority or establish live supplier acceptance. ## Start here - [Documentation](https://app.adbuymcp.com/docs): Product scope, workflow and current implementation limits. - [Agent readiness assessment](https://app.adbuymcp.com/docs/raw/agent-readiness): A source-based assessment against the SaaStr API Report Card rubric, with explicit implementation gaps. - [Run a sandbox campaign](https://app.adbuymcp.com/docs/raw/quickstart): Start locally, inspect the contracts and exercise a complete campaign without supplier credentials or real spend. - [Authentication and permissions](https://app.adbuymcp.com/docs/raw/authentication): Understand tenant identity, product scope and the human approval boundary before connecting an agent. - [Campaigns and approvals](https://app.adbuymcp.com/docs/raw/campaigns): Follow the state changes from audience brief to reconciled delivery, with explicit boundaries around spending. - [Money and charges](https://app.adbuymcp.com/docs/raw/pricing): Separate media commitments, platform fees, creative production and studies before requesting approval. - [Errors, retries and rate limits](https://app.adbuymcp.com/docs/raw/errors): Recover from errors without duplicating orders, losing an approval or guessing a financial outcome. - [Supply and evidence](https://app.adbuymcp.com/docs/raw/capabilities): Evaluate supported media and distinguish an implemented client from a verified commercial buying route. - [Choose the product](https://app.adbuymcp.com/docs/raw/products): One platform with explicit buying boundaries for AdBuyMCP, DOOHMCP and CTVMCP. ## Contracts - [REST API reference](https://app.adbuymcp.com/docs/api): Every documented operation on this product. - [OpenAPI JSON](https://app.adbuymcp.com/openapi.json): Generated request contracts; response schema limitations are explicit. - [MCP reference](https://app.adbuymcp.com/docs/mcp): Tool descriptions, inputs, outputs and execution mappings. - [MCP contracts JSON](https://app.adbuymcp.com/docs/mcp/adbuymcp.json): Exact registered tool schemas for this product. - [Full guide text](https://app.adbuymcp.com/llms-full.txt): All narrative guides in Markdown. ## Execution boundaries Hosted MCP requires configured tenant-bound OAuth. Consequential actions require exact human approvals. Media and asset charges are separate. Never infer a supplier outcome or released funds from a timeout. No outbound campaign webhooks or application progress subscriptions are currently available; read status endpoints. --- # Agent readiness assessment — AdBuyMCP A source-based assessment against the SaaStr API Report Card rubric, with explicit implementation gaps. ## Estimated score, not an official grade Reviewed 6 September 2026. SaaStr evaluates documentation and known behavior across six equally weighted categories. This is our source-based estimate; SaaStr has not graded this product, and these scores do not establish its position in their rankings. Before this documentation pass: 63/100 (B−). With the generated OpenAPI reference, public research guides and reproducible MCP examples verified and published: an estimated 68/100 (B). Public deployment and indexing still need to be verified. - [SaaStr API Report Card and methodology](https://saastr.ai/apireport) ## Assessment by category | SaaStr category | Before | After publication | Evidence and limits | | --- | --- | --- | --- | | API Design | 7/10 | 8/10 | Versioned REST, strict request contracts and generated OpenAPI. Some success payloads remain explicitly unmodeled. | | Events & Streaming | 2/10 | 2/10 | No outbound campaign webhooks or business event stream. Inbound Stripe webhooks and MCP response framing do not provide those capabilities. | | Auth & Security | 8/10 | 8/10 | Tenant, user, client, product/channel and exact action authority. No general per-operation OAuth read/write scopes. | | Rate Limits | 7/10 | 7/10 | REST limit/reset/remaining and retry headers. Process-local quotas; MCP tool results do not propagate downstream rate metadata. | | SDKs & Docs | 6/10 | 8/10 | Public HTML/Markdown, OpenAPI, exact MCP contracts and executable examples. No maintained language-specific REST SDK collection. | | Agent Readiness | 8/10 | 8/10 | Discoverable tools, structured errors, exact approvals and durable consequential retries. Idempotency is operation-specific. | ## What a higher score requires - Outbound signed webhooks with delivery records, retries, replay and subscription controls for campaign, booking, asset and reconciliation changes. - A resumable business event stream with tenant and scope checks; protocol-level response streaming alone is insufficient. - Finer read/write scopes in the hosted issuer and API authorization model, applied consistently to every affected operation. - A broader documented idempotency contract, coordinated quotas and actionable rate metadata through MCP. - Verified hosted onboarding and controlled supplier campaigns, followed by an independent documentation and behavior review. --- # Run a sandbox campaign — AdBuyMCP Start locally, inspect the contracts and exercise a complete campaign without supplier credentials or real spend. ## Start the isolated demo The repository runs without AI, payment or supplier credentials. Its deterministic sandbox is a way to evaluate the buying workflow; simulated delivery does not establish supplier access or audience availability. Use the repository demo script so the dashboard is built for the API port it will call. The default demo serves the API on port 4737 and the dashboard on port 3737. Use a separate terminal for MCP. ~~~bash pnpm install ./scripts/demo.sh # Separate terminal, from the repository root: CHORUS_API_URL=http://localhost:4737 pnpm --filter @adp/mcp start:http ~~~ ## Inspect before acting Read platform identity and the public tool contracts first. These requests neither create a campaign nor reserve funds. API paths include /api/v1; the MCP server is a separate process. ~~~bash curl --fail http://localhost:4737/api/v1/meta curl --fail http://localhost:4737/api/v1/openapi.json curl --fail http://localhost:4200/capabilities ~~~ ## Create a persona through the API Local AUTH_MODE=disabled uses the seeded development advertiser. Public deployments require an authenticated tenant identity; never expose development authentication on a public host. The extracted persona keeps unrepresented constraints visible. Preserve the returned persona ID and inspect its compiled targeting before planning. ~~~bash curl --fail-with-body http://localhost:4737/api/v1/personas/extract \ -H 'Content-Type: application/json' \ -d '{"nlBrief":"UK adults interested in hiking in Manchester"}' ~~~ ## Try the MCP SDK draft example This executable example connects over stdio to the actual MCP server and local API, checks that suppliers are sandbox-only, and creates a persona and draft plan. It does not approve, fund or launch a campaign. ~~~bash CHORUS_API_URL=http://localhost:4737 pnpm --filter @adp/mcp example:sandbox adbuymcp ~~~ ## Complete the buyer journey - Create a plan with the persona, GBP budget, permitted channels and flight dates. Review modeled reach, native targeting gaps and supplier readiness. - Upload real creative bytes, or review a separate AI production quote. Select same-channel creative and check the campaign readiness response. - Review and approve the exact campaign action. MCP agents must prepare an action, obtain human approval, create the execution step and use the returned step ID and digest. - Submit the retained booking request key or stage a supported native campaign. A booking waits for a human-recorded supplier outcome; a staged native hierarchy needs separate review and resume authority. - Read delivery and measurement, request a stop, and reconcile the final outcome. A timeout or overdue booking does not prove acceptance, cancellation or released funds. ## Executable end-to-end MCP example This repository test drives the actual MCP SDK and HTTP API through all three products: persona, plan, approvals, creative upload, wallet, booking and replay, supplier confirmation, delivery, measurement and stop. It creates an isolated database and test identities, and runs only sandbox suppliers. The fixture human deliberately provides approvals; this is not a way for a production agent to grant itself authority. ~~~bash pnpm build pnpm --filter @adp/api exec vitest run src/mcp-buyer-journey.integration.test.ts --maxWorkers=2 ~~~ --- # Authentication and permissions — AdBuyMCP Understand tenant identity, product scope and the human approval boundary before connecting an agent. ## Public research, private workspaces These guides, API specifications and MCP contract files are public documentation. They contain no advertiser data and grant no buying authority. Production API calls use verified Bearer credentials bound to a user and advertiser organization. Resource ownership is checked on each request; foreign or out-of-product resource IDs return 404. ~~~bash curl --fail-with-body "$ADBUY_API_URL/api/v1/auth/context" \ -H "Authorization: Bearer $ADBUY_API_TOKEN" ~~~ ## REST API credentials There is no self-service API key or long-lived personal access token. Sign in through the normal account flow. A direct REST integration uses the access_token from its authenticated Supabase human session; the API verifies the exact API audience and derives workspace identity from trusted claims. The project publishable key configures a Supabase client; it does not authenticate a customer request. Never send a Supabase secret, service-role key, Stripe key or MCP OAuth token as an API credential. Keep session and refresh credentials private; do not copy them into chat, URLs or source control. With an already signed-in Supabase client, verify access using the read-only auth/context endpoint before creating anything. The SDK manages session refresh; retrieve the current access token for each request rather than keeping a pasted token. A 401 means sign-in must be renewed or the token has the wrong audience. ~~~javascript // supabase is your integration’s already authenticated Supabase client. const { data: { session }, error } = await supabase.auth.getSession(); if (error || !session) throw new Error("Sign in to continue."); const response = await fetch(`${ADBUY_API_URL}/api/v1/auth/context`, { headers: { Authorization: `Bearer ${session.access_token}` }, }); if (!response.ok) throw new Error("Check your sign-in and API audience."); const context = await response.json(); ~~~ ## Connect a hosted MCP client - Obtain the deployment's exact HTTPS /mcp resource URL. Do not infer a live endpoint from a product name or a documentation example. - Use the client's remote MCP connection flow. The configured OAuth issuer supplies sign-in, workspace-bound consent and PKCE. - The MCP resource validates tenant, user, original client, product and channel scope. It exchanges the grant for a separate API credential and checks the delegated identity against /api/v1/auth/context. - Never use a shared static bearer token for a public multi-tenant service or forward a human browser session as an agent credential. - [Live connection details and client setup](/docs/mcp) ## Choose a registered assistant The AdBuyMCP Supabase deployment disables dynamic client registration. A server URL alone is insufficient: the assistant also needs its registered OAuth client identity and exact redirect URL. The connection guide reads published public client IDs; they identify the application and are not passwords or buying authority. For Claude web and Desktop, use the published Claude client ID, choose “Sign in now” and “Use your own OAuth client”, and leave the client secret blank. Team and Enterprise organization owners add the connector before members connect. Enable it in the conversation after sign-in. Claude Code needs a separate public client with its exact fixed http://localhost:PORT/callback URL. Use the command with both --client-id and --callback-port only after that pair is published. Do not reuse the Claude web or dashboard buyer client for another callback. ChatGPT and other assistants require their own registration. Give the platform operator the assistant name and exact callback URL displayed by that client. Do not supply a password or session token. Until registration and real client acceptance are complete, compatibility is not a verified connection. - [Claude custom connector setup](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp) - [Claude Code OAuth configuration](https://code.claude.com/docs/en/mcp#use-pre-configured-oauth-credentials) ## Verify and recover your connection | What you see | Next step | | --- | --- | | Connected | Ask for get_platform_info and list_personas. Platform information is public; listing your personas verifies authenticated workspace access. An empty list is valid for a new workspace. | | Dynamic registration unsupported | Select the pre-registered OAuth client settings. If no client ID is published for this assistant, request registration from the platform operator. | | Redirect URI mismatch | Check the exact registered callback, including hostname, path and port. For Claude Code, use the published fixed callback port. Do not broaden the redirect allowlist. | | 401 or sign-in required | Reconnect through the assistant’s OAuth sign-in. A human API token and an MCP OAuth token have different audiences and cannot be substituted. | | Wrong workspace or missing approval | Review the signed-in account and workspace consent. Approve the exact requested action in the workspace; reconnecting cannot grant human approval authority. | | Connection interrupted | Retry a read after reconnecting. Check the current state of a submitted campaign or booking before resubmitting a mutation. | ## What permissions mean | Boundary | Behavior | | --- | --- | | Tenant | Every private resource belongs to the authenticated advertiser. | | Product and channels | DOOHMCP permits DOOH; CTVMCP permits CTV. Signed entitlements can narrow the deployment further. | | Human permissions | Approving authority and reconciling uncertain outcomes require the specific human permission listed on the endpoint. | | Agent mandate | Allowed actions and budget bound what an agent may propose and execute. A mandate does not replace an exact approval. | | Execution binding | Consequential MCP mutations carry the approved execution step and action digest, bound to the actual request. | ## Current limits Authorization combines signed claims, resource ownership, product/channel restrictions and action approvals. The public MCP OAuth resource scope is not a separate read/write scope for every individual tool. A published OAuth registration establishes client configuration. Successful sign-in, consent, refresh and authenticated tool calls in that actual assistant still require separate acceptance; a public tool list does not prove them. --- # Campaigns and approvals — AdBuyMCP Follow the state changes from audience brief to reconciled delivery, with explicit boundaries around spending. ## Plan A persona preserves requested demographics, interests, intent, geography and exclusions. Each channel compilation shows represented and unsupported constraints, modeled catalogue evidence and the need for provider validation. A plan combines channel budgets, flight and forecast assumptions. Money in the REST API uses integer minor units. MCP convenience fields named budgetPounds or amountPounds are converted by deterministic code; the tool contract records that mapping. Unknown geographic population stays unknown. A reach upper bound is not a verified audience size, and a contextual proxy is not proof of audience membership. ## Approve an exact action Prepare the intended action and retain its returned snapshot and digest. Request a human review of the exact creative, targeting, budget, flight and effect. A permitted human resolves the request. The agent reads the approval, advances the run and creates its execution step. It then calls the requested operation with both execution headers. The MCP tool fields map to these headers automatically. ~~~http x-chorus-agent-step-id: x-chorus-agent-action-digest: ~~~ ## Book or stage | Path | Meaning | | --- | --- | | Managed booking | A retained order and media commitment enter a 12-hour supplier confirmation window. A human records the actual supplier outcome. | | Native staging | Supported native clients create spend-disabled provider objects and retain exact account, configuration and creative references. | | Creative review | Approval applies to the exact asset bytes, copy and destination. Changed content invalidates that evidence. | | Resume | A separate approved operation validates the retained provider hierarchy before enabling spend. | ## Measure and close Delivery, response, causal lift and brand-lift evidence are distinct outputs. Modeled reach remains labeled, and underpowered lift studies are refused. A successful pause does not immediately release money. Reports must reconcile through the stopping boundary; controlled native buys also require matching provider-spend evidence. Never-enabled staged campaigns have a human-attested zero-delivery cancellation path. Ambiguous provider outcomes enter reconciliation and are never automatically treated as failed. --- # Money and charges — AdBuyMCP Separate media commitments, platform fees, creative production and studies before requesting approval. ## Media platform fees Read the current billing summary and readiness response before committing a campaign. The platform reserves the required media and fee commitment; a reservation is not evidence that a supplier delivered. The current public prepaid buying flow accepts GBP. A supplier client supporting USD does not create a currency conversion or USD wallet. | Tier | Platform charge | | --- | --- | | Standard | 10% of media spend. | | Scale | 5% of media spend plus £749 per month when trailing 30-day spend exceeds £25,000. | ## Creative production is separate AI asset production is a separate wallet charge, quoted before submission. The current pricing endpoint is GET /api/v1/assets/pricing; it supplies prices, model licensing positions and provider terms. The configured default targets an 80% gross margin, with a 50p minimum charge. Actual prices derive from the configured provider cost and margin; an old example is not a current quote. A confirmed provider failure refunds the asset charge. An uncertain or delayed outcome stays held for reconciliation, rather than being assumed to have failed. ## Studies and shared wallets Purchased measurement studies have their own approved quote and separate charge lifecycle. They are not included in the media fee or an asset production price. AdBuyMCP, DOOHMCP and CTVMCP share the advertiser wallet. Specialist summaries identify that shared balance while scoping campaign spend to their permitted channels. --- # Errors, retries and rate limits — AdBuyMCP Recover from errors without duplicating orders, losing an approval or guessing a financial outcome. ## Read structured errors REST errors use an error envelope containing a stable code, a human-readable message and optional details. MCP tool failures set isError and return structured error information. Validation can reject unknown fields. Do not assume an API silently honored an unsupported request parameter. ~~~json { "error": { "code": "VALIDATION_ERROR", "message": "request failed validation", "details": [] } } ~~~ ## Retry by operation | Situation | Recovery | | --- | --- | | Transient read failure | Retry with bounded backoff and honor applicable Retry-After metadata. | | 429 rate limit | Wait for the indicated reset or Retry-After value; do not immediately loop. | | Mutation with an idempotency key | Retain the original key and exact request. A changed payload is not the same operation. | | Mutation without a documented retry contract | Read current resource state before deciding what to do. Generic POST retries are not guaranteed safe. | | Approval or revision conflict | Reload the current state and prepare a new review when the approved bytes changed. | | Ambiguous provider write | Stop automatic execution and request human reconciliation. Elapsed time does not determine the outcome. | ## REST rate-limit visibility The default API limits are 300 requests per minute per IP, 30 per minute on LLM-backed routes and 3,000 per minute for GET pixel and vanity-link tracking. The POST tracking endpoint uses the global limit. Deployment configuration can change these values; read response headers as the current authority. Responses expose x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-reset. Exhausted windows also expose retry-after. These controls are local to an API process; deployment-wide quotas require an appropriately coordinated store or edge policy. Browser clients can only read cross-origin headers exposed by CORS. The MCP REST client currently does not forward these downstream headers into tool results; do not assume a tool response contains the full HTTP rate-limit contract. ## MCP transport limits The MCP boundary limits request size, read deadlines, authentication deadlines and concurrent requests. The default maximum body is 32 MiB, allowing a 20 MiB decoded creative upload. Concurrency saturation returns HTTP 503 with Retry-After: 1. That is separate from a REST 429. Streamable HTTP response framing does not provide a campaign event subscription. --- # Supply and evidence — AdBuyMCP Evaluate supported media and distinguish an implemented client from a verified commercial buying route. ## Seven buyer-facing channels | Channel | Buying model | | --- | --- | | Paid search | Native search campaigns and reviewed keyword/negative targeting. | | Paid social | Native social campaigns with supplier-specific targeting and creative requirements. | | Connected TV | CTV video via eligible native suppliers or managed inventory. | | Podcast and audio | Audio assets, contextual/native targeting and managed publisher placements. | | Addressable TV | Household-oriented broadcaster and booking workflows; separate from CTV. | | Cinema | Venue and catchment planning with managed booking and clearance. | | DOOH | Screen, venue and place-based planning with supplier-specific inventory and booking. | ## Read operation-level evidence The repository has 26 connectors, including buying, data and measurement integrations. That number is not a count of live-certified buying suppliers. Read list_connections and the supplier dossier for the authenticated account. Capabilities are operation-specific: a working inventory read does not establish creative acceptance, activation, reporting or stop support. Native API suppliers and managed bookings follow different workflows. A supplier confirmation window is not an instant programmatic purchase. ## Known execution limits - Live supplier seats and controlled campaign acceptance remain required. No offline fixture is evidence that the account can buy media. - StackAdapt terminal budget/flight states do not reveal an independent configured spend switch; those states retain final reconciliation holds pending a verified contract. - Hivestack needs verifiable gross-cost readback and exact report columns/currency before automatic enable and settlement. - Amazon DSP write operations without a verified current contract remain disabled; its reporting contract is experimental. - Vibe supports US inventory and whole-USD budgets. The public prepaid platform is GBP-only, so that client cannot yet be funded through the buying flow. - Some providers remain explicit stubs or human booking workflows. Availability also depends on the advertiser account, geography and exact operation. ## Niche targeting is a request, not a promise The compiler preserves audience intent and labels unsupported constraints. Modeled catalogue matches are proposals, not verified provider segment IDs or audience counts. Native targeting must preserve the approved geography and constraints. Unsupported exclusions, unresolved semantics or mismatched countries fail rather than silently widening the audience. --- # Choose the product — AdBuyMCP One platform with explicit buying boundaries for AdBuyMCP, DOOHMCP and CTVMCP. ## Product boundaries | Product | Permitted buying channels | Deployment target | | --- | --- | --- | | AdBuyMCP | Search, social, CTV, audio, addressable TV, cinema and DOOH. | Parent production hostname must be configured. | | DOOHMCP | DOOH only. | doohmcp.com is the intended specialist domain. | | CTVMCP | CTV only. Addressable TV is a separate channel. | ctvmcp.com is the intended specialist domain. | ## Separate connections, shared organization Each hosted product has its own MCP resource URL and matching API deployment. Signed tokens bind the product and permitted channels; a request parameter cannot select a broader product. The API and MCP both enforce scope. A mixed-media campaign belongs on AdBuyMCP. Specialist requests cannot use a persisted ID to operate on excluded sibling channels. All products use the advertiser organization and shared wallet. Documentation downloads describe a product; downloading another product's schema does not grant its permissions. ## Verify the service before connecting A configured domain or example URL is not proof that a service is deployed. Check the published platform metadata, OAuth discovery and exact product contracts, then complete a real authenticated acceptance flow. These documentation pages remain readable without a workspace session. Campaign data and execution remain authenticated.