Jordan is staring at a spreadsheet. A holding company just sent Nova Motors’ CTV “do not air” list — 200+ programs organized by network, a mix of specific shows, entire genres, and content ratings. Some entries are app-level exclusions. Some are individual programs that air on five different platforms. One section says “ALWAYS EXCLUDE kids programming” and three rows later says “animation rated G or PG is permitted.”
This spreadsheet makes sense to a human trafficking linear TV. It does not make sense to an AI agent managing programmatic CTV across a dozen sellers.
Jordan needs to turn this into something machines can enforce. Property lists handle the app-level exclusions — she’s done that before. But the program-level exclusions? A show doesn’t belong to a single app. It airs everywhere. She needs a construct that identifies the program itself, independent of where it runs.
That’s what collection lists are for.
The gap in brand safety
Before collection lists, AdCP had two brand safety layers:
- Property lists control where ads run — which apps, sites, and platforms. Jordan can say “not on this news app” and every seller enforces it.
- Content standards control what content is adjacent to an ad — per-impression evaluation against a natural language policy. They handle nuance like “exclude kids content except G/PG animation.”
Most buyers use one or two layers. A buyer who only needs to exclude specific programs uses a collection list alone. The three-layer model is a composition framework, not a requirement.
Resolving program identifiers
The spreadsheet lists programs by name. Machines need identifiers. Jordan’s buyer agent resolves each program name to a platform-independent distribution identifier — an IMDb ID, Gracenote ID, or EIDR ID that uniquely identifies the program regardless of which CTV platform carries it.
Most programs resolve immediately. A few don’t — the agent flags these for Jordan to confirm manually. This is the translation step: human-readable names become machine-readable identifiers that every seller in the ecosystem understands.
Gracenote ID guidance: Use root-level IDs — SH-prefixed for series, MV-prefixed for movies, SP-prefixed for sports programs. Episode-level IDs (EP-prefixed) don’t belong in collection lists; episode-level evaluation is a content standards concern.
Building the collection list
Jordan’s buyer agent creates a collection list on the governance agent, combining explicit program exclusions with structural filters:
How filters compose
Include filters are allowlists, exclude filters are blocklists. When both are present for the same dimension, include applies first, then exclude narrows further. Example:genres_include: ["drama", "comedy"] + genres_exclude: ["crime"] first includes only drama and comedy collections, then removes any also tagged as crime. A collection tagged ["drama", "crime"] is excluded — the exclude filter wins.
Sellers match against their inventory
When Jordan’s media buy references the collection list, Priya’s sales agent at StreamHaus fetches it, matches entries against StreamHaus’s collection inventory, and excludes matched programs from delivery. The matching uses distribution identifiers — StreamHaus declared Gracenote IDs on their collections in adagents.json, so the match is automatic.
Priya’s agent reports back: 47 of 200 excluded programs are in StreamHaus’s library. 12 additional collections caught by the TV-MA filter. The rest aren’t programs StreamHaus carries — acknowledged and ignored.
The list is cached for a week (collection metadata changes less frequently than property metadata). When the governance agent re-resolves the list — a new season changes a show’s content rating, or Jordan adds programs — sellers receive a webhook and refresh their cache.
Targeting integration
Collection lists are referenced in targeting overlays alongside property lists:
A media buy can reference both simultaneously — “run in these approved shows, but never in these specific programs even if they appear on the approved list.” The exclude list always wins on overlap.
Why two fields for collections but one for properties? Property lists predate the paired include/exclude pattern now used across other targeting dimensions (geo, audience, device). Collection lists follow the current pattern. A future evolution may add
property_list_exclude for symmetry.Jordan’s three-layer configuration
By the time Jordan is done, Nova Motors’ CTV brand safety is expressed in three machine-readable artifacts:- Property list — excluded apps and approved CTV platforms
- Collection list — excluded programs by distribution identifier + TV-MA and news genre filters
- Content standards — the nuanced kids/animation policy that requires per-episode judgment
Relationship to property lists
Property lists and collection lists are sibling constructs — both are inventory lists managed by governance agents with the same lifecycle pattern (create, get, update, list, delete, webhook). They differ in what they address:Tasks
Collection list management
- create_collection_list: Create a new collection list on a governance agent
- get_collection_list: Retrieve resolved collections (with caching guidance)
- update_collection_list: Modify filters or base collections
- list_collection_lists: List collection lists for an account
- delete_collection_list: Remove a collection list