> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apostra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Media Partners

> Browse media partners, connect provider accounts, and manage advertiser activation

A **storefront** is a publisher's buyer-facing home on Apostra — a single ID that aggregates one or more **inventory sources**. A source can be an external AdCP sales agent or managed ad-server-backed inventory. As a buyer you browse the storefronts you can transact with and connect the credentials each source or adapter needs so discovery and media buys flow. For the full conceptual model — the Merchandising Agent, Storefront-built vs. Agent-supplied storefronts, OAuth flows, and the seller side — see the [Storefront object guide](/v2/object-guides/storefront).

## Manage media partner connections

The Media Partners view combines discovery, selection, connection setup, and
advertiser activation. It replaces the standalone Marketplace and Connections
destinations. There is one seller catalog and one set of connection records.
Media partner cards display the seller's available brand logo and background treatment
from its marketplace identity.

The two V3 nouns answer different questions. A **seller** is one exact
Storefront commercial counterparty and exists whether or not you have
authorized it. A **connection** is one authorization grant from your buyer
account to that seller. A seller can have zero, one, or several connections;
each connection can discover several provider accounts. For example, one Meta
business authorization is one connection even when it reveals many child ad
accounts. Authorizing a separate Meta business creates another connection.

Media Partners replaced the standalone Marketplace and Connections destinations. There
is one seller catalog and one set of connection records — no separate views.
The same underlying v2 storefront, provider-connection, discovered-account,
advertiser-mapping, and selection records drive the surface.

The Media Partners view keeps five settings and statuses at their correct scopes:

* **Selection** applies to your buyer account and one Storefront. **Global
  Market Makers** are selected for every buyer account. **Regional Market
  Makers** are selected when an advertiser's country and channel match their
  qualified inventory — the Storefront's own declared markets when it has
  declared any, or its approved market/channel scope when it has declared
  none. **Marketplace sellers** are sales agents available to include
  explicitly. Creative, signal, measurement, optimization, and composite
  agents do not appear in this seller catalog. **Ready for buying** shows
  transaction-ready partners; **All** also shows sales storefronts that cannot
  transact yet, with their readiness status. **Marketplace ready** is a
  separate readiness fact: it means the
  exact Storefront is listed and can transact, not that the buyer selected or
  activated it.
  Apostra separately reviews whether a Storefront is Marketplace eligible and,
  if so, whether it is Market Maker eligible within a maximum market/channel
  scope. The seller controls whether its eligible Storefront is published or
  opted out through `save_seller` or the Storefront update API. An active Market
  Maker entitlement can activate only an eligible
  Storefront and only within that approved scope; paying for an entitlement
  cannot bypass eligibility. Critical Supply and commercial access are two
  entitlement paths, not listing classes. Seller-declared coverage is
  supporting evidence rather than authority, and every path remains subject to
  publication, marketplace quality, and technical readiness.
  Related businesses under one organization can appear as separate Storefront
  cards. One organization entitlement may cover those Storefronts, but each is
  reviewed separately and receives only the markets and channels shared by the
  entitlement and its own approved scope. A Critical Supply entitlement belongs
  only to the exact reviewed Storefront and does not flow to sibling cards.
  An account administrator can always include or always exclude one exact
  Storefront. These classifications describe why a seller is offered; they do
  not describe how it authenticates.
* **Billing policy** also applies to your buyer account and a Storefront. When a
  Storefront supports both consolidated and direct media billing, you can choose
  while the policy is unlocked. Direct-only Storefronts require one account-wide
  acceptance that applies to current and future advertisers. Accepting direct
  billing does not lock the policy. It locks when Apostra dispatches the
  first activation for an eligible advertiser, before that activation becomes
  Active. A locked policy is read-only; changing it will require a future
  billing migration process, which is not part of this rollout.
  Operator-auth platforms are always direct: the platform bills your connected
  account under its terms, so Media Partners shows the policy read-only instead of
  offering a consolidated/direct selector.
* **Data sharing permission** applies to your buyer account and one Storefront.
  It is a consent gate: enabling it allows that seller to receive the selected
  classes of customer data for current and future advertisers, but does not
  itself select or send any audience, catalog, or conversion data. Each
  advertiser separately registers the specific audiences, catalogs, and
  conversion sources used by its downstream workflows. Account-wide permission
  and advertiser-level data registration are separate layers. **Turning a
  permission off is destructive**: it disables every advertiser's existing
  registrations of that data class under the seller, and turning the
  permission back on does not restore them — each advertiser must re-register.
  Both directions ask for confirmation on the Media Partners page.
