AdBuyMCP · 105 tools

MCP tool reference

These contracts are generated from the registered MCP tool definitions. They describe the deployment's maximum scope; the tools available to an authenticated client can be narrower.

Download the MCP contracts →

Connect and inspect

Configured MCP resource
https://app.adbuymcp.com/mcp

Hosted access uses tenant-bound OAuth and exact human approval for consequential actions. Modern and tested legacy MCP clients are supported. Streamable HTTP framing does not provide campaign event subscriptions.

Connect an AI assistant to AdBuyMCP

Plan, prepare creative, request placements and follow delivery from an MCP-compatible assistant. Your workspace and channel permissions apply throughout.

MCP
REST APIhttps://app.adbuymcp.com/api/v1API and MCP documentation →

Loading connection details…

JSON Schema describes structural validation. Runtime channel fit, ownership, canonical file bytes, per-kind duration, readiness, authority, and revision checks still apply. Output schemas are MCP envelopes unless they define nested fields; they are not a complete REST response model.

list_brand_lift_studiesGET /api/v1/campaigns/{campaignId}/brand-lift-studies

Read a bounded page of campaign-owned study metadata. Supplier outcomes and financial settlement are separate.

get_brand_lift_studyGET /api/v1/brand-lift-studies/{studyId}

Read tenant-owned study metadata or aggregate survey statistics. Sandbox evidence is modeled; provider sample sufficiency is not independently assessed power. Expired results are withheld.

get_brand_lift_resultsGET /api/v1/brand-lift-studies/{studyId}/results

Read tenant-owned study metadata or aggregate survey statistics. Sandbox evidence is modeled; provider sample sufficiency is not independently assessed power. Expired results are withheld.

get_brand_lift_study_catalogsGET /api/v1/campaigns/{campaignId}/brand-lift-study-catalogs

Read supplier-reported or deterministic sandbox industries, country languages and explicitly scoped standard question templates. Select both catalog IDs to read templates. Catalog availability is not a quote, purchase approval or credentialed acceptance.

create_brand_lift_studyPOST /api/v1/campaigns/{campaignId}/brand-lift-studies

Create a local study brief from exact catalog template selections. Human supplier quote and purchase approval are separate steps.

update_brand_lift_studyPATCH /api/v1/brand-lift-studies/{studyId}

Update an editable local brief at the reviewed revision. Existing human approvals cannot authorize a changed specification.

request_brand_lift_quotePOST /api/v1/brand-lift-studies/{studyId}/quote-request

Record a local task for a human to obtain and record the supplier quote. This does not establish a price or buy a study.

request_brand_lift_cancellationPOST /api/v1/brand-lift-studies/{studyId}/cancellation-request

Record a human supplier cancellation task. This does not confirm cancellation or release funds.

preview_brand_lift_studyPOST /api/v1/brand-lift-studies/{studyId}/preview

Read current supplier catalog templates and record a bounded question preview and request digest. The provider-native draft remains private. Requires study.preview authority.

refresh_brand_lift_resultsPOST /api/v1/brand-lift-studies/{studyId}/results/refresh

Read the known launched provider study under reviewed authority and retain aggregate survey results. A parked read requires a human operator; retryParked must be false.

create_brand_lift_draftPOST /api/v1/brand-lift-studies/{studyId}/draft

Execute the exact unused human draft approval for the already-funded study. Declare the full GBP cap under study-commitment in agent approval; incremental reservation is zero. An uncertain supplier write requires human reconciliation.

launch_brand_lift_studyPOST /api/v1/brand-lift-studies/{studyId}/launch

Execute the exact unused human launch approval, current tracking evidence and approved provider definition. Agent approval must disclose the full already-funded GBP cap. An uncertain launch requires human reconciliation.

get_buyer_contextGET /api/v1/buyer/context

Start or resume one of four buying workflows. Reads scoped resource evidence, missing inputs, human handoffs and exact canonical next-tool arguments. Does not launch, spend, generate assets or approve actions.

list_buyer_sessionsGET /api/v1/buyer/sessions

Read compact summaries of persisted buyer sessions belonging to this authenticated agent client, tenant and product scope. Use get_buyer_session to recover a selected conversation.

get_buyer_sessionGET /api/v1/buyer/sessions/{sessionId}

Read one agent-owned buyer conversation, its references, messages and current revision. A conversation is not commercial authority; existing Operator approvals still govern consequential actions.

list_creativesGET /api/v1/creatives

Read the advertiser’s creatives, optionally for a campaign, so creative direction can reuse current work and inspect its channel and precheck evidence.

adapt_creativePOST /api/v1/creatives/{creativeId}/adapt

Generate a new channel-specific creative and copy precheck from an existing concept, preserving the source. Does not render paid assets, submit to a supplier or launch media. Review the result and use separately governed tools for those actions.

get_platform_infoGET /api/v1/meta

Read the trusted API product profile, supported channels and configured MCP connection metadata. A configured public URL is connection information, not proof of live supplier acceptance or production readiness. Use the advertised capabilitiesUrl for complete product tool contracts; do not invent a hosted endpoint when it is absent.

list_agent_actionsGET /api/v1/agent/actions

List every consequential MCP action AdBuyMCP can execute, with its stable action name, REST route, exact parameter contract and budget policy. Read this before requesting an external-action approval. New mutation routes fail closed until they appear in this registry.

