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. 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.
{
  "media_buy_id": "mb_2026_q2_ctv",
  "packages": [
    {
      "product_id": "run-of-site",
      "budget": 50000
    }
  ],
  "push_notification_config": {
    "url": "https://buyer.example.com/adcp/tasks",
    "token": "buyer-echo-token",
    "authentication": {
      "schemes": ["HMAC-SHA256"],
      "credentials": "shared-webhook-secret"
    }
  }
}
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.
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:
https://api.interchange.io/api/v2/storefront
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