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

# Inventory sources

> Connect AdCP-compatible agents and ad servers to your storefront so buyers can discover and transact against your inventory

An **inventory source** is a named slot inside your storefront that your Merchandising Agent draws from when it answers buyer briefs. Each source wraps something the agent can call: an external AdCP-compatible sales agent, an operator-owned ad server with Apostra-managed sales-agent plumbing behind it (an **ad-server-backed source**), a linked storefront source, or a modular source assembled from individual modules. Buyers never target a source directly — they call your storefront, and discovery fans out to every eligible, compatible Source.

All examples use the storefront base URL:

```
https://api.apostra.com/api/v2/storefront
```

Authenticate ordinary storefront requests with `Authorization: Bearer $SCOPE3_API_KEY`. The storefront is resolved from your API key's account context — there is no `customerId` path parameter. Routes below that explicitly require a direct human Account Admin or SuperAdmin session use that session instead.

## Key concepts

* **Execution type.** Every source has an `executionType`: `AGENT` (external AdCP sales/signal/creative/outcome agent), `MANAGED_SALES_AGENT` (ad-server-backed source — GAM, FreeWheel, SpringServe, or AdsWizz), `LINKED_STOREFRONT`, or `MODULAR_SOURCE`. `AGENT` sources use the generic inventory-source endpoints. A pilot-enabled seller can use the same create endpoint to create a linked storefront source that selects an approved storefront as `LINKED_STOREFRONT`; the new row remains `PENDING`, cannot receive requests or bookings, and can only be disabled until its separate terms and activation requirements are met. Managed and modular sources use dedicated provisioning flows.
* **Two identifiers.** `sourceId` is unique within your storefront and is what you use for actions on your own rows. `id` is a globally unique surrogate used for cross-account actions (for example, a seller approving an inbound link).
* **Lifecycle.** A source moves through `PENDING → ACTIVE → DISABLED → ACTIVE`. That source status is the single lifecycle authority for an external-agent source; its connection metadata and legacy agent registration do not carry a second status. A linked storefront source starts `PENDING`; configure its pass-through terms and activate it when the selected partner storefront still consents. A failed activation keeps the current status: `PENDING` stays `PENDING`, and `DISABLED` stays `DISABLED`. You can update terms while it is pending, active, or disabled. Updating disabled terms leaves it disabled; activate it separately to use the latest terms version. Archived linked storefront sources cannot be configured. You can disable a linked storefront source with the standard update endpoint. Existing diagnostics may still return `agentStatus` as a deprecated copy of `sourceStatus`; do not interpret it independently. An ad-server-backed source is enabled unless `deactivatedAt` is set (`null` means enabled). Its `operational.isLive` value is health/readiness presentation, not a discovery-eligibility decision. Recent failures surface as `lastErrorCode`/`lastError`. The operator flow is the same: create the connection, save ad-server config, test it, launch into the admin UI, then deactivate or reactivate as needed.
* **Linked storefront source terms.** The pilot uses pass-through terms: the buyer price equals the partner price, the platform retains 0%, and supplier settlement is external to the platform. The buyer-payment collector comes from the buyer account's approved billing setting for the selected seller account on your storefront and is recorded on each booking. This is separate from the partner's consent for your storefront to buy from it. Changing terms creates a new version; a later activation uses the latest version, while existing bookings keep the terms recorded when they were booked. For flag-enabled pilot storefronts, active linked storefront sources with current partner consent receive briefs and bookings. Pending, disabled, archived, or no-longer-authorized sources do not. The partner sees your storefront as the buyer for these requests; your buyer's account remains on your own booking and is not sent to the partner.
* **Linked partner availability.** A linked partner must remain marketplace-listed, opted in, unpaused, and unarchived for new briefs, bookings, budget increases, and new packages. If the partner later delists, existing bookings still support delivery reads and polling, cancellation, budget decreases, creative sync, and approval forwarding for as long as that partner storefront exists. A delisted partner cannot receive new work.
* **Eligibility is not health.** Apostra sends discovery to every Source
  whose Storefront and Source setup are complete, whose Storefront is not
  paused, and whose Source and mapped Agent are explicitly eligible. Request
  channel, country, and currency compatibility then selects the recipients for
  that request. Degraded or erroring health remains visible but does not stop
  requests by itself; an explicit ineligibility decision does.
* **Product paths.** A Sales Agent explicitly declares whether it supplies
  ingredients for Apostra to merchandise (Storefront-built), complete
  buyer-ready products (Agent-supplied), or both. A Source whose Agent supports
  both selects one or both paths. This is not a separately priced add-on and is
  not controlled by a Storefront-wide toggle.
* **Managed sources are wholesale.** An ad-server-backed source has a fixed
  Storefront-built contract because raw ad-server inventory must be converted into
  sellable products. Other active Sources retain their own independent paths.
