Skip to main content
When a buyer submits a media buy to your storefront, it lands in your approval queue as a pending entry holding the raw AdCP create_media_buy payload. You inspect it and record a decision: approved or rejected. Approved entries are forwarded upstream to the underlying sales agent by the storefront’s MCP layer; the forwardedAt stamp tells you when that succeeded. For when this queue is used — the mediaBuyApproval setting (and why manual still auto-forwards clearly on-policy buys), the lowest-risk “review everything” posture, and how you find out something is waiting — see Reviewing buyer transactions.

What the pre-screen verdict means

Each queued entry carries the deterministic pre-screen verdict: clearly on policy (would have auto-forwarded), needs a look, or clearly against an explicit rule you wrote. That last bucket is decision-support only — the platform does not auto-reject; a clearly-against-policy buy still queues for your decision. For the full verdict model, the one-way AI second opinion, and how the agent reads your written policy, see Acceptance policy.
A buyer you’ve opted into per-buyer auto-approve never appears in this queue — their media buys forward without a pending entry. If you expect a buyer’s buys and never see them here, check your auto-approve overrides.
An entry moves through pending → approved or pending → rejected. Decisions are terminal — deciding an entry that is no longer pending is rejected, so a double-decide cannot slip through. The revoked state covers buyer- or system-initiated cancellation after a decision and is not something you set on the decide endpoint. Each entry is keyed by the buyer’s AdCP mediaBuyId.

Buyer task callbacks

Buyer agents can attach AdCP push-notification config to the original create_media_buy call. The storefront stores that callback configuration separately from the operator-facing payload and uses it when the approval resolves.
Use push_notification_config for canonical AdCP requests. The storefront also accepts pushNotificationConfig from clients that pass camelCase JSON through a REST/MCP proxy. Callback URLs must be public HTTPS endpoints; localhost, private-network, link-local, metadata, and internal hostnames are rejected. Supported authentication schemes are Bearer and HMAC-SHA256. When the operator approves and every underlying source accepts the forwarded buy, the buyer webhook receives a signed ADCP task event with status: "completed" and a result containing the accepted media_buy_id. When the operator rejects, or approval succeeds but source forwarding fails, the webhook receives status: "failed" with an AdCP-compatible error object. Polling the submitted task remains the fallback if no callback is supplied or delivery fails. Media-buy task events use the AdCP task protocol media-buy; creative approval task events use creative. These webhook protocol values are distinct from the snake-case media_buy value advertised by storefront capabilities.
The approval row returned to storefront operators omits push_notification_config and pushNotificationConfig from submittedPayload so webhook credentials are not exposed in the queue UI or REST responses.
All examples use the storefront base URL:
Authenticate every request with Authorization: Bearer $SCOPE3_API_KEY.

Task reference

List approvals

GET /media-buy-approvals — the approval queue, newest first

Get an approval

GET /media-buy-approvals/{mediaBuyId} — one queue entry

Decide an approval

POST /media-buy-approvals/{mediaBuyId}/decide — approve or reject