prepare_agent_actionPOST /api/v1/agent/actions/prepare

Canonicalize one registered consequential action before requesting approval. Pass REST-level parameters from list_agent_actions and explicit integer-minor-unit authority. The API returns the exact privacy-safe action object plus its SHA-256 digest. Use that action unchanged with request_agent_approval, then as the execute-step input. Credentials and large outcome batches are represented by fingerprints rather than copied into the durable approval journal. This tool has no side effect.

create_agent_missionPOST /api/v1/agent/missions

Create a durable mission with explicit objectives, success criteria and an initial authority mandate. Observe/recommend mandates cannot carry money authority. An execute mandate requires an explicit action allowlist, integer-minor-unit budget ceiling and currency. This stores authority only: it does not start a run, call a provider or spend money. Show an execute mandate to the user and obtain explicit approval before creating it.

list_agent_missionsGET /api/v1/agent/missions

List tenant-scoped durable agent missions newest first, including objectives, mandate versions and counts of runs, approvals, exceptions, decisions and evidence. Use this to find an existing mission before creating another one.

get_agent_missionGET /api/v1/agent/missions/{missionId}

Read one tenant-scoped mission with its ordered objectives, mandate history, active run id and control-record counts. This is the authoritative mission state; it is not evidence that any campaign or provider action has occurred.

start_agent_runPOST /api/v1/agent/missions/{missionId}/runs

Start the single active run allowed for a mission, bound immutably to one active mandate version. Omit mandateId to bind the newest active mandate. The run begins in observe phase. Starting it does not execute tools, contact providers or grant authority beyond the bound mandate.

list_agent_runsGET /api/v1/agent/missions/{missionId}/runs

List tenant-scoped runs for one mission newest first, including their bound mandate and durable control-record counts. Filter by state when looking for work waiting on approval or blocked by an exception.

get_agent_runGET /api/v1/agent/runs/{runId}

Read a run with its mission, bound mandate, ordered steps, approvals, exceptions, decisions and evidence. detailLimit applies independently to each child collection and counts reveal truncation. Inspect this immediately before any state transition to avoid acting on stale phase or authority.

add_agent_stepPOST /api/v1/agent/runs/{runId}/steps

Record one pending step in the run’s current phase using optimistic expectedPhase. A non-other kind must match the phase. An EXECUTE step must carry the approved external action’s approvalId and exact actionDigest; recording it atomically consumes that approval so it cannot authorize a second action. CRITICAL: this tool only records the step and consumes authority. It does not call an AdBuyMCP execution tool or any provider. Call the governed tool separately with its agentAuthorization; the API claims and settles the execute step from the real route receipt.

complete_agent_stepPOST /api/v1/agent/steps/{stepId}/complete

Settle one pending non-execute step exactly once. A completed step may carry structured output; a failed step must carry an error and blocks the run. Execute steps reject this endpoint: they are atomically claimed and settled only by the governed AdBuyMCP route that performs the approved action.

request_agent_approvalPOST /api/v1/agent/runs/{runId}/approvals

Create a pending approval and move an unblocked run to waiting_approval. An external_action can only be requested in approve phase and must fit the run’s active execute mandate, including its allowlisted action name and explicit budgetMinor/currency (use zero for non-spend actions). The response returns the canonical actionDigest. This requests authority; it does not grant or execute it. An MCP identity cannot approve its own request: direct the user to the Operator approval queue, then poll get_agent_run until the approval is approved or rejected.

advance_agent_runPOST /api/v1/agent/runs/{runId}/advance

Advance exactly one phase along observe → plan → approve → execute → verify after all pending steps are settled. Entering execute requires a matching approved external-action approvalId and actionDigest from get_agent_run after a permitted human resolved the request in Operator, a current execute mandate, and no pending approvals or open exceptions. This changes control state only; it does not execute the approved action or contact a provider.

raise_agent_exceptionPOST /api/v1/agent/runs/{runId}/exceptions

Record a structured operational, policy or evidence exception on an active run and block the run. Use a stable machine category plus a human-readable message and detail. Raising an exception does not roll back or infer the outcome of any provider action. Ambiguous provider side effects require a permitted human to reconcile them in Operator; poll the relevant read tool for the resulting state.

list_agent_exceptionsGET /api/v1/agent/exceptions

List tenant-scoped agent exceptions newest first, optionally filtered by mission, run, status and severity. Use this before attempting resume: every open exception and pending approval must be resolved independently.

resolve_agent_exceptionPOST /api/v1/agent/exceptions/{exceptionId}/resolve

Record the human or operational resolution of one open exception exactly once. This does not resume the run automatically and does not assert any provider outcome. Inspect all remaining exceptions and approvals, then call resume_agent_run separately when the run is genuinely clear.

resume_agent_runPOST /api/v1/agent/runs/{runId}/resume

Move a blocked run back to running only after every exception is resolved and every approval is resolved. This is a control-state transition in the current phase; it does not retry, repeat or assume the outcome of any external action.

record_agent_decisionPOST /api/v1/agent/runs/{runId}/decisions

Append a structured decision, rationale and up to 20 inline evidence records to a non-terminal run. Evidence content is SHA-256 digested by the API. This is an audit/explanation record only: a decision does not grant approval, change a mandate or prove a provider action occurred.

record_agent_evidencePOST /api/v1/agent/runs/{runId}/evidence

