Skip to content

Commit 946c962

Browse files
bokelleyclaude
andauthored
feat: show selectors on products with creator-as-registry (#1550)
* feat: move shows from response-level to product-level selectors Shows on products are now `shows: ShowSelector[]` where each selector references shows declared in an external adagents.json by domain and show ID. This enables show creators (e.g., MrBeast) to serve as canonical registries — any seller can reference their shows, giving buyers stable identity across sellers and platforms. Breaking changes: - Product field `show_ids` (string[]) replaced by `shows` (ShowSelector[]) - Top-level `shows` array removed from get_products response - Buyers resolve show objects from adagents.json instead of the response New fields: - `show_targeting_allowed` on products (default false = bundle) - `enforced_policies` added to fields projection enum Also fixes ISO duration parsing bug in training agent episode generation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: add empty changeset for CI Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 1970888 commit 946c962

17 files changed

Lines changed: 174 additions & 338 deletions

File tree

.changeset/tidy-geese-joke.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
---
2+
---

docs/guides/seller-integration.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ For content-centric inventory like podcasts, CTV, or live events, products refer
9292
"product_id": "signal_noise_sponsorship",
9393
"name": "Signal & Noise — Category Sponsorship",
9494
"description": "Category-exclusive sponsorship of the Signal & Noise podcast, including pre-roll and mid-roll host read placements.",
95-
"show_ids": ["signal_noise"],
95+
"shows": [{ "publisher_domain": "crestnetwork.example.com", "show_ids": ["signal_noise"] }],
9696
"publisher_properties": ["crestnetwork_podcast"],
9797
"channels": ["podcast"],
9898
"placements": [
@@ -172,9 +172,9 @@ Different inventory types use different AdCP features:
172172
| Inventory type | Key features |
173173
|---|---|
174174
| Standard display/video | `format_ids`, `delivery_type: "non_guaranteed"`, auction pricing |
175-
| Podcast sponsorship | `show_ids`, `placements` (host read), `delivery_type: "guaranteed"`, flat_rate |
176-
| CTV series sponsorship | `show_ids`, `exclusivity`, `delivery_type: "guaranteed"` |
177-
| Live event | `show_ids` (cadence: event), `episodes` (flexible_end, tentative), `exclusivity` |
175+
| Podcast sponsorship | `shows`, `placements` (host read), `delivery_type: "guaranteed"`, flat_rate |
176+
| CTV series sponsorship | `shows`, `exclusivity`, `delivery_type: "guaranteed"` |
177+
| Live event | `shows` (cadence: event), `episodes` (flexible_end, tentative), `exclusivity` |
178178
| Retail media | `catalog_types`, `catalog_match`, metric optimization |
179179

180180
For content-centric inventory, see [Shows and episodes](/docs/media-buy/product-discovery/shows-and-episodes). For exclusivity and sponsorship patterns, see [Media products](/docs/media-buy/product-discovery/media-products#exclusivity).

docs/media-buy/product-discovery/index.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Products describe sellable inventory along three independent dimensions:
6060
- **Shows and episodes** — WHAT CONTENT the ad runs in or around (a series, podcast, or live event)
6161
- **Placements** — WHAT POSITION the ad appears in (pre-roll, mid-roll, host read)
6262

63-
Each product also includes audience targeting, creative format requirements, pricing, and delivery characteristics. When products reference shows, the `get_products` response includes a top-level `shows` array with full show metadata (talent, genre, content ratings, distribution identifiers).
63+
Each product also includes audience targeting, creative format requirements, pricing, and delivery characteristics. When products reference shows, buyers resolve full show metadata (talent, genre, content ratings, distribution identifiers) from the show creator's or publisher's `adagents.json`.
6464

6565
Understand the complete product structure in [Media Products](/docs/media-buy/product-discovery/media-products). For show-centric inventory like podcasts, CTV series, and live events, see [Shows and Episodes](/docs/media-buy/product-discovery/shows-and-episodes).
6666

docs/media-buy/product-discovery/media-products.mdx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Products declare which pricing models they support. Buyers select a specific pri
2121
- `channels` (list[string], optional): Advertising channels this product is sold as (e.g., `["retail_media"]`, `["display", "olv"]`). Sellers SHOULD declare `channels` on products that span non-obvious channels, particularly retail media, CTV/OLV, and multi-channel bundles. Product channels SHOULD be a subset of the union of their properties' `supported_channels`. See [Media Channel Taxonomy](/docs/reference/media-channel-taxonomy).
2222
- `format_ids` (list[FormatID], required): Structured format ID references. See [Creative Formats](/docs/creative/formats).
2323
- `placements` (list[Placement], optional): Specific ad placements within this product. When provided, buyers can target individual placements when assigning creatives. See [Placements](#placements).
24-
- `show_ids` (list[string], optional): Show IDs available within this product. When provided, buyers can target specific shows. See [Shows and episodes](/docs/media-buy/product-discovery/shows-and-episodes).
24+
- `shows` (list[ShowSelector], optional): Shows covered by this product, grouped by publisher. Each entry has `publisher_domain` and `show_ids` referencing shows in the publisher's `adagents.json`. See [Shows and episodes](/docs/media-buy/product-discovery/shows-and-episodes).
2525
- `episodes` (list[Episode], optional): Specific episodes available within this product. See [Shows and episodes](/docs/media-buy/product-discovery/shows-and-episodes).
2626
- `delivery_type` (string, required): Either `"guaranteed"` or `"non_guaranteed"`.
2727
- `exclusivity` (string, optional): Whether this product offers exclusive access. `"none"` (default when absent) — multiple advertisers can buy simultaneously. `"category"` — one advertiser per industry category. `"exclusive"` — sole sponsorship. Most relevant for guaranteed products tied to specific shows or placements.
@@ -32,6 +32,7 @@ Products declare which pricing models they support. Buyers select a specific pri
3232
- `is_custom` (bool, optional): `true` if the product was generated for a specific brief.
3333
- `expires_at` (datetime, optional): If `is_custom`, the time the product is no longer valid.
3434
- `property_targeting_allowed` (bool, optional, default: false): Whether buyers can filter this product to a subset of its `publisher_properties`. When `false` (default), the product is "all or nothing" - buyers must accept all properties or the product is excluded from `property_list` filtering results. See [Property Targeting](#property-targeting).
35+
- `show_targeting_allowed` (bool, optional, default: false): Whether buyers can target a subset of this product's `shows`. When `false` (default), the product is a bundle — buyers get all listed shows. When `true`, buyers can select specific shows in the media buy.
3536
- `catalog_types` (list[string], optional): Catalog types this product supports for catalog-driven campaigns. A sponsored product listing declares `["product"]`, a job board declares `["job", "offering"]`. Buyers match synced catalogs to products via this field. See [Catalogs](/docs/creative/catalogs).
3637
- `catalog_match` (object, optional): When the buyer provides a `catalog` on `get_products`, indicates which catalog items are eligible for this product. Contains `matched_gtins` (cross-retailer GTIN matches), `matched_ids` (generic item ID matches), `matched_count`, and `submitted_count`.
3738
- `metric_optimization` (object, optional): Metric optimization capabilities for this product. Presence indicates the product supports `optimization_goals` with `kind: "metric"`. See [Metric optimization](#metric-optimization).
@@ -252,7 +253,7 @@ See [Creative Assignment and Placement Targeting](/docs/media-buy/media-buys/ind
252253

253254
### Shows and episodes
254255

255-
Shows are a third product dimension alongside formats and placements. While placements describe *where* an ad appears and formats describe *what* the ad looks like, shows describe the *content context* — the programming a viewer is watching. Products can declare `show_ids` and `episodes` so buyers can target specific shows or episodes when purchasing inventory.
256+
Shows are a third product dimension alongside formats and placements. While placements describe *where* an ad appears and formats describe *what* the ad looks like, shows describe the *content context* — the programming a viewer is watching. Products can declare `shows` and `episodes` so buyers can target specific shows or episodes when purchasing inventory.
256257

257258
See [Shows and episodes](/docs/media-buy/product-discovery/shows-and-episodes) for the full model, examples, and targeting details.
258259

@@ -274,11 +275,11 @@ Exclusivity is most relevant for guaranteed products tied to specific shows or p
274275
- **`category`**: Podcast or CTV sponsorships where competitive separation matters. One auto brand per show, one fintech brand per episode — but multiple non-competing advertisers can buy simultaneously.
275276
- **`exclusive`**: Sole sponsorship of a single show or event. The advertiser is the only brand associated with the content.
276277

277-
Publishers SHOULD include `exclusivity` on guaranteed products with `show_ids`. The implicit default of `"none"` is ambiguous for show-level inventory — buyers cannot tell whether the publisher intends shared inventory or simply omitted the field.
278+
Publishers SHOULD include `exclusivity` on guaranteed products with `shows`. The implicit default of `"none"` is ambiguous for show-level inventory — buyers cannot tell whether the publisher intends shared inventory or simply omitted the field.
278279

279280
#### Content sponsorship pattern
280281

281-
A product combining `delivery_type: "guaranteed"`, `exclusivity: "exclusive"`, and `show_ids` represents a content sponsorship — the advertiser becomes the sole sponsor of specific content. This is the standard pattern for podcast title sponsorships, CTV show sponsorships, and event-based takeovers.
282+
A product combining `delivery_type: "guaranteed"`, `exclusivity: "exclusive"`, and `shows` represents a content sponsorship — the advertiser becomes the sole sponsor of specific content. This is the standard pattern for podcast title sponsorships, CTV show sponsorships, and event-based takeovers.
282283

283284
```json
284285
{
@@ -292,7 +293,7 @@ A product combining `delivery_type: "guaranteed"`, `exclusivity: "exclusive"`, a
292293
{ "agent_url": "https://ads.crestnetwork.example", "id": "audio_pre_roll_30s" },
293294
{ "agent_url": "https://ads.crestnetwork.example", "id": "audio_mid_roll_60s" }
294295
],
295-
"show_ids": ["signal_noise"],
296+
"shows": [{ "publisher_domain": "crestnetwork.example", "show_ids": ["signal_noise"] }],
296297
"delivery_type": "guaranteed",
297298
"exclusivity": "exclusive",
298299
"pricing_options": [
@@ -320,7 +321,7 @@ Category exclusivity works for multi-show bundles where the publisher separates
320321
{ "agent_url": "https://ads.crestnetwork.example", "id": "audio_pre_roll_30s" },
321322
{ "agent_url": "https://ads.crestnetwork.example", "id": "audio_mid_roll_60s" }
322323
],
323-
"show_ids": ["signal_noise", "market_beat", "founder_stories"],
324+
"shows": [{ "publisher_domain": "crestnetwork.example", "show_ids": ["signal_noise", "market_beat", "founder_stories"] }],
324325
"delivery_type": "guaranteed",
325326
"exclusivity": "category",
326327
"pricing_options": [

0 commit comments

Comments
 (0)