* **Component cache.** When a Storefront-built source supports AdCP 3.1+
  wholesale products, Apostra stores those inputs for merchandising and
  Storefront-built reads.
  Cache success means the source returns stable component ids, pricing, formats,
  property/selectors, delivery type, and execution metadata. A cache miss does
  not by itself mean live passthrough is broken.
* **Credentials are never echoed.** Agent API keys and JWT private keys are encrypted at rest and referenced by an opaque ref. Responses surface `authConfigured: true` instead of the raw secret.
* **Connection definitions are versioned.** The external sales-agent Task pins
  the endpoint, protocol, and authentication definition used during setup.
  Built-in and Partner-backed integrations use the same typed definition model,
  while older integrations keep their existing setup path until migrated.
* **Modular readiness.** A `MODULAR_SOURCE` is composed of typed modules (inventory feed, booking ledger, trafficking, status sync, reporting import). Its readiness projection reports per-module contracts, lifecycle stages, missing setup fields, and open work-item counts.

## Plans, entitlements, and feature profiles

Inventory Sources is available in the navigation for every seller account. A
new seller chooses **Just list** or **Agentic Media Company**. Both include
listing and can connect inventory through the supported source paths. Just list
uses an agent operated by your company, a partner, or another provider; that
agent can be connected during setup and does not need to exist at signup.
Agentic Media Company adds Apostra's hosted Merchandising Agent, which you train
for your business. Operator ownership is Source configuration, not a separate
plan or feature profile.

Plans are the commercial choice. Each plan declares its default feature
profile. Feature profiles determine the coherent set of product surfaces the
account receives; entitlements are reserved for independently sold additions:

* **Basic / Listing** includes Apostra listing,
  sales-agent connection, and operational surfaces for campaigns, media buys,
  creatives, approvals, delivery, activity, and reporting. AI Business Rules
  are available here. Saving, enabling, and evaluating AI Business Rules is not
  an IU-rated activity today; other qualifying activity remains governed by the
  organization's accepted IU Rate Card.
* **Listing + Distribution** is the standard paid Seller Account package for unlimited
  self-serve advertiser invitations and management, public listing distribution
  and an optional customer CNAME, and
  customer-branded AdCP and ChatGPT app channels. It does not improve or rank
  Apostra listing, replace the connected sales agent, or enable
  Merchandising and modular inventory sources. Existing accepted offers continue
  to use the advertiser capacity stated in their terms. Until this package is active,
  **Listing** shows the Public distribution benefits and an
  upgrade link instead of the domain step and destination controls.
* **Premium** uses the Merchandising profile. Merchandising includes publisher
  self-service and **Custom modular sources** without separate entitlements.

**Enterprise** describes custom commercial terms such as price, term, credits,
support, and payment arrangements. It uses the same Premium/Merchandising profile
when the product surfaces are the same, so Enterprise also includes publisher
self-service and **Custom modular sources**. A separate Enterprise feature
profile is needed only if the account receives a genuinely different product
experience—not merely a different contract.

Standard managed integrations are included with every seller plan; sellers do
not need to know whether Apostra implements one with modular internals. The
stable internal feature key for customer-specific composition is
`modular-sources`, and customer-facing surfaces call it **Custom modular
sources**. Basic excludes it; Premium and Enterprise include it through the
Merchandising profile. It is not a separately provisioned entitlement.

## Working with an ad-server source in Murph

Ad-server setup is separated by job so first-time connection does not compete
with operational detail:

1. **Connect ad server** is a one-completion task. Choose the provider, enter
   the account or credential details it requires, create the source, and the
   task closes.
2. **Ad server source** is the return page for an existing source: current
   posture, default-advertiser work, configuration, and deactivation.
3. **Sync & diagnostics** is the evidence page for source health, sync streams
   and run history, and buyer-discovery cache freshness. It appears when you
   ask for diagnostics or follow a source problem; it is not a permanent green
   setup step.

If part of the diagnostics payload is temporarily unavailable, Murph names the
missing evidence and keeps the rest visible instead of treating a failed read
as an empty or healthy result.

## Add another source

Open the **Inventory** workspace in the seller navigation and choose **Add
inventory source** whenever you want to connect another source. This opens the
Inventory sources list and expands the provider choices immediately. Choose an
ad server, a modular inventory source, or an external AdCP sales agent to open
its structured setup flow; the button does not turn the action into a new chat
prompt.

Adding a source keeps the storefront settings you already completed: currency,
approval routing, business profile, publisher domains, acceptance policy, and
selling rules. The new source gets its own connection, credentials, catalog,
health, and setup work. Seller Setup lists those facts per source, so a healthy
first source cannot hide a second source that is still waiting for credentials,
sync, products, or repair.