Append one observed evidence object to a non-terminal run, optionally linked to a step. The API canonicalizes and SHA-256 digests the content. State the real source and observation time; this record does not independently verify the source or replace provider reconciliation evidence.

finish_agent_runPOST /api/v1/agent/runs/{runId}/finish

Finish a non-terminal run as succeeded, failed or cancelled using optimistic expectedPhase and a durable summary. Success requires verify phase, a completed verify step with linked evidence, and no pending steps, approvals or exceptions. In verify, add_agent_step with kind verify, record_agent_evidence linked by stepId, then complete_agent_step before finishing. This terminal control record frees the mission for another run; it does not change campaigns or infer success from missing provider evidence.

get_workspace_overviewGET /api/v1/workspace/overview

Read the authenticated brand workspace across every channel and supplier: campaign states, delivery, spend, outcome summaries, freshness and modeled/observed provenance. Supplier names are drill-down dimensions; the brand remains the top-level workspace. Optionally scope the overview to one tenant-owned campaignId.

suggest_search_keywordsPOST /api/v1/workspace/keywords/suggest

Request Google Ads and/or Microsoft Advertising keyword ideas for this brand, including provider search volume, competition and bid estimates where available. Results retain their supplier and modeled/observed labels and do not change a plan. An optional page URL must use HTTPS without embedded credentials.

get_plan_search_keywordsGET /api/v1/plans/{planId}/search-keywords

Read the exact keyword and negative-keyword selection shared by every paid-search line in a draft brand plan. Returns the provider targeting preview plus the optimistic selectionVersion and buyerPreviewVersion required to apply reviewed ideas. The preview explicitly blocks live conversion bidding until an exact provider-owned goal/action is persisted and provider-verified; initial canaries are clicks-only.

set_plan_search_keywordsPATCH /api/v1/plans/{planId}/search-keywords

Apply one buyer-reviewed keyword and negative-keyword set to every Google/Microsoft search line in a draft brand plan. Requires the latest selectionVersion so a stale agent cannot overwrite a buyer’s newer selection, plus the exact buyerPreviewVersion after reviewing provider match types, networks, bidding, budgets and account revisions. This edits targeting but does not approve or launch spend, and still requires a human-approved agent action bound to the exact plan snapshot.

forecast_search_performancePOST /api/v1/planning/provider-forecast

Read Google Ads v25 keyword performance estimates for an explicit budget, flight, native geo and language references, match types and bidding strategy. This stateless planning query creates no provider campaign and enables no spend. Live calls require verified supplier authority. Google does not accept campaign negatives, network controls or a selected custom conversion goal for this endpoint; acknowledge those limitations explicitly. Clicks, conversions and cost are returned only when the provider supplies them. Missing metrics stay absent or null; this result does not claim impressions, reach, frequency or CPM. Sandbox estimates are clearly labeled modeled. The API supplies its own request clock; callers cannot override asOf.

list_identity_cohortsGET /api/v1/identity/cohorts

List tenant-owned EUID cohort metadata, consent assertions, mapping counts and retention dates. No email hashes or EUIDs are returned. New live imports have no observed provider mapping; sandbox maintenance is labeled modeled. Cohorts do not yet deliver DSP audiences. Import and erasure require a human in the Identity dashboard.

get_identity_cohortGET /api/v1/identity/cohorts/{cohortId}

Read one tenant-owned identity cohort, its current connection revision and recent provider-attempt metadata. Stored hashes, EUIDs and provider payloads are never exposed. Read this before preparing a mapping or opt-out action. Uncertain provider outcomes require a human operator to review and resolve them in the Identity dashboard; never infer a failed outcome.

map_identity_cohortPOST /api/v1/identity/cohorts/{cohortId}/map

Execute the governed data.identity.map action for an existing consented cohort. Live execution sends stored identifiers to EUID; it requires supplier privacy authority and the exact cohort and connection revisions from get_identity_cohort. Use null expectedConnectionRevision for sandbox cohorts. No identities are accepted as tool input or returned. A human must approve the exact metadata-bound action. Retain the same UUID and revision inputs after a timeout; recorded requests are never automatically reissued. If the attempt is uncertain, hand it to a human operator and poll status. Mapping maintenance does not deliver a DSP audience.

check_identity_optoutsPOST /api/v1/identity/cohorts/{cohortId}/optout

Execute the governed data.identity.optout action for an existing consented cohort. Live execution sends stored identifiers to EUID; it requires supplier privacy authority and the exact cohort and connection revisions from get_identity_cohort. Use null expectedConnectionRevision for sandbox cohorts. No identities are accepted as tool input or returned. A human must approve the exact metadata-bound action. Retain the same UUID and revision inputs after a timeout; recorded requests are never automatically reissued. If the attempt is uncertain, hand it to a human operator and poll status. Mapping maintenance does not deliver a DSP audience.

classify_postcodesPOST /api/v1/data/caci-acorn/classify

Return CACI postcode-level categories, groups and types, or explicitly modeled sandbox samples. Live lookups transfer postcodes and consume licensed supplier records, so approve the governed data.postcodes.classify action with these exact requests and connection preconditions first. Read expectedExecutionMode and expectedConfigurationRevision from list_connections; use null revision only when configured is false. Supply an opaque uid per row and a fresh UUID per batch. On an uncertain response retain the exact UUID, records and preconditions: repeating a recorded live attempt returns its metadata without submitting it again. Never automatically create a new UUID to bypass that result. Postcodes and classifications are not persisted by the API; keep raw records out of approval notes and durable agent evidence. Area classifications are not individual attributes or persona-affinity scores.

