Three things called “product”
Worth separating before you start, because they behave differently and only one of them is yours to author:
A component is none of these — it is the raw ad-server material (ad units, placements, targeting) you select from when authoring. You never author a component.
If your source is a third-party sales agent rather than a managed one, its products live in that agent and you author them there; Apostra reads them.
How a product gets created
Both paths follow the same server contract, so you see the exact request before anything is saved:- Pick inventory. Choose the ad-server objects to package, such as ad units or placements from your synced inventory. If the package uses GAM key-values for targeting, create signals from that ad-server targeting rather than putting raw key-values in the inventory selector bundle.
- Draft. In Inventory Components, select reviewed components, enter a product name and optional description, and choose the delivery options buyers can use. Each option shows practical details such as media type, dimensions, and video length. Choose the publisher-property coverage this product declares from the options your ad server lists: everything sold under one publisher, specific properties, or specific tags. For a representation network, the publisher shown is the network while its represented sites are the individual properties. When exactly one option is available, the form preselects it; with several, choose the one that covers the product. The Inventory Selector task offers the same form after you pick exact ad-server rows. When you start from Create product in Property Roster, the publisher requirement is already attached and only compatible delivery options are shown. Neither widget sends the selection back into chat.
- Validate. Choose Review product. This checks that the selected inventory can deliver every option before anything is saved and surfaces field-level issues (see What validation surfaces).
- Confirm and create. Choose Create draft product only after validation succeeds. That explicit click saves the exact reviewed request as
draft; it is not visible to buyers until you activate it.
FreeWheel products need an Ad Unit or Ad Unit Package
Choose at least one Ad Unit, Ad Unit Package, or a combination of both to identify the FreeWheel delivery opportunities for a product. Content scope, such as a site, site group, series, or video group, is a separate optional selection. Content scope alone cannot receive creatives. Inventory Components follows the selection rule returned by the connected FreeWheel source. It lists the direct ad units and packages that source makes available, so a network can work with either inventory model without a seller-specific setting. If neither type has eligible inventory, the form says so and blocks review. A failed inventory request produces a separate retryable error and also blocks review. Google Ad Manager, SpringServe, and other adapters do not show or require this FreeWheel field.Edit an existing product
In Inventory Components → Products, choose Edit to load the complete product definition before changing it. The editor shows the channels and delivery type, every canonical format option with its parameters (including dimensions and duration), the inventory selectors and placements, targeting capabilities, video placement types, and every pricing option with its model, rate or floor, currency, and delivery type. Choose Save changes to validate the complete product first. Any blocking problem names the field and how to correct it; nothing is saved until validation passes. The save then changes only the fields you edited, so a name or status update cannot clear pricing, coverage, formats, placements, or targeting that you left unchanged. Blank ornull JSON does not mean “clear”: correct it to a valid value or cancel to retain the original value. Delivery type can be changed only to a supported value; it cannot be cleared because the source PATCH contract has no clearing value. Product IDs, timestamps, source-owned permissions, and any other source-managed fields remain visible but are explicitly read-only in this screen.
Legacy FreeWheel products that do not meet the source’s current selection rule
can still be renamed, described, activated, or archived. Changing their
inventory is a repair: retain the publisher properties separately and add a
current FreeWheel Ad Unit or Ad Unit Package under
inventory.execution.selectors before saving.
Buyer-facing AdCP compatibility
Author products with canonical delivery options. Inventory-feed payloads useformatOptions[]; the corresponding AdCP 3.1 buyer response uses
format_options[], with a stable format_option_id, a format_kind, and any
format-specific params.
Storefront negotiates the response for the buyer’s AdCP version:
- AdCP 3.1 clients receive the canonical
format_options[]declarations. - AdCP 3.0 clients receive the required legacy
format_ids[]projection when the seller has published a valid mapping for the canonical option. - If a canonical option cannot be projected safely, validation fails closed; Storefront does not invent a legacy format identity.
ext.scope3.storefront. Integrations that previously read
extensions.scope3.storefront must move to the ext path. Demo responses use
ext.scope3.storefront.demo and
ext.scope3.storefront.demo_disclosure; see Demo Storefront.
Make a product ready for proposals
The proposal composer can pitch an active product only when it has a channel, a canonical URL-free format, and a priced option with a currency and delivery type.save_wholesale_product accepts channels when you need to set that
fact yourself. Use the same AdCP channel codes the storefront uses, such as
display, olv, ctv, and streaming_audio.
For a managed source that returns no channel, Apostra infers a channel only
when its canonical creative format maps to exactly one composer-compatible
channel. Ambiguous formats, including common video and audio formats, remain
unclassified so you can state the intended channels yourself. Your non-empty
channels declaration always wins over that fallback.
For GAM, this means video_vast, image, and html5 always need explicit
channels: each is compatible with several composer channels, so inferring one
would guess at the commercial placement. This fail-closed rule is intentional.
Pricing coverage alone is not a price the composer can quote. A positive fixed
price or platform-derived floor with its pricing-option ID, pricing model, ISO
currency, and guaranteed or non_guaranteed delivery type is quoteable. A
bare non-fixed rate without a fixed price or floor is not quoteable. The
product read reports any remaining request-independent
composerCompleteness.missing facts beside pricingStatus, so a
source-reported priced status cannot hide a product that still lacks a
quoteable option. A particular RFP also needs a price in its requested currency.
If GAM shows only the network
A connected Google Ad Manager source should expose the selector types and inventory rows that its sync can read, such as ad units, placements, and custom targeting. Seeing only the GAM network, with no selectable inventory below it, is not a completed product-setup state. It does not mean you must first invent title or geography keys.- Confirm the source sync has completed and open its Health or diagnostics view.
- Check that Apostra service account still has GAM inventory read access.
- Inspect the source’s advertised selector capabilities. A selector type can be absent because GAM does not expose it for that network or because the integration does not support it; an advertised type with no rows is a sync or product defect.
- If the source is healthy but still exposes no inventory rows, contact Apostra with the source ID, last sync time, missing selector type, and a screenshot. Do not work around it by creating unsupported targeting keys.
What validation surfaces
Validation (and preview) returns two kinds of findings:- Blocking problems that stop the product from being valid — for example a creative format your ad server doesn’t recognize. Fix these before creating.
- Advisory warnings that never block creating the product, but flag a gap worth closing:
- A declared property wasn’t found. You named a specific property (by id or tag) that isn’t in the registry or on the publisher’s
adagents.json— usually a typo. The check skips a publisher that exposes no property list yet (not-yet-crawled), so valid-but-unindexed inventory isn’t flagged. - Publisher hasn’t authorized your agent. A declared publisher’s
adagents.jsondoesn’t list your storefront’s sales agent. The product still authors fine; treat the warning as a publisher-owned authorization gap to fix before depending on that inventory. The check reads the publisher’s liveadagents.json, so a publisher that simply hasn’t been crawled yet is not flagged. - Publisher format needs attention. The selected format may be missing or changed in the latest catalog, the catalog may be unavailable or stale, or its property scope may not cover the selected publisher properties. The product task adds the selected publisher format and property scope automatically so validation can flag these gaps.
- A declared property wasn’t found. You named a specific property (by id or tag) that isn’t in the registry or on the publisher’s
all coverage option, even when no individual properties are listed yet. Specific property ids and tags appear only when your ad server supplies them. If the task offers no coverage options, the source has not supplied any publishers; refresh the source and check its publisher setup. A publisher’s adagents.json status does not limit which listed coverage options you can use to author a product.
Creating several products at once
When you have a set of products to add, for example a spreadsheet of ad units, you do not have to approve them one by one. The agent validates and previews each draft, then creates the whole set after a single approval.- Drop a spreadsheet into the chat. Attach a CSV or spreadsheet of products and the agent maps the rows into drafts, validates them, and proposes the batch.
- One approval for the batch. You approve the full set once rather than per product.
- It keeps going if one fails. Bulk creation continues on error: if one product can’t be created, the rest still are. At the end you get a clear per-product result showing which products were created and which failed, with the reason, so you can re-run just the ones that need attention.
- “Set up my initial products for me.”
- “Take a crack at my first cut.”
- “Here is a list of sections and ad units; bulk create products from it.”
Updating several products at once
When you need to change a set of products, for example fixing the ones that failed during a batch create or adjusting pricing across a slate, you do not have to approve each edit one at a time. The agent applies all patches after a single approval.- Describe the changes in chat. Tell the agent which products to update and what to change. You can paste a list or describe the edits; the agent maps them to the matching products and shows you what will change before asking for approval.
- One approval for the batch. You approve the full set of updates once rather than per product.
- It keeps going if one fails. Bulk updates continue on error: if one product can’t be updated, the rest still are. At the end you get a clear per-product result showing which products were updated and which failed, with the reason, so you can re-run just the ones that need attention.
Product status
Every product has a status:
Inventory Components and Inventory Selector create new products as
draft so you can review them before activation. In chat, state whether you want a draft or an active product; the confirmation shows the exact status before the write.
Retiring a product
Two endings, and only one of them can be walked back:
Archive first. Archiving is the normal way to stop offering something and is
enough for almost every case: a seasonal package, a product you are reworking,
inventory you are not selling this quarter. Delete only when you want the
product gone for good, and archive it first — deleting an
active product takes
it out from under buyers who can discover and buy it right now, and there is no
undo. A draft was never offered to anyone, so it can go directly.
Because the step cannot be reversed, confirm the exact product before you ask
for it: name, not just id. Deleting the wrong product is not something a retry
fixes.
Deleting a product does not touch your ad-server inventory. The ad units,
placements, and targeting you packaged stay in your ad server exactly as they
were: you are removing the product you authored, not the material it was built
from. To sell that inventory again, author a new product from the same
components — it comes back with a new id, not the one you deleted.
GAM key-value signal targeting
GAM key-value targeting is supported through signals, not as raw product selector fields. For simple one-key mappings, browse thecustom_targeting_key and custom_targeting_value ad-server targeting types
and create a custom_key_value signal. For composite logic, create a
gam_targeting_groups signal: groups are OR’d
together, criteria inside a group are AND’d together, and multiple values in one
criterion are OR’d by GAM for that key.
Before answering whether a source supports key-value targeting, read the
source’s signal capabilities. A GAM-backed ad server source can advertise
mappingKinds[].mappingKind: "gam_targeting_groups" and API targeting types such
as custom_targeting_key and custom_targeting_value. If those capabilities
are present, tell the operator that key-value targeting is supported through
signals, then validate and create the signal.
Property and tag mappings
Some large networks map each publisher property or site in GAM with key-values instead of breaking out placements or ad units per property. Sellers can now author and preview those source-scoped mappings, including tag-based mappings, through the property and tag mapping task. This authoring slice records the seller’s execution address. It does not replacepublisher_properties, grant publisher authorization, or claim that downstream
media-buy execution consumes the mapping yet.
Do not use GAM key-values as a substitute for publisher_properties, and do
not describe a mapping as proof of which properties a product sells. Use
key-values for source targeting where the source capabilities support it; use
ad units, placements, or declared publisher properties for the product’s
inventory and property definition.
See Ad-server signals for the
gam_targeting_groups request shape and validation flow.
Related
Inventory sources overview
How sources sync inventory you can package
Ad-server access
What each ad server asks for, and why
Source diagnostics
Check sync health before packaging
Storefront onboarding
End-to-end seller setup