Skip to main content
Interchange is built on the Ad Context Protocol (AdCP). This page covers the buy side — how Interchange, acting as a buyer platform, consumes AdCP across many sellers.
This is the buy-side view. For the seller (supply) side — connecting your own AdCP sales agent as a storefront source — see Connect your sales agent. When this page and the AdCP spec disagree on what the protocol means, the AdCP spec wins.
The external-buyer campaign spine described below is alpha and available only to explicitly enrolled buyer/storefront relationships. It supports governed create, update, cancellation, and live delivery through platform-composed storefronts and direct adapter storefronts. Adding packages during an endpoint update, change webhooks, and scheduled reporting exports are not part of this slice.

Two AdCP directions, one direct campaign mode

AdCP addresses one storefront at a time. Whether the storefront is reached through an external buyer endpoint or a connected account, the campaign carries mode: "directed" — a compatibility wire value; read the campaign’s management state for what the platform does with it: A task addressed directly to one storefront carries mode: "directed" because Interchange does not perform cross-storefront discovery or allocation. A discovery campaign can still finish with one seller when Interchange performed that selection; the result count does not change its mode. See Campaigns on connected seller accounts for the shared model. You may also hear this called a mediated AdCP campaign. Mediation is the platform invariant, so these docs use inbound when distinguishing the protocol direction. Neither “inbound” nor “mediated” is a campaign mode.

The cross-seller pattern

The defining difference between AdCP and Interchange on the buy side is the same everywhere: AdCP defines a task against one agent; Interchange runs it across many. That fan-out is our core scaling layer. An external AdCP client can also call one Interchange-hosted storefront directly. That is deliberately a single-seller protocol interaction, while Interchange still provides the buyer identity, contract, governance, audit, campaign, and ledger around the seller call.

Compliance at the edges, scale above them

Interchange does not ask a seller to understand a multi-seller request. The buyer-facing ext.interchange object selects storefronts, controls progressive polling, and optionally requests managed screening. Interchange then projects the canonical part of the request onto separate one-to-one get_products calls. Each seller returns its normal AdCP products/proposals; Interchange validates that response independently before aggregation. The aggregate page stays bounded rather than becoming one giant catalog:
  • pagination.max_results caps proposal and proposal-less-product candidates;
  • products referenced by a paged proposal travel with that proposal so its allocation graph is not split;
  • revisioned snapshots expose fast sellers while slower sellers remain pending;
  • cursors become stable only after all reachable sellers settle; and
  • storefront-qualified sf1: / sfp1: identities prevent collisions and are preserved until the bilateral purchase edge.
Optional screening is also above the protocol. It evaluates each valid proposal against buyer instructions and returns accept, reject, or refine. A refine decision is sent back to the originating seller through canonical AdCP; only the seller can change pricing, allocations, availability, or terms.

Conformance (buy side)

Status: 1:1 conforms as written · +ext with a Scope3 scaling layer · none not implemented yet.

External buyer to Interchange to seller (alpha)

An external AdCP client connects to one storefront at:
Every hosted storefront has one deterministic endpoint at this path. The endpoint is the storefront’s external demand surface for AdCP buyers: it exposes that storefront’s products and directed media-buy lifecycle, rather than performing Interchange’s cross-seller discovery or allocation. The endpoint can exist before a buyer/storefront relationship is enrolled for alpha transactions; write tasks remain fail-closed until the relationship is eligible. Use the normal authenticated AdCP 3.0/3.1 task lifecycle:
  1. Call get_adcp_capabilities and get_products on that storefront.
  2. Send create_media_buy with an idempotency_key, brand identity, flight, currency, and one or more explicitly budgeted packages.
  3. Use the returned media_buy_id with get_media_buys and get_media_buy_delivery.

Country and channel routing

For an external sales agent, Interchange reads portfolio coverage from get_adcp_capabilities.media_buy.portfolio:
  • primary_channels and primary_countries are the declared coverage for that source. Interchange keeps the two arrays correlated, and accepted countries equal primary countries.
  • Coverage from separate sources is never combined to manufacture a match.
There is no separate local accepted-country allowlist for a pass-through seller. After the staged buyer-routing flag is enabled, Interchange includes a source only when both primary arrays are complete and match the requested coverage. A missing or malformed primary array is unknown and is a go-live readiness gap. Before that flag is enabled, legacy product fan-out remains unchanged. Missing primary coverage means unknown, not global coverage. Interchange does not infer an upstream agent’s countries from the storefront Media Kit or business profile.

Linked account scope