get_brand_analyticsGET /api/v1/workspace/analytics

Read advertiser-owned Plausible website traffic, an optional exact goal display-name filter and currency-preserved revenue for a date range. The Stats API proves its executed filter but does not enumerate configured goal identities, so zero is explicitly ambiguous. Prefer tenant-scoped campaignId, which resolves the campaign’s immutable analytics key; the stored destination URL is context, not a page/path filter, and raw campaign is advanced compatibility only. The response is correlated brand-site evidence, not a causal media claim.

list_personasGET /api/v1/personas

List all audience personas in AdBuyMCP (id, name, NL description, semantic core, version). Use this first to find an existing persona before extracting a new one.

extract_personaPOST /api/v1/personas/extract

Turn a natural-language audience brief (e.g. "London-based technology decision makers") into a structured AdBuyMCP persona: geo, demographics, firmographics, intent topics, interests, exclusions, with per-element confidence. Returns the created persona including its id — use that id with compile_persona and generate_plan.

compile_personaPOST /api/v1/personas/{personaId}/compile

Compile a persona into concrete targeting for all seven workbench channels (CTV, audio, TV, cinema, DOOH, paid search, and paid social). Returns per-channel targeting specs, a fidelity score/grade per channel (person → household → content → venue → geo-cohort), a lawful-basis manifest for every targeting element, warnings, and a plain-English narration of how the persona translates on each channel.

browse_inventoryGET /api/v1/inventory

Browse concrete inventory on ctv, audio, tv, cinema, dooh, search, social — with location, format, monthly audience, CPM (pence), owner, and tags. This is how you hand-pick specific placements ("the Piccadilly Lights screen", "that tech podcast") instead of letting the AI planner choose: browse here, note the item ids, then pass them to create_manual_plan as selections. Filter by city, free-text query, or a maximum CPM in pence.

generate_planPOST /api/v1/plans/generate

Generate one brand-level media plan on ctv, audio, tv, cinema, dooh, search, social for a persona: budget split with reasoning, adapter-grounded forecasts (reach/impressions/CPM), flighting, and modeled total reach/frequency. Optionally choose the exact native Search and Social buyers; each selected provider receives its own reviewable budget line. Budget is in pounds sterling. Returns the draft plan with its id and line items — review it, then approve_plan to create a campaign.

create_manual_planPOST /api/v1/plans/manual

Build a media plan from inventory items YOU picked (via browse_inventory) instead of the AI planner. Trade-off: generate_plan optimizes the budget split across channels with reasoning and forecasts; create_manual_plan gives you exact control over which billboards/shows/channels/venues run, at the cost of that optimization. Budget is split across your selections and the platform fee is disclosed per line, exactly like an AI plan. The result is a normal draft plan: approve_plan and launch_campaign work the same afterwards. Optionally attach a persona for targeting/fidelity context.

list_plansGET /api/v1/plans

List this advertiser’s media plans, newest first. Use this when the user asks for an existing draft or approved plan but has not supplied its id; then call get_plan before editing or approving it.

get_planGET /api/v1/plans/{planId}

Fetch a media plan by id: status (draft/approved), line items with budgets and forecasts, total forecast, narrative, and a staleReason if the persona changed since the plan was generated.

update_plan_allocationsPATCH /api/v1/plans/{planId}

Change one or more line budgets on a DRAFT plan and reforecast every changed line through its selected adapter. Use the allocationVersion returned by get_plan as expectedAllocationVersion; a concurrent change returns PLAN_VERSION_CONFLICT, in which case reload and ask the user to review the new state. Omitted lines keep their budgets. Amounts are pounds sterling and each line must remain above its channel/flight minimum. This changes money allocation and must be shown to the user before calling it.

approve_planPOST /api/v1/plans/{planId}/approve

Approve a draft media plan. This locks the plan and creates a campaign with one channel-campaign per plan line, all in status "pending". Returns the new campaign including its id — use launch_campaign to activate it. Fails with 409 if the plan is already approved.

get_campaign_bookingsGET /api/v1/campaigns/{campaignId}/bookings

Read the campaign’s durable supplier booking requests and current preview: exact snapshot digest, media budget, maximum commitment, currency, eligible lines, readiness and blockers. Use this before requesting buyer approval and poll it after booking. A 12-hour confirmation deadline is the supplier response window; overdue never means accepted or safely cancelled.

request_campaign_bookingPOST /api/v1/campaigns/{campaignId}/bookings

Request supplier booking for exactly the preview the buyer approved. Show the media split, maximum commitment, creative and flight before asking for approval. Use the campaign.booking.request governed action and exact execute-step authority. This records a durable booking request with a 12-hour supplier confirmation window; it does not fabricate supplier acceptance. Reuse the idempotency key after a timeout and poll get_campaign_bookings. Confirmation is a human-only Operator action, and an expired response window never authorizes automatic retry or acceptance.

list_campaign_conversion_goalsGET /api/v1/campaigns/{campaignId}/lines/{lineId}/conversion-goals

