Skip to main content
Three read-only surfaces answer the operating questions “what buys do I have, where is this one stuck, and what needs attention” — without a ticket and without platform support looking at a database. Each is available as a REST endpoint and as an in-chat surface (ask Murph, or open it from the rail’s Operate section). All examples use the storefront base URL:
https://api.interchange.io/api/v2/storefront
Authenticate every request with Authorization: Bearer $SCOPE3_API_KEY.

Media buys — every buy on the storefront

GET /media-buys returns the union of routed buys (buys forwarded through the storefront routing layer — the approval queue plus per-source forwarding routes) and ESA-managed buys (buys living inside an embedded sales-agent tenant). Filter by status, buyerCustomerId, sourceId, or flight-start window. The default sort is urgency: buys still waiting on someone whose flight starts within 48 hours (or has already started) come first, ordered by flight start; everything else follows newest-first. Each row carries:
FieldMeaning
statusA coarse seller lifecycle view derived from persisted state: pending_approval, forwarding, forward_failed, awaiting_source, rejected, canceled, booked, delivering, paused, completed. This is a platform list-view convenience, never an AdCP status.
sourceStatusThe raw upstream status as persisted, for transparency.
pendingReasonWhy the buy is not delivering yet — the same shared vocabulary buyers see (awaiting_storefront_approval, awaiting_source_moderation, creative_processing_at_source, awaiting_creative_approval, forward_failed_retrying, forward_failed_needs_correction, accepted_awaiting_trafficking, scheduled_not_started), rolled up to the most-blocking source leg. It is an annotation, never a status.
errorCodeThe structured error code of the latest failed exchange (the platform’s ledger vocabulary, e.g. unknown_product_ids).
forwardOutcomeHow far dispatch got: not_forwarded, all_completed, all_submitted, partial, failed.

Per-buy timeline — what was sent, when, and where it is stuck

GET /media-buys/{mediaBuyId}/timeline is the seller-scoped projection of the buy’s exchange record. Stages follow the exchange lifecycle, failure branches included:
received → screened → decided → forwarded / forward-failed → submitted
        → source moderation (pending since T) → accepted / rejected → delivering
Update exchanges reuse the same stages. Inbound source webhooks appear as evidence inside stages, never as a stage of their own — many sources never send webhooks, so their absence means nothing. The screened stage is reserved for the acceptance-policy pre-screen record and is not emitted today; do not wait for it. What you can see, and what you cannot. The forwarded payload is yours to inspect — you are the counterparty to that message — minus platform-internal fields: webhook/push-notification configuration and any signing or credential material are removed server-side. Platform-internal diagnostics (resolution cache internals, worker polling state, cross-tenant audit entries) never appear; failures surface as structured error codes with a recovery class instead. A payload shown as {"pruned": true} means retention removed the stored bytes (payload bodies are kept for 90 days; the slim event record is kept indefinitely). Each source leg carries a trafficker-grade summary of the request (flight, budget, packages, targeting dimensions) with the raw JSON behind a disclosure.

Whose reference to quote to whom

Every leg carries two references, and they are for different counterparties:
ReferenceFieldQuote it to
Their reference — the source’s own idstheirReference.mediaBuyId / theirReference.taskIdThe inventory source. These are ids minted in their system; their support can look them up directly. For adapter sources (e.g. Google Ad Manager) the platform order id plays this role.
Platform reference — the create idempotency keyplatformReference.idempotencyKey (sf:<storefront>:<buy>:<source>) paired with platformReference.requestedAtThe source (for pre-acceptance exchanges — it is the deduplication key they received) and Scope3 support. Always quote the key together with the request timestamp: the key is stable across the buy’s life, requests are not.
While a source is still moderating (no upstream buy exists yet), their task id is the handle; once accepted, their media-buy id is.

Pending operations — everything waiting on someone

GET /pending-operations returns the union of work in flight, grouped; a group appears only when it is non-empty:
  • approvals — media buys (creates and updates) waiting on your review.
  • creativeReviews — creatives waiting on your review.
  • failedForwards — approved buys that could not be sent to their source, grouped by structured error code so a source outage reads as one row, not N. Each group and item carries its gated action (below).
  • awaitingSource — buys a source accepted asynchronously and is still moderating, each with “waiting since” and the source’s task id.
  • sourceDegradations — seller-owned source-health diagnoses: an ad-server or sales-agent source you operate that is degraded, each with its severity (blocking, attention, or advisory) and a one-line summary. Only diagnoses you own appear — an issue Scope3 or a vendor must fix never shows up as your task. Each row links to the source diagnostics surface scoped to that source.

Recovery classes: why some failures have no retry

Every forwarding failure carries a recovery class, and the class — not the operator’s optimism — decides which action is offered:
Recovery classMeaningAction offered
transientThe send can succeed if repeated (source outage, timeout). The platform retries these itself for up to 6 hours after approval.Retry — a one-decision confirmation that re-fires the forward. The create idempotency key makes a duplicate booking impossible if the source already received it.
correctableThe request needs a change before any send can succeed (e.g. an expired cross-currency quote).Fix & resubmit — guidance; retrying the same payload would fail identically.
structuralNo retry can ever succeed (e.g. the selected product no longer resolves). The platform terminalizes these — it stops retrying and marks the buy.Escalate to Scope3 — with the buy’s references pre-attached. A retry button is never shown, because a retry would silently do nothing.
A transient failure whose retry window has lapsed is treated as terminalized and also becomes escalate-only.

Transition notifications

You do not have to keep this surface open: a forward failure on an approved buy and a source-moderation wait that ages past its deadline each push one notification to your storefront’s notification stream (in-app, email, Slack — per your delivery settings). These fire on the transition only, never repeatedly, and carry the error code and recovery class.

Task reference

List media buys

GET /media-buys — every buy, routed and ESA-managed, urgency-sorted

Get a buy's timeline

GET /media-buys/{mediaBuyId}/timeline — the seller-scoped exchange record

List pending operations

GET /pending-operations — everything waiting on someone

Retry a failed forward

POST /media-buy-approvals/{mediaBuyId}/retry-forward — transient, non-terminalized failures only