When a request carries a linked storefront account_id, Interchange resolves the authenticated buyer’s grant before contacting any inventory source. Each source receives only the account identifier the seller assigned to that source; the linked Interchange account ID is never forwarded as if it were a source account. get_products returns structured AdCP errors when the account cannot be used: Missing, ambiguous, or stale source mappings are excluded from discovery without calling those sources. If every source required by create_media_buy lacks a healthy mapping, the tool returns ACCESS_DENIED with details.reason: "source_account_not_bound" and the coverage state in details.per_source. The seller must repair the mapping; the buyer then runs get_products again and submits a new media buy. Calls without a linked account and legacy natural-key accounts are unchanged. A transient account-resolution failure instead returns SERVICE_UNAVAILABLE with details.reason: "account_context_unavailable"; retry the same request after a short delay rather than changing the mapping. The same linked account now scopes media-buy reads. Call get_media_buys with the opaque account_id and no media_buy_ids to enumerate the mapped account across every inventory source that has a healthy native-account mapping. Interchange drains each source’s pages within a bounded discovery window, qualifies colliding native IDs into stable storefront media_buy_id values, and persists the route so get_media_buy_delivery can reach the same source later. Pass the same account and buyer credential on the delivery call; Interchange substitutes the source-native account again. To include terminal history, supply the desired status_filter values—an omitted filter keeps each source’s normal AdCP default. A targeted get_media_buys call with media_buy_ids reads already discovered storefront IDs and does not re-enumerate sources. Follow pagination.cursor to read the complete combined result. If one mapped source is unavailable, the completed response contains the buys from healthy sources plus a generic SOURCE_UNAVAILABLE entry; it never exposes the source name, native account ID, or provider error. If every mapped source is unavailable and there is no persisted result to return, the task fails with SERVICE_UNAVAILABLE and details.reason: "account_media_buy_sources_unavailable". Sources marked not_required are not enumerated for account history: an unscoped campaign list could expose other buyers. Account-enumerated buys are tracked, read-only records; create a managed buy through the normal product and media-buy flow instead of updating a discovered buy. Webhook activity is not included in this surface because the upstream call uses the storefront’s source credential, not the linked buyer principal. On a platform-composed storefront endpoint, the same linked account can list audience, signal, and event-source references with the Interchange MCP extension get_account_resources. Direct adapter storefronts do not expose this tool. This is a live, read-only call: Interchange verifies the active grant for the authenticated buyer principal before contacting a source, forwards each eligible source only its own native account reference, and returns opaque storefront-qualified resource IDs. It never returns private source IDs, source-native account IDs, audience membership, setup secrets, or event payloads. Every source/resource-kind pair reports capability, coverage, authoritative, observed_at, item/exclusion counts, truncation, and a generic error code when a provider read fails. Missing, ambiguous, stale, and not_required source mappings are never called. Demo or placeholder resources are explicitly labeled non-authoritative. Results default to 50 resources and accept pagination.max_results up to 100; follow the opaque cursor while pagination.has_more is true. A request is also bounded by a 30-second live-read window and a 1,000-resource safety ceiling, so partial or truncated must be checked before treating the result as a complete account inventory. This is different from the directed-campaigns alpha .../presences endpoint. That older endpoint reads a background mirror for enrolled connection accounts; get_account_resources uses the linked account’s principal grant directly and does not require directed-campaign enrollment. The same buyer credential must resolve to an Interchange buyer account. A transacting credential should be scoped to an advertiser. During the alpha, an unscoped credential may resolve by brand.domain only when that domain identifies exactly one active advertiser in the buyer account; missing or ambiguous identity fails closed.

What Interchange adds before seller dispatch

For an enrolled relationship, media-buy writes do more than relay the protocol request:
  • checks a buyer/storefront currency policy plus per-buy and aggregate exposure caps;
  • journals create, update, and cancellation idempotently so an uncertain seller outcome is not silently dispatched twice;
  • creates the compatibility mode: directed campaign projection, media buy, and package records in the buyer account;
  • pins the buyer’s zero-fee AdCP entitlement terms for the life of the buy;
  • commits the authorized amount to the campaign ledger after the seller accepts or begins processing the buy; and
  • records dark alpha usage at zero billable amount.
Zero-billable alpha usage applies to the feature’s usage meter, not to media. The authorized media budget and zero-fee AdCP entitlement still govern the buy. Every caller budget is gross: the all-in amount authorized by the buyer. Pure AdCP access pins a zero fee, so gross and net are equal and the full media budget reaches the seller. Ordinary buyer clearing fees are not inherited on this path; advanced value is governed by entitlements/IUs. The seller never receives buyer terms. See Budgets and fees. The route is dual-keyed. The Interchange campaign/media-buy identity drives contract, governance, and reporting records; the AdCP media-buy identity correlates the public task response and downstream seller object. get_media_buys and get_media_buy_delivery therefore remain addressable with the external buyer’s AdCP ID without making the seller’s ID the buyer-account primary key.

Current reporting behavior

get_media_buy_delivery is live read-through: Interchange calls the seller, returns the current delivery response, and opportunistically records realized spend against the pinned zero-fee entitlement ledger. The alpha does not promise a cached time series, change webhooks, scheduled delivery, or billing UI from that read.
Any future non-zero buyer-edge fee requires separate fee-inclusive delivery verification before rollout. The current alpha remains zero-fee and is not an invoice statement.

Current eligibility and limits

  • The buyer campaign spine is customer-scoped and fail-closed. There is no environment-variable bypass.
  • Every enrolled active storefront route creates the governed campaign, contract, operation, and ledger anchor before dispatch. This includes platform-composed storefronts and direct social/ad-platform ADAPTER storefronts. Wonderstruck ESA is the first live managed-agent proof; adapter routes also require a delegated, advertiser-mapped provider account.
  • Seller rejection and non-retryable dispatch failures mark the campaign as failed. A temporary source or adapter outage remains pending while Interchange retries for up to six hours, then becomes failed if the retry window ends without a successful dispatch.
  • The governed endpoint spine covers create_media_buy, supported update_media_buy fields, and cancellation. Update/cancel share the pinned policy, durable mutation journal, budget-delta caps, SCD2 activation, dark metering, ledger commitment sync, and ambiguous-outcome fence. Adding packages still returns a capability error.
  • Strict SDK lifecycle testing and source-specific end-to-end verification are both required before enrolling another seller.

Where the truth lives

AdCP specification

The protocol’s source of truth.

Connect your sales agent

The seller (supply) side — bring your AdCP agent in as a storefront source.

Get products across storefronts

Canonical AdCP-shaped retrieval with Interchange fan-out, screening, refinement, and purchase continuation.

Discover Products

The legacy-compatible grouped, browsable discovery-session projection.

Create a campaign

How a campaign spawns media buys across sellers.

Budgets and fees

Why the buyer budget is gross while the seller receives net media spend.

Campaigns on connected seller accounts

Tracked campaign mirrors — the opposite ownership direction.