Read exact Google, Microsoft, TikTok or Meta website conversion goals for one approved campaign line. Returns provider account, complete immutable rule definitions and digests, connection revision, availability blockers and the selected binding. Event activity is separate from goal configuration. Live reads require verified supplier authority; sandbox examples are explicitly labeled. Use the returned goal reference and revision evidence in set_campaign_conversion_goal.

set_campaign_conversion_goalPATCH /api/v1/campaigns/{campaignId}/lines/{lineId}/conversion-goal

Bind one freshly read provider-owned conversion rule to a pending campaign line and its approved performance brief and destination. Requires the exact definition digest, connection revision and current binding ID from list_campaign_conversion_goals, plus governed action approval. The provider definition is reread before saving. Activated lines are immutable; stale evidence returns a conflict and must be reviewed again. TikTok and Meta require explicit click/view attribution windows and event counting; these have no defaults and become immutable after creation. This selection does not launch or enable spend.

launch_campaignPOST /api/v1/campaigns/{campaignId}/launch

Activate every pending/errored channel-campaign via its adapter (API channels go live or pending-approval; workflow channels like cinema/AdSmart start a booking workflow). Sandbox workflow lines can also resume here. Live paid-media activation stages provider objects paused; a human must record exact provider creative approval and issue fresh supplier authority before resume can enable the manifest-bound hierarchy. Before first launch, every campaign line must have at least one selected creative for the same channel with a completed, non-failing policy precheck; generate_creative with campaignId attaches new work automatically, or use set_campaign_creatives to select reusable existing work. Returns the refreshed campaign plus per-line launchErrors if any adapter failed.

pause_campaignPOST /api/v1/campaigns/{campaignId}/pause

Pause every active channel-campaign through its executing adapter. Each live provider call is durable, and AdBuyMCP keeps pausing the remaining lines if one fails. A complete pause returns the campaign in paused-pending-reconciliation. A 502 may be state-bearing: PAUSE_FAILED means confirmed-paused lines stay paused while active lines can be retried; PAUSE_RECONCILIATION_REQUIRED means an unknown vendor outcome must be inspected with list_campaign_attempts and handed to a permitted human in Operator. Poll get_campaign after that reconciliation. Unused wallet funds stay reserved until final reporting through the pause boundary reconciles.

resume_campaignPOST /api/v1/campaigns/{campaignId}/resume

After pause reporting has reconciled, resume a paused campaign without creating a duplicate external campaign. A live paid-media resume requires exact creative approvals, a persisted staged-resource manifest, and fresh human-issued supplier authority; the adapter proves the upstream hierarchy still matches before enabling it. Returns the refreshed campaign.

list_campaignsGET /api/v1/campaigns

List all campaigns with their status (including pending, live, pausing, pause-failed, paused-pending-reconciliation, paused, reconciliation-required, and error), flight dates, and per-channel status, adapter, budget, and external references. Inspect the per-channel statuses for partial pauses: pause-failed can contain both paused and still-active lines.

get_campaignGET /api/v1/campaigns/{campaignId}

Fetch one tenant-scoped campaign with its plan, selected creatives, channel-campaign lines, booking workflows and current statuses. Use this before any campaign mutation when the user has supplied a campaign id, and after launch/pause/resume to inspect partial line-level state.

get_campaign_readinessGET /api/v1/campaigns/{campaignId}/readiness

Read the exact fail-closed launch or resume checklist without reserving money, submitting creative, advancing workflows or calling a media provider. Returns readyToLaunch plus funding, measurement, creative, execution and workflow findings. ALWAYS call this immediately before asking for approval to launch; surface every blocker, action and warning rather than merely reporting the boolean. Launch repeats the checks atomically.

list_live_execution_grantsGET /api/v1/campaigns/{campaignId}/live-test-grants

Inspect the tenant-scoped, campaign-specific supplier authority records that back controlled live execution. Returns each exact adapter grant with its dossier and connection revisions, minor-unit budget cap, currency, validity window and issued, claimed or revoked state; compare the validity window with the current time to identify expiry. This is strictly read-only: grant issue and revocation are human-only in Operator, while claim is not a separate handoff — AdBuyMCP consumes the exact grant atomically inside an approved launch before provider I/O.

list_campaign_attemptsGET /api/v1/campaigns/{campaignId}/attempts

List the durable provider calls for one campaign, including operation, adapter, execution mode, status, idempotency key, vendor reference, and diagnostic detail. Use this when a campaign is reconciliation-required to identify the exact call a permitted human must verify and resolve in Operator. MCP identities can inspect and poll this state but cannot assert the outcome.

get_campaign_dead_lettersGET /api/v1/campaigns/{campaignId}/dead-letters

List delivery-report pulls for one campaign that reached the retry ceiling and are now parked, including the affected line, adapter, attempt count, last error and observation times. This is read-only: it does not requeue a report, change delivery or release held funds. Hand the exact record and corrective evidence to a permitted human in Operator, then poll this tool until the record clears and verify fresh authoritative delivery. MCP identities cannot perform the requeue.

get_deliveryGET /api/v1/campaigns/{campaignId}/delivery

