readiness.canTransact is the canonical answer to whether ordinary buyer traffic can purchase now, and readiness.effectiveStatus explains whether the storefront is live, blocked, paused, or archived. Credentials are still required per source when applicable. List endpoints return sourceCount and connectedSourceCount; detail returns connected, requiresCredentials, and customerAccounts. Those connection fields describe buyer wiring only and never make a blocked storefront live.
There are two bills: intelligence units (IUs) and media. Interchange clears the media transaction — and it appears on your Interchange media bill — only when the storefront advertises agent billing (AdCP BillingParty vocabulary: the agent, Interchange, is the invoiced party and bills you). Every storefront list and marketplace card carries supportedBilling, and every hosted AdCP capability response carries the protocol-native account.supported_billing, so you know the counterparty before you buy. Adapter storefronts advertise ["operator", "advertiser"]: your connected platform account bills you directly, and Interchange never touches the media money.
Storefront names are not always the names buyers use in conversation. The
authenticated storefront list’s name filter also resolves the seller
account or company, brand, publisher/operator domain, and website. Public Murph
lookup uses only curated storefront name, brand, domain, and website fields for
marketplace-listed storefronts, so questions such as
“Is OptOut’s storefront available?” work without supplying an exact domain or
connecting the Slack channel to an account. That public answer contains only
the seller and storefront names, public status, domain, channels, and regions;
buyer credentials and account-specific data still require authentication.
When a Scope3 admin declares a Slack channel shared between a buyer and a
seller, Interchange records that relationship as demand and automatically
shows the seller’s marketplace-visible storefront relationship in the buyer’s
Supply I would buy view with the storefront channel. These rows are labeled as shared-channel tracking and are not
removable manual requests. Any seller-facing demand summary keeps the buyer’s
identity private unless disclosure is separately permitted.
Use GET /api/v2/buyer/storefronts/:storefrontId/capabilities when you need a diagnostic view of the active sources behind a storefront. External AdCP sales-agent sources are capability-checkable and include cached-or-refreshed capability details. Managed ad-server-backed sources are returned with probeable: false and probeStatus: "not_applicable"; do not treat those rows as unreachable agents just because they are not checked through the AdCP capabilities endpoint.
Adapter storefronts can have more than one connected provider account for the same buyer. For example, an agency can connect separate Snap business accounts for different brands, or a single advertiser can connect separate provider accounts for separate product lines. Use the storefront connection OAuth flow again to add another provider account; already-connected storefronts show this as adding an account rather than replacing the existing one.
When listing or linking advertiser accounts from an adapter storefront, use the returned credentialId to distinguish which connected provider credential owns the account. This is required when more than one connected credential can expose the same upstream accountId.
Account discovery is stored as an authoritative provider snapshot. The account
list preserves the provider’s normalized and provider-native status, hierarchy,
advertiser label, and ISO currency; these fields are returned consistently by
the buyer REST API and service routes. Only active advertiser accounts can
become the default or selected buying account. Manager containers and accounts that are pending,
payment-blocked, suspended, rejected, or closed remain visible for setup and
diagnosis but are not selectable. If provider pagination or validation fails,
Interchange keeps the previous valid snapshot rather than treating a partial
response—or a storage error midway through publication—as account deletion.
When a credential is replaced while an older refresh is still running, the
older response is discarded even if it completes last; only the snapshot made
with the current credential can replace the stored list. For Meta, a
sandbox: true account-list request returns no accounts until Meta test-account
classification is supported, so production accounts are never returned to a
sandbox canary. A database lock or statement timeout during publication also
keeps the prior complete account list. Publication is rejected before changing
the stored list if a provider returns more than 5,000 accounts or the complete
database publication exceeds 30 seconds. During a rolling deployment, an older
application replica can still change which existing account is selected, but
cannot replace authoritative provider account fields without the current
credential proof.
OAuth token refresh publishes a replacement credential atomically. If that
publication fails, the previously connected credential remains bound and
usable; the old credential is retired only after the replacement commits.
When a reconnect succeeds, Interchange keeps the selected account and its
stable account identity only if the refreshed grant’s complete account list
still contains that account; the account is then rebound to the refreshed
credential. A selected Snap account is not reported as authorized unless that
exact active OAuth credential still owns the account and its stored secret can
be read. Missing, expired, errored, mismatched, or unavailable credentials fail
closed before a provider tool runs and expose the safe diagnostic reason
delegated_auth_unready; reconnect Snap to restore the account.
Existing Snap connections require one reconnect after this deployment. This
intentionally establishes fresh account-ownership proof instead of trusting or
backfilling a pre-deployment snapshot. Until that reconnect succeeds, Snap
adapter calls fail closed with delegated_auth_unready.
OAuth credentials are never returned in account metadata. Meta financial amounts are converted from the
account currency’s minor unit, so zero-decimal currencies such as JPY and
three-decimal currencies such as KWD are not treated as cents. Meta’s zero
spend_cap value means that no spending cap is configured; it is not reported
as zero available credit.
For Meta products, placement choices use publisher-scoped AdCP placements.
Today the selectable catalog contains Facebook and Instagram Feed, Stories,
and Reels. Name the surfaces in the discovery brief or a refinement request to
narrow the product before buying. If you do not select placements, the adapter
keeps Meta Advantage+ placements as the default. A creative’s placement mapping
controls where that creative can render; it does not change the inventory
purchased by the media buy.
Placement publication is fail-closed. Meta publishes six targetable Facebook
and Instagram surfaces. Publisher-contained Spotify products publish included
MUSIC inventory. Spotify podcast and TikTok inventory can span publisher
networks, so they are not published under Spotify’s or TikTok’s domain. Other
adapters do not turn creative-format labels, automatic strategies, or ad
networks into placements until provider selection, containment, and exact
readback are implemented. Flashtalking is creative/ad-serving
infrastructure, not a publisher sales agent. CitrusAd and Criteo inventory must
be scoped to account-discovered retailer domains, never the technology
vendor’s domain.
Placement performance is returned only when the product advertises
supports_placement_breakdown and the request includes
reporting_dimensions.placement. Meta and publisher-contained Spotify Music
products support package-level by_placement rows. Spotify verifies that Music
packages have no off-platform impressions; podcast/network packages do not
advertise the capability. Other adapters omit the dimension until their
provider reports can be mapped and reconciled to public placement IDs exactly.
For directed-campaign REST delivery, set placementBreakdown=true; optional
placementLimit and placementSortBy query parameters map to that same AdCP
request.
Adapter credentials are separate from inventory source credentials. Do not use POST /storefronts/:storefrontId/sources/:sourceId/credentials to fix an adapter-provider OAuth token, API key, or bearer token; reconnect or rotate the adapter credential through the storefront adapter connection flow for that provider.
In the connected-account campaigns alpha, a registered external AdCP source can
also be projected into the shared buyer connection plane after its account is
discovered and linked to an advertiser. Use
POST /storefronts/:storefrontId/sources/:sourceId/adcp-connection; it does not
accept a new endpoint or secret and does not replace source registration.
Adapter credential lifecycle
Adapter storefront credential status is maintained after the initial connection. OAuth credentials are refreshed automatically during use and by a nightly health sweep before expiry. If refresh fails because the provider token is expired, revoked, or otherwise rejected, Interchange marks the adapter credentialEXPIRED and the storefront connection summary reports error until the buyer reconnects.
Bearer and API-key adapter credentials cannot be refreshed by Interchange. If they carry an expiry timestamp, the health sweep notifies operators before expiry and marks them EXPIRED after expiry. Delegated adapter calls that receive provider auth failures also write back credential health: expired OAuth credentials become EXPIRED, while invalid API keys, bearer tokens, or permission failures become ERROR.
Key concepts
Task reference
List storefronts
GET /storefronts — paginated summariesGet storefront
GET /storefronts/:storefrontId — rolled-up connection stateGet storefront capabilities
GET /storefronts/:storefrontId/capabilities — source diagnosticsList credentials
GET /storefronts/credentials — all your registered credentialsRegister source credentials
POST /storefronts/:storefrontId/sources/:sourceId/credentials — connect an
inventory source, not an adapter providerConnect an AdCP source (alpha)
Project a mapped source account into tracked campaigns
Related
Storefront object guide
Full model: sources, OAuth, seller side
Discovery
Once connected, run discovery to find products