* **Activation** is tracked for the buyer account, Storefront, and advertiser.
  The advertiser view lets an administrator choose **Inherit**, **On**, or
  **Off** for that advertiser only. Inherit follows account selection and
  automatic market/channel matching. Account-wide **Always include** and
  **Always exclude** remain authoritative; an advertiser preference cannot
  override them. Turning one advertiser off preserves a shared Seller
  authorization while another advertiser still needs it. The account overview
  shows the aggregate state beside each advertiser's state and
  required action. When an agent-auth seller is selected, Apostra
  asynchronously activates every current eligible advertiser and picks up new
  eligible advertisers while that selection remains active. Always exclude
  prevents new advertiser accounts from being created; it does not erase
  historical seller accounts. Operator authorization, account mapping, and direct-billing
  acceptance appear as **Action required** overlays within any classification;
  they are not separate seller categories. A selected Storefront with no
  advertisers is **Not applicable**, not inactive.
* **Enhanced Reporting** applies to one exact connected account, never to every
  account on a seller connection. Turning it on records that account's reporting
  preference; an existing reporting subscription starts its reporting and history
  pipeline. A billing period earns the published account-reporting rate only
  after that exact account completes a successful subscription sync that started
  after the control was enabled. An account with no subscription or successful
  sync draws no IUs. Turning the control off stops future work while retaining
  existing reports and billing evidence. It requires an active IU rate card and
  does not affect ordinary connection, account mapping, Buy, Events, Audiences,
  or directed campaigns.

Activation can be **Provisioning**, **Active**, **Action required**, **Waiting
on seller**, **Retrying**, **Failed**, **Retiring**, **Inactive**, or **Not
applicable**. Operator-auth sellers can require **Connect account**, **Reconnect**,
or **Map account** for each advertiser. Direct-only sellers can require
**Approve direct billing**. Agent-auth sellers provision and sync
directly; they do not ask you to select a seller account. A rejection from an
agent-auth seller is shown as a seller outcome, not as an account-mapping
action. A failed row includes an opaque support code that support can correlate
with the durable activation event without exposing credentials. Currency and reporting time zone are advertiser settings; markets and
channels inform automatic seller availability. Advertisers do not choose a
separate billing policy.

An operator authorization such as Meta can expose multiple child ad accounts.
Media Partners shows the complete discovered account inventory, provider status,
Business Manager or other parent when known, mapped advertisers, and last
update. Each advertiser has one active default mapping per seller/source;
changing it preserves the old link for historical buy attribution. A provider
account can be reused across advertisers. Routing one buy across multiple
provider accounts is a campaign-level allocation concern, not an advertiser
activation or seller-selection setting.

Use **Add account** to start the existing provider connection flow again,
**Reconnect** to refresh access, and **Remove connection** to archive one
authorization. Removing a connection does not erase advertiser mappings; a
mapping that no remaining authorization can reach is retained as unreachable
until you reconnect or map another account. Provider account inventory is an
authoritative snapshot from the platform, so Apostra does not offer a
misleading delete button for one discovered Meta ad account.

Sandbox is an advertiser property, not a label Apostra can infer for every
provider account. Create one with **Create sandbox advertiser**; the setup task
opens with sandbox enabled, and sandbox cannot be changed after creation.
Media Partners marks those advertiser rows and selector options as **Sandbox**. Meta
test-account classification is not supported yet, so Meta provider accounts are
not labeled sandbox and a sandbox-only Meta account-list request returns no
production accounts.