Normalized delivery for a campaign: totals (impressions, spend), per-channel and per-day breakdowns, modeled deduped reach (labeled as modeled; daily reach rows are never summed), and byPlacement — the per-unit view: which individual board, show, screen or app ran, on how many days, and what it cost. byPlacement.coveragePct states what share of spend could be attributed to a named unit; the remainder is reported at line level because not every rail breaks delivery down that far, which is legitimate and NOT an unidentified board. Raw per-day×geo×placement rows are omitted for compactness — rowCount tells you how many exist; fetch the CSV export for the full ledger.

get_measurementGET /api/v1/campaigns/{campaignId}/measurement

The four-verb measurement story for a campaign: Delivered (normalized delivery + channel-native metrics side-by-side), Responded (pixel/promo tracking, outcomes, attribution), Caused (latest geo-lift result, or a pointer to prove_it), Remembered (bounded study records, mode and retained-result metadata; no pooled survey statistics). Use this to report campaign performance honestly.

get_campaign_trackingGET /api/v1/campaigns/{campaignId}/tracking

Read each campaign channel’s provisioned promo code, pixel URL/tag and vanity URL, plus whether the vanity destination has been configured. Use this before launch when responded measurement is expected. Public pixels record pageviews only; use import_outcomes for authenticated conversion/value data, and do not claim response coverage merely because identifiers exist.

set_campaign_trackingPATCH /api/v1/campaigns/{campaignId}/tracking/{channel}

Set or clear the HTTPS destination behind one campaign channel’s AdBuyMCP vanity URL. The URL must be HTTPS and contain no embedded credentials. This changes where future respondents are redirected, is audit logged, and should be previewed with the user before calling. Pass null only when the user explicitly wants to disable that channel’s vanity redirect.

import_outcomesPOST /api/v1/campaigns/{campaignId}/outcomes/import

Import up to 500 authenticated analytics, commerce, CRM or offline response events for one campaign. Each event needs an opaque source event id for deterministic deduplication. Raw identifiers are forbidden; optional household identity must already be a SHA-256 hash. A promo code is accepted only when provisioned for this campaign. Imported response remains correlational unless deterministic evidence or a powered causal test supports it.

get_outcome_healthGET /api/v1/campaigns/{campaignId}/outcomes/health

Read observed outcome recency, source volumes and field coverage for one campaign. This is a feed diagnostic, not proof that every real-world conversion was captured and not causal attribution.

get_campaign_reportGET /api/v1/campaigns/{campaignId}/report

Return the URL of a self-contained, printable campaign report — delivered spend by channel, modeled reach, responses, and the causal result (or an honest refusal where the test was not powered or had no clean control market). It is a single HTML file with no scripts and no external requests, rendered in the advertiser brand kit, meant to be opened, printed to PDF and forwarded to people who never log into AdBuyMCP. The document body is deliberately NOT inlined here: it is several kilobytes of markup that is useless to read as text. Use get_measurement instead when you need the numbers themselves. NOTE: the URL is tenant-scoped, not a public share link — under AUTH_MODE=clerk it needs the same credentials this MCP server uses, so a recipient without an account cannot open it. Download it and attach the file, or open it yourself and print to PDF.

get_auditGET /api/v1/audit

Read the append-only audit trail of tenant-visible mutations: persona create/update/delete, plan approval, campaign launch/pause/resume and creative-selection changes, optimization approvals and rejections, connection updates, creative generation/revision/submission, outcome imports, audience syncs, wallet top-ups and asset charges — each with who did it, when, and the entity it touched. This is what a finance or governance reviewer asks for first. Newest first, paged.

prove_itPOST /api/v1/campaigns/{campaignId}/prove-it

Run a matched-market geo-lift test on a campaign’s geo-tagged conversions: power analysis first (the engine REFUSES underpowered tests and says why), then diff-in-diff lift vs matched control markets. Returns status completed (with lift + confidence) or refused (with the power readout).

get_campaign_insightsGET /api/v1/campaigns/{campaignId}/insights

One call for the analysis a Head of Data would present to a client: PACING (planned vs delivered to date, and a run-rate projection to flight end), EFFICIENCY (blended and per-channel CPM/CPA plus a weekly trend), OUTCOMES, modeled REACH, the MIX MODEL verdict, INCREMENTALITY, the optimizer RECOMMENDATIONS, and — read this one — LIMITATIONS. Two things are deliberate and must be carried through to whatever you produce. The mix model usually reports status "not-ready" with the weeks it has against the weeks it needs; that refusal IS the finding, not a gap to fill with your own estimate. And `limitations` lists what this analysis cannot claim, derived from the actual data — surface it with the numbers rather than as a footnote, because every line in it is a claim someone would otherwise make by mistake. The projection is a run-rate, not a forecast model.

generate_optimizationsPOST /api/v1/campaigns/{campaignId}/optimize

Analyse the campaign plan, delivery and observed outcomes and replace its pending optimisation set with fresh explainable proposals. This creates recommendations only; it does not approve a budget reallocation or change a live provider. Previously approved or rejected decisions remain immutable. Review the returned confidence, rationale and expected impact, then ask the user before approve_optimization or reject_optimization.

list_optimizationsGET /api/v1/optimizations

List tenant-scoped optimisation proposals newest first, optionally filtered by campaign and status. Use this to reload proposal state immediately before an approval or rejection; only pending proposals can be decided.

approve_optimizationPOST /api/v1/optimizations/{optimizationId}/approve

