> ## 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.

# Listings

> Understand the buyer-visible storefront identity, coverage, policy disclosure, and Marketplace filters

A **listing** (previously called the media kit or Discovery Card) is the
buyer-visible projection of a storefront. The same
listing powers Marketplace results and the `discoveryCard` object returned by the
buyer storefront APIs. It is not a separate inventory or policy object.

<Note title="Identity, not authorization">
  A listing describes the seller/Storefront identity; seeing the listing does
  not mean the buyer is connected. In the buyer V3 surface, one `seller` can have
  zero, one, or several authorization `connection` objects, and each connection
  can expose multiple provider accounts. See
  [Media Partners and connections](/v2/buyer/storefronts/overview) for that relationship.
</Note>

Seller admins publish this same listing from **Settings → Discovery &
distribution**.
The publication identity, logo, colors, and generated icons come from the
values present in the storefront's canonical brand profile when it is
published. Icon generation is not a background step to wait for.
Publishing and downloading the submission package do not require a logo. If the
brand profile has no usable logo, the publisher uploads production-ready logo
assets directly in OpenAI before submitting. See
[Publisher domains and Discovery publication origins](/v2/storefront/publisher-domains#discovery-publication-origins)
for the operator workflow and public-origin behavior.

The **Discovery & distribution** page links to the complete
[OpenAI submission walkthrough](/v2/reference/white-label-chatgpt-app#4-prepare-the-public-submission),
including verification, package contents, manual logo handling, and the steps
that remain in OpenAI.

Visibility and account access are separate. **Public** makes the published
Discovery page readable on the web; it does not grant anonymous or self-serve
access to the account. Browser-based MCP apps still need OAuth, PKCE, an exact
registered redirect URI, and an account-approved browser origin.

Public distribution also requires an active publication hostname. Apostra's
first-party publication uses the platform-managed `api.apostra.com` origin
and needs no CNAME. A customer-owned origin uses the TXT ownership and CNAME
routing records shown in **Discovery & distribution** before it can become the
preferred public origin. The machine-readable listing JSON is available
under **Developer details** for renderers and integrations; it is not a manual
submission artifact.

## Public root and agent discovery

A verified customer CNAME is one shared publication implementation, not a copy
of the API or a new set of routes maintained for that customer. Its root stays
human-first while publishing machine links in both the HTML and HTTP `Link`
headers. Listing assets stay on the verified publication origin; reusable skills
stay on the platform API origin:

| Path                                                         | Purpose                                                                                 |
| ------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
| `/`                                                          | Human listing with a small **For agents** footer.                                       |
| `/card.json`                                                 | The exact machine-readable listing revision.                                            |
| `https://api.interchange.io/skills/index.json`               | Public, versioned workflow catalog.                                                     |
| `https://api.interchange.io/skills/buy-from-seller/SKILL.md` | Workflow for finding and using this publication's verified seller-specific AdCP action. |

The platform-managed Apostra listing uses `/discovery` and
`/discovery/card.json`; agents should follow the advertised links instead of
assuming either layout.

The public listing and skill do not grant access. A buyer authenticates as its own
entitled Apostra identity. To transact directly with the published Seller,
the agent follows the verified `actions[kind=adcp].url` from the listing. On a
Seller CNAME that URL is `/adcp/mcp`, because the verified hostname already
identifies the Seller. A platform-managed listing uses the shared-host fallback
`/seller/{platformId}/mcp`. The agent must not derive a Seller ID or restore the
retired `/storefront/{platformId}/mcp` path.
The action is included when the Seller has the Listing + Distribution package;
other published Listings do not advertise a direct transaction endpoint.
The public projection follows the Seller's current profile immediately, so
changing profiles does not require republishing the Listing.

The CNAME changes public discovery and routing only. Apostra remains the
agent of record for the resulting inbound AdCP campaign: it anchors buyer
identity, advertiser, contract terms, governance, journal, reporting identity,
accepted commitments, and delivery evidence. The Seller Account manages the
one-to-one buy; the public hostname does not bypass Apostra or create a new
commercial counterparty.

`/mcp/v3` is a different contract: it is the account-resolved Apostra
product API. The authenticated account, enrollment, and capabilities determine
which nouns and tools appear in `tools/list`. Serving V3 through an approved
hostname does not make it a direct Seller endpoint, and the hostname does not
widen the credential's authority.

Use the listing to answer three questions before sending a brief:

* Who operates this storefront?
* Does it accept briefs for this channel and country?
* Has the seller chosen to disclose any Advertising Policies?

## Coverage declarations

`coverageDeclarations` contains the source-specific coverage claims. Each entry keeps
the channels and countries declared by one source together. A managed
storefront normally has one declaration; a storefront whose sources are all
external sales agents can have one declaration per active upstream inventory
source. Never combine channels
from one declaration with countries from another.

The top-level `channels` and `countries` arrays are aggregate search and display
facets. They are the union of known values, not a promise that every listed
channel is available in every listed country. Country values are ISO 3166-1
alpha-2 codes such as `FR`, `US`, and `JP`. The legacy channel alias `audio` is
normalized to the AdCP channel `streaming_audio`.

Use `GET /api/v2/buyer/storefronts?region=FR&channel=ctv` to find storefronts
that accept CTV briefs in France. Legacy market-group filters such as `EMEA`
remain available for older region declarations, but new listings use
country codes. A combined channel-and-country filter matches only when one
declaration satisfies both known dimensions. During the compatibility rollout,
missing country coverage remains eligible for country-filtered discovery so
existing storefronts do not disappear. Known country restrictions still apply,
and an explicitly empty authoritative declaration from a pure pass-through storefront remains ineligible.

The `coverage` object makes completeness explicit:

| Value      | Meaning                                                                                                                                                                           |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `declared` | The storefront has an authoritative declaration for this dimension.                                                                                                               |
| `partial`  | Some sources declare the dimension and others do not.                                                                                                                             |
| `unknown`  | Apostra has no authoritative declaration. Country filters temporarily keep these storefronts eligible for rollout compatibility; the listing does not claim worldwide acceptance. |

`acceptsAllCountries: true` remains the only explicit worldwide declaration.
For managed storefronts that still have legacy unknown country coverage, Seller
Setup starts the editor with every country selected. Saving records that
worldwide behavior explicitly; leaving the old record untouched preserves the
temporary compatibility behavior above.

## Where listing fields come from

The listing carries `provenance` so buyers and agents can distinguish operator,
registry, and upstream facts.

* Managed storefronts author their accepted channels and countries in Seller
  Setup. Their identity is resolved from the verified brand domain and its
  brand profile, with an operator-authored Marketplace description.
* Official provider adapters always use the provider name registered by
  Apostra and the channels implemented by that adapter. Stale
  operator-authored channels cannot change the provider's listing coverage.
  Apostra uses the provider logo when it can resolve that logo from the
  provider's registered domain. Until then, the listing shows the provider's
  initials; it never pairs the provider name with the operator's logo or
  colors. The brand domain remains a separate ownership fact.
* A pure pass-through storefront projects coverage
  from that source's standard AdCP `media_buy.portfolio.primary_channels` and
  `primary_countries`. Those values are read-only in Apostra because the
  upstream sales agent is authoritative. The listing turns each source's two
  arrays into one correlated `coverageDeclarations` entry; accepted countries
  equal primary countries, and separate sources are never combined. A mixed or
  BOTH-capable storefront's Storefront-built sources instead declare coverage
  locally.

Brand identity remains owned where its `brand.json` is hosted. Seller Setup
opens the specific AAO brand Page for an AAO-hosted identity. For a self-hosted
identity, it instead tells the seller to update `/.well-known/brand.json` on the
verified brand domain.

All Marketplace listings and buyer storefront responses use this same projection;
clients do not need to resolve a second profile to reproduce the listing.

## Advertising Policies

`advertisingPolicies` is an optional buyer-facing disclosure. A managed seller
chooses whether to publish its Brief Acceptance rules, Creative Policy, or
both. Approval routing, approver identities, revision notes, and per-buyer
overrides are never included. A pure pass-through storefront can expose the upstream AdCP
`media_buy.portfolio.advertising_policies` value read-only; a mixed or
BOTH-capable storefront's local disclosure remains editable.

The complete disclosure is bounded to 10,000 characters. Storefront list
responses use `hasAdvertisingPolicies` plus a bounded
`advertisingPoliciesExcerpt`; retrieve storefront detail when you need the
complete disclosed text.

Advertising Policies help evaluate fit, but absence is not permission. The
seller or upstream agent still decides whether to accept a brief.

## Response fields

| Field                                                     | Purpose                                                                      |
| --------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `displayName`, `logoUrl`, `logoBackground`, `brandColors` | Resolved storefront identity.                                                |
| `description`, `website`                                  | Buyer-facing summary and verified destination.                               |
| `channels`, `countries`                                   | Aggregate search and display facets; never a cross-product coverage promise. |
| `acceptsAllCountries`                                     | True only for an explicit worldwide declaration.                             |
| `coverageDeclarations`                                    | Source-correlated channel and country claims.                                |
| `coverage`                                                | Whether each coverage dimension is declared, partial, or unknown.            |
| `advertisingPolicies`                                     | Optional complete policy disclosure on detail responses.                     |
| `provenance`                                              | Source of identity, coverage, and policy values.                             |

## V3 compatibility

For new V3 integrations, read the listing with
`get({ kind: "seller", include: ["listing"] })` (`discoveryCard` is a
deprecated alias) or open the `listing` Page (`discovery_card` is an
accepted, deprecated spelling of the same Page; `open_page({ page:
"media_kit" })` is retired as an ambiguous key and returns an error naming
`listing` and `business_profile` instead of opening either). The older
`get(kind: "media_kit")` and `save_media_kit` contracts remain available as
deprecated V3 compatibility surfaces pointing at the legacy Business Profile;
they do not define the canonical listing model.

<CardGroup cols={2}>
  <Card title="List storefronts" href="/v2/buyer/storefronts/tasks/list-storefronts" icon="list">
    Filter Marketplace storefronts by country and channel.
  </Card>

  <Card title="Storefront object guide" href="/v2/object-guides/storefront" icon="store">
    See how storefronts, inventory sources, and Agent-supplied routing relate.
  </Card>
</CardGroup>