When an exact specialist destination is available, the source card also shows
**Open source**. It opens the existing ad-server detail, modular readiness, or
external-agent diagnostics surface directly. The action is omitted when that
destination cannot be resolved or its capability is not enabled.

## Submit a certification test-fixture setup request

Use [Submit certification test setup](/v2/storefront/inventory-sources/tasks/submit-certification-fixture-setup)
for the request, response, authentication, state, and idempotency contract.

An Account Admin can nominate a separate, non-production inventory Source for
review before a protected certification test uses it. This REST request records
the setup for review. It does not create a fixture, run a test, dispatch an
evaluation, or grant certification. No Agent Task or MCP tool starts this
request yet.

Use the exact current revision and its attested endpoint, plus an active,
separate Source and account that are owned by the same seller. Supply current
isolation evidence and the required fixture specification. Never nominate a
live customer Source as the test fixture.

```http theme={null}
POST /api/v2/provider/registration/capabilities/{capabilityUid}/certification-fixture-setups
Authorization: Bearer <your direct Account Admin session token>
Content-Type: application/json

{
  "revisionUid": "<uuid>",
  "endpointUid": "<uuid>",
  "inventorySourceId": "<positive bigint>",
  "sourceAccountId": "<positive bigint>",
  "isolationEvidence": {
    "reference": "review://provider/sandbox",
    "digest": "sha256:<64 lowercase hex characters>",
    "expiresAt": "2026-09-30T12:00:00.000Z"
  },
  "spec": { "...": "Provider certification fixture specification" },
  "idempotencyKey": "<8-128 character replay key>"
}
```

Authenticate this request with the current direct human Account Admin session
for the seller that owns the capability. Service principals, API keys, simulated
sessions, and indirect access cannot submit a setup request.

`spec` must describe a non-deliverable setup: an `isolation` object with the
selected sandbox kind and each required isolation guarantee set to `true`, a
`nonDeliverableMode` of `PAUSED` or `FUTURE_DATED`, a cleanup lifetime from 60
to 86,400 seconds, and at least one product with a supported route. Include
the reviewed tenant-isolation or operational-ownership probe when the provider
contract requires it.

The response contains `setupRequestUid`, `state: "PENDING_REVIEW"`,
`isolationEvidenceExpiresAt`, `createdAt`, and `replayed`. Reusing the same
request returns the same receipt with `replayed: true`.

### Administrative review

Review is a separate administrative REST action, not an inventory-source Task
or MCP tool. A direct human SuperAdmin user reviews the pending request at:

```http theme={null}
POST /api/v2/admin/provider-certification/candidates/{capabilityUid}/fixture-setup-requests/{setupRequestUid}/review
Authorization: Bearer <SuperAdmin user session token>
Content-Type: application/json

{
  "ownerCustomerId": 123,
  "action": "APPROVE"
}
```

An Account Admin cannot approve a request. API keys, service principals,
simulated sessions, delegated support, and indirect access cannot approve it.
The `ownerCustomerId` must match the seller that owns the submitted capability.
The only supported action is
`APPROVE`; malformed identifiers or body values return `400 VALIDATION_ERROR`,
and callers that do not have a direct human SuperAdmin session receive
`403 FORBIDDEN`.

An approval response returns `setupRequestUid`, `state: "APPROVED"`, the
registered `fixtureEvent`, and `replayed`. Repeating approval for the same
approved setup request returns the same fixture event with `replayed: true`;
it does not create another fixture event. Approval registers and parks that
exact separate Source; it still does not launch validation or certify the
Agent. A request that is no longer current, whose evidence has expired, or
whose Source is unavailable or unsafe to park is rejected instead. Submit a
new truthful request only after correcting that condition.

Seller Setup keeps the decisions separate: setup complete or setup required;
Agent unmapped, certified, validated, or unvalidated; context-free routing
eligibility; Source health; and Agent implementation health. Use Source Health or TARS to
preview whether a Source is selected for an exact channel/country/currency request.
A sales agent on the Agent-supplied path does not need a warm merchandising cache.
Bad or malformed returned products are a health error and are filtered from the
response, but they do not silently make the Source ineligible.

<Note>
  Sources can't be deleted while their backing agent has non-terminal media buys
  (`ACTIVE`, `PAUSED`, `PENDING_APPROVAL`, or `INPUT_REQUIRED`). Cancel or
  terminate those first.
</Note>

## Task reference

### Manage