Approve one pending optimisation proposal after showing the user its exact budget movement, confidence, expected impact and rationale. Reallocation approvals mutate the stored plan and sandbox execution budgets, with both affected sides reforecast. Live upstream budget updates fail closed as UPSTREAM_UPDATE_UNSUPPORTED. The pending-to-approved claim is atomic and audit logged.

reject_optimizationPOST /api/v1/optimizations/{optimizationId}/reject

Reject one pending optimisation proposal after the user has reviewed it. Rejection is a durable, audit-logged human decision and the same deterministic proposal will not be resurrected as pending by a later generation run.

mmm_readinessGET /api/v1/measurement/mmm/readiness

Ask BEFORE attempting an MMM. Reports weeks of usable history against what is required, which channels carry material spend, whether each channel's spend actually VARIES (a channel held at a flat budget cannot be separated from the baseline — this is the failure mode that makes naive mix models confidently wrong), collinearity between channels that move together, outcome density, and a plain-English list of what is missing with what to run instead. Returns 200 whether or not it is ready: "not yet, and here is why" is a valid answer, not an error. Most advertisers running short pilots will NOT be ready, and that is the expected result.

run_micro_mmmPOST /api/v1/measurement/mmm

Fit a weekly marketing-mix model across this advertiser's channels: geometric adstock (carryover), a diminishing-returns saturation curve, and ridge-regularised regression. Returns per-channel contribution, marginal cost per outcome, and fit quality. Every number is labeled modeled and carries caveats — render the caveats WITH the numbers, not behind a tooltip, and never present a weak fit as an allocation recommendation. When the data cannot support a model this REFUSES with 422 and the full readiness report naming what is missing and what to run instead (usually a geo-lift). That refusal is the correct answer — do not retry with different parameters to force a number out of it, and do not substitute your own estimate.

get_journeysGET /api/v1/campaigns/{campaignId}/journeys

Exposure-ledger journeys for a campaign: journey stages (e.g. exposed on DOOH but not CTV), cross-channel frequency, per-channel and deduped reach, and ranked next-best-channel audience-sync suggestions (each flagged syncAvailable when an adapter can actually run it — feed one into sync_audience).

sync_audiencePOST /api/v1/campaigns/{campaignId}/sync-audience

Build an audience from the exposure ledger (households exposed on some channels and not others) and sync it to an adapter on the target channel as an inclusion or suppression audience — the sequencing primitive (e.g. billboard-exposed households retargeted on CTV). Returns the sync record with matched count and key-grade breakdown. Copy adapterKey and executionMode from the selected get_journeys suggestion exactly; the API rejects provider or mode drift.

upload_creativePOST /api/v1/creatives/upload

Upload the buyer’s existing creative bytes to a permitted campaign channel. Provide the original file as base64, its MIME type and supplier format; the API verifies and stores the asset and returns the created creative. File size is at most 20 MiB decoded. Uploading is separate from provider approval or booking: inspect the resulting precheck/readiness and attach the creative before requesting supplier booking. Inline HTTP uploads must fit the configured MCP body limit.

generate_creativePOST /api/v1/creatives/generate

Generate channel-appropriate ad creative (copy + renditions) from a brief, grounded in a persona passed directly or inherited from campaignId: e.g. a 30s audio script, DOOH copy, CTV storyboard, responsive search assets, or portable paid-social copy and asset direction. Returns the stored creative, its per-channel renditions, and an automatic clearance precheck. Then use submit_creative to send it to an adapter.

precheck_creativePOST /api/v1/creatives/{creativeId}/precheck

Run the AI clearance precheck on an existing creative: predicted UK CAP/BCAP, Clearcast/CAA, publisher, and search/social platform-review flags with rule citations, before you submit anywhere. Pass any factual claims the copy makes so substantiation requirements are checked too.

revise_creativePOST /api/v1/creatives/{creativeId}/revise

Rewrite a generated DOOH creative in your own words and re-render it through the same layout, brand kit and legal strip. Supply only the fields you want to change; the rest carry over from the creative you are revising. The result is a NEW versioned creative linked by sourceCreativeId — the original is never mutated, because it may already be trafficking. Copy is clamped to the format limits (a six-sheet cannot show more) and any field that had to be trimmed is named in clampedFields, so shortening it yourself keeps the wording exact. The clearance precheck re-runs on the revised copy, so an edit cannot dodge it. DOOH only — the storyboard channels would need the copy re-timed against scene durations, which is a different operation and is not pretended here.

set_campaign_creativesPATCH /api/v1/campaigns/{campaignId}/creatives

Replace a pending campaign’s creative selection with existing reusable creatives. Every selected creative must belong to the advertiser and match a channel in the campaign plan. Do this before activation; launch_campaign requires at least one same-channel creative with a completed, non-failing policy precheck for every campaign line. The selection locks once activation starts.

submit_creativePOST /api/v1/creatives/{creativeId}/submit

Submit an existing creative to a channel adapter for approval/trafficking (the adapter must have the "creative" capability — see list_connections). Returns the submission status and any adapter feedback.

get_asset_pricingGET /api/v1/assets/pricing

The AI asset production price ladder currently in force. Retail prices are derived server-side, never hardcoded: retail = provider cost basis ÷ (1 − margin%/100), with a configurable margin (default 80%, i.e. cost × 5) and a minimum-charge floor — cost bases, margin, and floor are all env-overridable on the API, so ALWAYS read the ladder from here instead of assuming amounts. Covers every kind: image per render, vo per script, music per track, video per second by tier (draft/standard/premium), and motion (programmatic SVG loops carry zero provider cost so the floor applies; rendered loops bill per second at the draft video basis). Amounts are GBP minor units (pence). Check this before produce_asset to quote the exact charge.

