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

# Product composition

> Products assembled to a buyer's brief on demand by the Merchandising Agent, instead of hand-authored one at a time.

<Note title="Beta">
  Product composition is in beta. The behavior below is live for storefronts with
  a ready Storefront-built product path; the surface may evolve before general availability.
</Note>

**Product composition** lets your storefront assemble buyer-ready products on
demand instead of returning a fixed catalog to everyone. When a buyer sends a
brief, the [Merchandising Agent](/v2/concepts/storefront-agent) builds products
for it — selecting from your inventory building blocks, applying your
[operating instructions](/v2/storefront/operating-instructions/overview), pricing
them against your [Playbook pricing](/v2/storefront/playbook/overview), and
returning products shaped for the brief in front of it.

A composed product is indistinguishable from a hand-authored one to the buyer — it
carries a name, description, targeting, canonical `format_options[]`, and pricing. The
difference is that you never had to author it: the agent built it from your rules.

When a composed product is backed by your static avails feed, it also carries
an `ext.scope3_merchandise` block: the actual property each backing avail runs
on, its available delivery for that avail's own window, and any audience
facts your [product marketing](/v2/storefront/product-marketing/overview) has
taught for that channel — all resolved from your own data, never invented.
This block is not exclusive to composition: a `buying_mode: "wholesale"`
response carries the same `ext.scope3_merchandise` block for the same
static-avails-feed products, since it's read from your inventory data
directly rather than produced by composition. See
[the story-first proposal](/v2/storefront/proposal-story#the-plan-specifically-what-youre-buying)
for the full field-by-field explanation.

Composition is deterministic where it matters — the same brief against the same
inventory and rules returns products with stable ids, so a buyer who discovers
again sees the same products rather than a fresh set each time.

## How the product path is selected

Product composition is not a separately priced add-on and has no Storefront-wide
on/off switch. Each inventory source has an explicit product contract:

* **Storefront-built** supplies ingredients that Apostra turns into buyer-ready
  products.
* **Agent-supplied** supplies complete products that Apostra preserves and routes
  back to that Sales Agent.
* **Both product paths** supports both flows; each Source selects one or both.

The Sales Agent provider owns that declaration. Apostra Source pages show it
read-only. Apostra support handles declaration and both-path selection reconciliation;
Storefront operators cannot change the contract with a local toggle.

The Storefront-built path needs these things in place:

1. **A ready wholesale source.** The source must declare and implement the AdCP
   3.1+ wholesale product contract. Ordinary buyer-facing products are never
   guessed to be ingredients.
2. **Author operating instructions.** Composition can't run without rules — an
   active [operating-instructions](/v2/storefront/operating-instructions/overview)
   ruleset tells the agent what to build and how. If a Storefront-built path is
   ready but no active ruleset exists, the storefront auto-pauses and notifies
   you rather than composing blindly.

If diagnostics say the wholesale path is not ready, correct the Agent's product,
property, format, pricing, or execution declaration as reported, then ask Apostra
support to refresh or reconcile the capability. Apostra does not infer a new
mode from catalog contents.

Optionally, set [Playbook pricing](/v2/storefront/playbook/overview) so composed
products are anchored to your rate card's floors, targets, and ceilings.

<Note>
  An [ad-server-backed source](/v2/storefront/inventory-sources/overview) has a
  fixed Storefront-built contract. An ad server exposes raw
  inventory — ad units and placements — which must be composed into buyer-ready
  products before it can be sold; this is source behavior, not an account toggle.
</Note>

## Provider adapter catalog snapshots

For a storefront connected directly to a supported provider, each successful
wholesale discovery refreshes a durable snapshot of every product the adapter
returned. The seller product list combines that snapshot with products from any
managed ad-server sources, using the adapter's stable catalog ids so products do
not appear new merely because a buyer started another discovery session.

The snapshot update runs after discovery and never holds up the buyer response.
That also means a newly connected adapter does not appear in the seller product
list until its first successful wholesale discovery finishes. The snapshot is a
catalog view, not permission to buy: every live buyer request still refreshes
account-specific availability and pricing and receives product ids scoped to
that buyer's provider account.

## What a buyer sees

Composed products are returned in ordinary product discovery. The buyer submits a
brief; the agent returns products (and, where configured, multi-product
**proposals** with budget allocations across them). Each product is priced
server-side and clamped to the `[wholesale floor, seller ceiling]` range, so a
composed price is never below your cost.

Creative delivery is canonical end to end. The composed product exposes the
selected URL-free `format_options[]`; when a buyer pins one with
`format_option_refs[]`, Apostra resolves it back to the exact source option
or direct `format_kind` and `params` selector. Source compatibility adapters may
normalize an older named format at ingestion, but composed products never expose
that source's legacy URL-based format identity.

That source option must still have the same identifier, format kind, parameters,
and publisher scope when the buyer submits the media buy. If the source product
changed after composition, the storefront rejects the stale selection and asks
the buyer to discover the product again. It never substitutes another option
merely because its dimensions look the same.

## Watching it work

Every composition run is observable. Use
[intelligence runs](/v2/storefront/intelligence-runs/overview) to see what the
agent composed for a given brief and why — the inventory it drew on, the rules it
applied, and the rationale behind each product.

## Related

<CardGroup cols={2}>
  <Card title="Operating instructions" href="/v2/storefront/operating-instructions/overview" icon="list-ol">
    The rules the agent follows when composing products — required for composition.
  </Card>

  <Card title="Playbook pricing" href="/v2/storefront/playbook/overview" icon="tags">
    The pricing facts composed products are anchored to.
  </Card>

  <Card title="Intelligence runs" href="/v2/storefront/intelligence-runs/overview" icon="magnifying-glass-chart">
    See what the agent composed for a brief, and why.
  </Card>

  <Card title="Merchandising agent" href="/v2/concepts/storefront-agent" icon="wand-magic-sparkles">
    How the agent turns inventory + rules into a proposal.
  </Card>
</CardGroup>