<CardGroup cols={2}>
  <Card title="List inventory sources" href="/v2/storefront/inventory-sources/tasks/list-inventory-sources" icon="list">
    Every source on the storefront
  </Card>

  <Card title="Create inventory source" href="/v2/storefront/inventory-sources/tasks/create-inventory-source" icon="plus">
    Register an external AGENT source
  </Card>

  <Card title="Get inventory source" href="/v2/storefront/inventory-sources/tasks/get-inventory-source" icon="magnifying-glass">
    Read one source by ID
  </Card>

  <Card title="Diagnose third-party sales agents" href="/v2/storefront/inventory-sources/diagnostics" icon="stethoscope">
    Check source health and recent AdCP activity
  </Card>

  <Card title="Update inventory source" href="/v2/storefront/inventory-sources/tasks/update-inventory-source" icon="pen">
    Change fields, rotate auth, transition status
  </Card>

  <Card title="Delete inventory source" href="/v2/storefront/inventory-sources/tasks/delete-inventory-source" icon="trash">
    Remove a source and disable its agent
  </Card>
</CardGroup>

### Ad-server connection

<CardGroup cols={2}>
  <Card title="Get ad-server connection" href="/v2/storefront/inventory-sources/tasks/get-ad-server-connection" icon="server">
    Connection state for a managed source
  </Card>

  <Card title="Get status" href="/v2/storefront/inventory-sources/tasks/get-status" icon="heart-pulse">
    Operational snapshot of the managed source
  </Card>

  <Card title="List sync history" href="/v2/storefront/inventory-sources/tasks/list-sync-history" icon="clock-rotate-left">
    Historical sync runs for drill-down
  </Card>

  <Card title="Replace ad-server config" href="/v2/storefront/inventory-sources/tasks/replace-ad-server-config" icon="gear">
    Set GAM, FreeWheel, SpringServe, or AdsWizz config
  </Card>

  <Card title="Rotate credentials" href="/v2/storefront/inventory-sources/tasks/rotate-credentials" icon="key">
    In-place credential rotation
  </Card>
</CardGroup>

### Lifecycle

<CardGroup cols={2}>
  <Card title="Launch admin UI" href="/v2/storefront/inventory-sources/tasks/launch" icon="up-right-from-square">
    Mint a one-time URL into the managed source
  </Card>

  <Card title="Test connection" href="/v2/storefront/inventory-sources/tasks/test-connection" icon="plug-circle-check">
    Probe upstream reachability
  </Card>

  <Card title="Refresh" href="/v2/storefront/inventory-sources/tasks/refresh" icon="arrows-rotate">
    Force-refresh the status cache
  </Card>

  <Card title="Deactivate" href="/v2/storefront/inventory-sources/tasks/deactivate" icon="ban">
    Soft-delete the managed source
  </Card>

  <Card title="Reactivate" href="/v2/storefront/inventory-sources/tasks/reactivate" icon="rotate-right">
    Re-enable a deactivated source
  </Card>
</CardGroup>

### Modular

Modular sources use a staged operator lifecycle: ingest avails, inspect product
projections, reserve capacity, prepare supported execution handoffs, release
capacity when needed, and work any source-side human queue items. See the [modular lifecycle guide](/v2/storefront/inventory-sources/modular-lifecycle)
for the full setup checklist, feed format, sequence, and examples.

<CardGroup cols={2}>
  <Card title="Prepare inventory source inputs" href="/v2/setup/publisher-onboarding-starter-kit" icon="clipboard-check">
    Request the complete evidence pack and copy parser-valid avails templates
  </Card>

  <Card title="Modular lifecycle guide" href="/v2/storefront/inventory-sources/modular-lifecycle" icon="diagram-project">
    End-to-end avails, reservation, execution handoff, release, and HITL
    workflow
  </Card>

  <Card title="Author property and tag mappings" href="/v2/storefront/inventory-sources/tasks/import-mapping" icon="diagram-project">
    Preview and author property/tag to key-value, ad-unit, or placement mappings
  </Card>

  <Card title="Get modular readiness" href="/v2/storefront/inventory-sources/tasks/get-modular-readiness" icon="diagram-project">
    Runtime projection for a modular source
  </Card>

  <Card title="Update module config" href="/v2/storefront/inventory-sources/tasks/update-modular-module-config" icon="sliders">
    Write non-secret config for one module
  </Card>
</CardGroup>

## Related

<CardGroup cols={2}>
  <Card title="All inventory-source tasks" href="/v2/storefront/inventory-sources/tasks" icon="list-check">
    Every operation in one place
  </Card>

  <Card title="Storefront onboarding" href="/v2/setup/storefront-onboarding" icon="store">
    End-to-end seller setup
  </Card>

  <Card title="Diagnose third-party sales agents" href="/v2/storefront/inventory-sources/diagnostics" icon="stethoscope">
    How to inspect source health and recent ADCP calls
  </Card>

  <Card title="Storefront object guide" href="/v2/object-guides/storefront" icon="store">
    How buyers see your storefront
  </Card>

  <Card title="Errors" href="/v2/reference/errors" icon="triangle-exclamation">
    Shared error contract
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.