produce_assetPOST /api/v1/creatives/{creativeId}/assets

Produce a finished AI asset attached to an existing creative: video (CTV/cinema 16:9; DOOH 9:16 or 16:9 loops), image (DOOH stills), vo (audio-channel voiceover of the creative script), music (audio bed), or motion — an animated text loop ("moving image") for DOOH/display where the headline/subline/CTA slide and fade in, hold, and exit, looping forever. Motion has two modes: "programmatic" (deterministic animated SVG generated in-process, ready immediately) and "rendered" (a provider-rendered 5–10s video loop). IMPORTANT — production is a SEPARATE HARD wallet charge, debited immediately at submit and stated in the response (chargedMinor + remaining wallet balance). Definite provider failures are auto-refunded; an ambiguous acceptance becomes terminal reconciliation-required with the charge retained and retry disabled to prevent duplicate production. Prices are cost-plus at a configured margin over provider cost — call get_asset_pricing for the current ladder. Never blended into media-spend platform fees. Fails with 402 INSUFFICIENT_FUNDS (including shortfallMinor) when the wallet cannot cover it — top up first. Unset fields default sensibly from the creative’s channel and content. Then poll get_asset_status until ready.

get_asset_statusGET /api/v1/assets/{assetJobId}

Check an AI asset production job by id (from produce_asset). Jobs move submitting → queued → generating → ready, failed, or reconciliation-required. Poll while submitting/queued/generating; the other three states are terminal. Provider renders typically take tens of seconds to a few minutes (vo and programmatic motion complete synchronously at submit). When ready, outputUrl is the produced file (video/image/audio/animated SVG) ready to download or attach; sandbox mode (no provider keys) returns deterministic placeholder URLs. Failed means a definite provider failure: the wallet charge was refunded and retry creates a fresh debit. Reconciliation-required means provider acceptance is unknown: the charge is retained and retry is disabled to prevent duplicate production. Hand that state to a permitted human in Operator, then poll this tool; an MCP identity cannot assert the provider outcome.

list_connectionsGET /api/v1/connections

List every channel adapter (StackAdapt, Vistar, Sky AdSmart, DCM cinema, …) with its metadata (channels, capabilities, rail), verification provenance, current mode (sandbox/live), and whether credentials are set. Sandbox mode returns realistic deterministic data with zero credentials.

get_supplier_dossierGET /api/v1/connections/{key}/dossier

Read the privacy-safe agent projection of the tenant-owned supplier dossier for one adapter, including effective status, revision, provenance freshness, commercial access, supported operations, billing, technical API/MCP evidence, privacy, support and explicit readiness blockers. Credentials, contacts, source/artifact references, digests, reviewer identities and free-text notes are never returned. This tool cannot draft, update or verify a dossier; those authority changes remain human-only in Operator.

set_connectionPATCH /api/v1/connections/{key}

Switch an adapter between sandbox and live mode and optionally set its credentials. Live mode requires canonical credentials, implemented live provenance and a current human-verified supplier dossier. A campaign-specific, capped and expiring live-execution grant may also be required at launch; this tool cannot create one. An agent also cannot change a connection while an issued supplier grant exists, because the required safety revocation must be human-attributed. Sandbox needs none. Returns the updated connection.

get_billing_summaryGET /api/v1/billing/summary

The advertiser’s transparent fee ledger: wallet balance, media spend, accrued platform fees, and the current fee tier. AdBuyMCP charges 10% of media spend, disclosed per line; advertisers whose trailing-30-day spend exceeds £25,000 move to the scale tier — 5% of spend plus a £749/month SaaS fee. AI asset production (produce_asset) appears as its own DISTINCT line (assetProductionMinor): hard wallet charges per asset, never blended into the media fee — the blended take % stays media-only. Use this to explain exactly what the platform costs on top of media.

get_billing_statementGET /api/v1/billing/statements

Get the transparent JSON statement for one calendar month: media spend and per-campaign/channel platform fees, the scale-tier SaaS charge when applicable, and AI asset production as a separate hard-charge section. Amounts are integer GBP minor units. Use this for reconciliation; this tool does not return the CSV download variant.

get_topup_statusGET /api/v1/billing/topup/status

Check whether a live Stripe Checkout session has produced a webhook-backed wallet credit. A browser return is not payment evidence: pending means keep checking later; only credited includes trusted creditedMinor. Sandbox top-ups credit synchronously and do not need this tool.

top_up_walletPOST /api/v1/billing/topup

Create a prepaid-wallet top-up in GBP. Offline sandbox credits immediately; live and isolated Stripe-test modes create a Stripe Checkout session whose URL must be opened and whose eventual credit must be verified with get_topup_status. This is a consequential money operation: quote the exact amount and obtain explicit user approval immediately before calling. idempotencyKey is mandatory here; reuse it after timeouts. New live/Stripe-test funding intents require a funding-v2: prefix and unique opaque suffix. Existing keys must retain their exact value; a legacy key with no durable history or an uncertain provider outcome requires human operator reconciliation, never a replacement key or blind retry. Changed funding details fail.