Storefront availability and buyer connection state are separate. `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. Apostra clears the media transaction — and it appears on your Apostra media bill — only when the storefront advertises `agent` billing (AdCP `BillingParty` vocabulary: the agent, Apostra, 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 Apostra never touches the media money.

## Automatic selection and overrides

Selection answers whether your buyer account should have a connection to one
exact storefront. An eligible storefront can be selected automatically because
it is a Regional Market Maker with qualified inventory in an advertiser's
country and channel, or because a Market Maker-eligible Storefront has matching
Global Market Maker authority. In the reviewed model, Market Maker
eligibility is not itself activation: without a matching entitlement the
Storefront remains Marketplace-visible as **Market Maker eligible**. Critical
Supply or commercial authority activates it only where the entitlement's markets
and channels intersect the approved maximum scope. A seller publication
opt-out removes it from buyer discovery without changing the underlying Apostra
review. Global authority can select the Storefront account-wide even before the
buyer has an advertiser. Selection is account-wide: one selected storefront
connection is reused across advertiser contexts.

Online video (`olv`) is reviewed as its own channel. A Storefront's display or
connected-TV approval does not grant online-video Market Maker coverage; its
approved scope and matching entitlement must both include `olv`.

Market Maker scope uses the AdCP `MediaChannel` vocabulary: `display`, `olv`,
`social`, `search`, `ctv`, `linear_tv`, `radio`, `streaming_audio`, `podcast`,
`dooh`, `ooh`, `print`, `cinema`, `email`, `gaming`, `retail_media`,
`influencer`, `affiliate`, `product_placement`, and
`sponsored_intelligence`. Existing `audio` scope is interpreted as
`streaming_audio`; new scope uses the canonical value.

An account administrator can set an override for the exact storefront:

* **Default** removes the explicit override and returns control to automatic
  selection.
* **Always include** selects the storefront account-wide while it remains
  eligible, even when your current advertiser footprint has no matching
  market-and-channel context.
* **Always exclude** prevents the storefront from being selected.

The override does not apply to sibling storefronts owned by the same seller.
Hard ineligibility, such as an archived or non-transactable storefront, still
wins over an include decision.

Inside one advertiser, Seller activation has a separate scoped preference:

* **Inherit** follows account selection and automatic matching.
* **On** uses the Seller for this advertiser when eligible.
* **Off** does not use the Seller for this advertiser only.

Seller eligibility takes precedence over every account or advertiser setting.
Account **Always include** or **Always exclude** settings override the advertiser
preference until the account returns to **Default**. Changing an advertiser
preference does not create or remove an authorization grant, change another
advertiser, or alter account-wide billing or data-sharing settings. The public
V3 write is `save_connection({ sellerId, advertiserActivation: { advertiserId,
decision } })`, where `decision` is `DEFAULT`, `ENABLED`, or `DISABLED`.

Selection is also separate from activation and billing readiness. A direct-only
or operator-auth storefront can remain selected while its connection reports an
action such as approving direct billing, connecting or reconnecting an account,
or mapping an advertiser. Unsupported or failed activation does not temporarily
turn the selection off. See [Update selection override](/v2/buyer/storefronts/tasks/update-selection-override)
for the API operation.

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/brand 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 an Apostra admin declares a Slack channel shared between a buyer and a
seller, Apostra 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 authorization connection for the
same buyer, and each authorization can reveal more than one provider account.
For example, an agency can authorize separate Snap businesses for different
brands, while either business can expose several child ad accounts. Use the
storefront authorization flow again to add a connection; already-connected
storefronts show this as **Add account** rather than replacing the existing
grant.

Brief-led product discovery separates a platform product from the remaining
campaign decisions. On TikTok, a brief with one clear objective but no country
still returns relevant products and reports `missing_geography` in
`scope3_brief_strategy`; it does not imply that the connected account has no
inventory. A missing or competing objective returns no recommendation until
you choose one. State countries in explicit geographic prose, such as “in the
US” or “markets: GB and AU.” When a Meta or TikTok strategy is ready, its plan
contains the exact returned product and pricing-option IDs plus an immutable
execution snapshot. Activation resources such as a Page, form, Pixel,
identity, destination, or creative remain separate selections and must still
be supplied when the product contract requires them.

Use `buying_mode: wholesale` when you need the complete deterministic catalog
of adapter-executable products. Brief mode composes from that catalog; it does
not replace or narrow the wholesale result. A brief response can keep grounded
products in its relevant shortlist while withholding an actionable plan. In
that case, `scope3_brief_strategy.clarification_codes` identifies unresolved
decisions such as objective or geography; the returned strategy remains
`clarification_required` until you provide the material choice. Product,
capability, signal, and resource IDs in a ready plan must come from the
discovery and account evidence supplied for that request.

Apostra maintains a versioned synthetic contract corpus across Meta, Google,
TikTok, LinkedIn, Snap, Pinterest, Reddit, and Spotify. Missing adapter
observations fail the portfolio check; the corpus does not imply that every
adapter already returns the shared plan. The check does not contact provider
accounts and does not prove that a connected account is ready to launch.
Continue to use the returned account-resource readiness and execution-package
fields before creating a media buy. This evaluation adds no new response
fields and requires no change to existing API requests.

For a Meta, TikTok, or Snap product returned by brief or wholesale discovery,
`execution_readiness.slots` shows those activation resources as they appear on
the connected account. Each slot names whether Apostra selected the only
eligible account resource, needs you to choose among several, needs account
setup, needs campaign input such as a URL or creative, or could not read that
provider inventory. Candidate IDs and names come from the provider account—not
from brief interpretation. A failed inventory read is never presented as “no
resources.” Meta Form candidates also identify their owning Page. TikTok
identity remains a deliberate choice because it must match the selected
creative, while a single eligible Pixel can be selected automatically. Snap
binds the account's Public Profile automatically when present and returns
Snap Pixel candidates for conversion-optimized products; a product without a
buyer-supplied creative or destination is flagged with `input_required` on
those slots.

LinkedIn Lead Generation is not currently available to buyers. The
single-image resource, creative, and readback implementation remains behind a
protected conformance gate until an approved exact-revision no-spend lifecycle
run is retained. It is absent from ordinary product discovery, and ordinary
create requests fail before contacting LinkedIn. Carousel, video, Message,
Conversation, and Document Lead Gen branches are also not executable.

LinkedIn Website Conversions is not currently available to buyers either. The
single-image resource, creative, and readback implementation is present
behind the same protected conformance gate: it binds one or more of the
selected account's enabled conversion rules as `optimization_goals` event
sources and verifies each campaign's conversion association, but it is absent
from ordinary product discovery until an approved exact-revision no-spend
lifecycle run is retained. Carousel and video Website Conversions are also
not executable. Matched Audiences access is a separate, optional signal
source across LinkedIn products; its absence never blocks discovery or
campaign creation.

Wholesale Meta App Promotion products expose the same account resource view
under `product.ext.scope3_execution_readiness`, even without paid brief
composition. Installs, post-install events, and in-app value are separate
products; application, event source, provider-authorized conversion event,
Page identity, creative, and audiences remain separate attachments. This lets
a buyer reproduce the platform UI choice without creating one product row for
every app, event, audience, or targeting combination.

The selected product's
`ext.scope3_brief_strategy.execution_package_template` is the request-ready
portion of that decision. It includes the exact product and pricing option,
geography, resolved audiences, event goal, and authorized Page, Pixel, Form, or
App IDs. Check `remaining_inputs` before execution: URLs, creative,
account setup, and ambiguous choices are intentionally not guessed. Pass a
chosen Meta Instant Form as `leadFormId` in the buyer product selection; it is
forwarded to the adapter with its Page and event goal. Pass a chosen TikTok app
as `appId`; it is durably forwarded to the App Install writer.
For **Meta Sales — Website Catalog Sales**, choose an authorized commerce
catalog and a non-empty product set that belongs to it. The execution package
carries them as `meta_catalog_id` and `meta_product_set_id`, alongside the
selected Pixel/Dataset, Facebook Page, destination, and creative. Catalogs and
product sets are activation resources, never audience signals. A `get_products`
call returns a bounded number of product-set candidates in
`ext.scope3_execution_readiness` across every ad-account-authorized catalog;
once a catalog is chosen, pass its ID as `ext.meta_catalog_id` on a follow-up
`get_products` call to scope discovery to that one catalog. A catalog-scoped
call still returns candidates one page at a time; if the response's
`product_set` slot reports more remain, pass the last candidate's ID as
`ext.meta_after_product_set_id` on the next call to continue from there.
For **Meta Engagement — Event Responses**, the account's upcoming, promotable
Facebook Events are also returned one page at a time in the `destination`
slot; if it reports more remain, pass the last candidate's ID as
`ext.meta_after_event_id` on the next `get_products` call to continue from
there.

For **Meta Leads — Messenger, Instagram Direct, and WhatsApp**, the account's
welcome-message flows are returned the same way in the `welcome_message` slot,
scoped per authorized Page or Instagram profile. This slot always reports
`decision: "explicit_selection_required"` — unlike Page or Pixel selection,
a welcome message is never auto-bound even when exactly one candidate exists,
because it fixes the automated conversation a lead-to-message buy runs.
Candidates only appear on a catalog-style `get_products`/`discover_products`
call with no `brief` — a `buying_mode: "wholesale"` request that still
includes a `brief` does not surface them; a brief-driven call only computes
readiness for the one AI-selected product, and drops it entirely if the
brief needed any clarification. Reads are best-effort per identity: if some
authorized Pages or Instagram profiles couldn't be read within the read
budget, the slot still returns any real candidates the identities that did
succeed found, and `reason` names how many couldn't be read — it is not
silently presented as a complete list. An account with more than 50
authorized identities only sees candidates from the first 50 (a stable,
sorted subset). The slot reports `decision: "inventory_unavailable"` —
instead of a false "no compatible flow" — whenever a read failure (an
identity's own read, or the authorized-identity list itself) leaves zero
candidates found; an account with zero authorized Pages or Instagram
profiles to begin with is a different, successfully-confirmed case and still
correctly reports no compatible flow.

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,
Apostra 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 active and
usable; the old credential is retired only after the replacement commits.
When a reconnect succeeds, Apostra 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. Retail-media 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.

For tracked campaigns, 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, Apostra marks the adapter credential `EXPIRED` and the storefront connection summary reports `error` until the buyer reconnects.

Bearer and API-key adapter credentials cannot be refreshed by Apostra. 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

| Concept                                | Description                                                                                                                     |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Storefront                             | A publisher's buyer-facing presence aggregating inventory sources behind one `id`                                               |
| Inventory source                       | A source behind a storefront, either an external AdCP sales agent or managed ad-server-backed inventory                         |
| `requiresCredentials`                  | Whether the buyer must register credentials to use a source                                                                     |
| `readiness`                            | Canonical transaction availability: `canTransact`, `effectiveStatus`, and machine-readable `blockerIds`                         |
| `connected`                            | Whether the source is usable without additional credentials or already has working buyer credentials; not seller readiness      |
| Selection                              | Whether the buyer account should maintain a connection to one exact storefront; independent of activation and billing readiness |
| Selection override                     | `DEFAULT`, `ALWAYS_INCLUDE`, or `ALWAYS_EXCLUDE` for one buyer account and exact storefront                                     |
| Credential                             | A buyer's registered account at a source — covers one or more `(storefrontId, sourceId)` pairs                                  |
| `credentialId`                         | Connected provider credential identifier used to disambiguate duplicate upstream account IDs                                    |
| `displayStatus`                        | Deprecated stored-control compatibility label; do not use for purchasing availability                                           |
| `sourceCount` / `connectedSourceCount` | Total sources vs. those the buyer has wired up                                                                                  |

## Task reference

<CardGroup cols={2}>
  <Card title="List storefronts" href="/v2/buyer/storefronts/tasks/list-storefronts" icon="list">
    `GET /storefronts` — paginated summaries
  </Card>

  <Card title="Get storefront" href="/v2/buyer/storefronts/tasks/get-storefront" icon="magnifying-glass">
    `GET /storefronts/:storefrontId` — rolled-up connection state
  </Card>

  <Card title="Get storefront capabilities" href="/v2/buyer/storefronts/tasks/get-storefront-capabilities" icon="signal">
    `GET /storefronts/:storefrontId/capabilities` — source diagnostics
  </Card>

  <Card title="Update selection override" href="/v2/buyer/storefronts/tasks/update-selection-override" icon="toggle-on">
    `PUT /storefronts/:storefrontId/selection-override` — use Default, Always
    include, or Always exclude
  </Card>

  <Card title="List credentials" href="/v2/buyer/storefronts/tasks/list-credentials" icon="key">
    `GET /storefronts/credentials` — all your registered credentials
  </Card>

  <Card title="Register source credentials" href="/v2/buyer/storefronts/tasks/register-source-credentials" icon="user-lock">
    `POST /storefronts/:storefrontId/sources/:sourceId/credentials` — connect an
    inventory source, not an adapter provider
  </Card>

  <Card title="Connect an AdCP source (alpha)" href="/v2/buyer/storefronts/tasks/connect-adcp-storefront" icon="link">
    Project a mapped source account into tracked campaigns
  </Card>
</CardGroup>

## Related

<CardGroup cols={2}>
  <Card title="Storefront object guide" href="/v2/object-guides/storefront" icon="store">
    Full model: sources, OAuth, seller side
  </Card>

  <Card title="Discovery" href="/v2/guides/discovery" icon="magnifying-glass">
    Once connected, run discovery to find products
  </Card>
</CardGroup>
