Catalog
Publish your catalog
PUT/v1/me/catalogcatalog:write
Publish or update your packages and taxonomy. Every update is integrity-checked at ingest: for each network and week, no two packages in state Available may overlap in days-intersect-time, unless every package in the overlapping set declares the same validated inventory_pool. A violation rejects the whole update with a conflict report, before it can ever produce an order error.
Request body
| Field | Type | Description |
|---|---|---|
taxonomy_version required | string | The version this update publishes, e.g. acme-2026q4-v1. Selling titles are versioned data with effective windows, never enums; orders pin this version. See Selling titles. |
packages[] required | array of object | The packages to publish, full shape at package: type, definition, effective window, currencies, tiers, deal types, and the optional market and inventory_pool declarations. |
pools[] | array of object | Shared capacity pools your packages reference via inventory_pool. Every reference is validated at ingest: the pool must exist on the same network, with a matching unit and an effective window covering the overlapping coverage. |
Example request
PUT /v1/me/catalog
{
"taxonomy_version": "acme-2026q4-v1",
"packages": [
{
"package_id": "acme-prime",
"type": "daypart",
"network": "ACME",
"provider": "National ACME",
"definition": {
"selling_title": "Prime",
"days": ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],
"start": "20:00",
"end": "23:00",
"timezone": "America/New_York",
"sample_programming": ["Gameday Live","Prime Movie","Late Slate"]
},
"effective": { "start": "2026-09-28", "end": "2026-12-27" },
"sm_daypart": "Primetime",
"currencies": ["spots","hh","p2plus","a25_54"],
"guarantee_tiers": ["ng_preemptible","guaranteed","audience_guaranteed"],
"deal_types": ["preemptible","fixed","audience_as_aired","audience_guaranteed"],
"spot_lengths": [15, 30, 60],
"advertiser_classes": ["general","dr","competitive","theatrical"]
}
]
}
Response
The update is atomic: it applies in full or rejects in full. On success the response acknowledges the version now current; buyers see it immediately through catalog reads.
200 Response
{
"taxonomy_version": "acme-2026q4-v1",
"packages_written": 24,
"pools_written": 0,
"integrity_status": "pass"
}
Errors
Error bodies carry the structured shape described in Errors.
| Status | Code | When |
|---|---|---|
| 422 | INVALID_INPUT | Malformed package: an unknown type, a definition missing its selling_title, a bad time or timezone. |
| 409 | DAYPART_CONFLICT | Two Available packages overlap in days-intersect-time for some network and week without sharing a validated pool. The conflict report names the overlapping set; nothing from the update is applied. |
| 409 | DAYPART_CONFLICT | An inventory_pool.pool_id fails validation: missing, expired, cross-network, or unit-incompatible. A dangling reference rejects exactly like an undeclared overlap; a shared label never disables the guard. |
List sellers
GET/v1/sellerscatalog:read
Discovery within your authorized scope: private catalogs your agreements unlock, plus open catalogs.
Response
One entry per seller you can transact with, with its networks, capability level, and catalog location.
200 Response
{
"sellers": [
{
"seller": "acme",
"name": "Acme Broadcasting",
"networks": ["ACME"],
"level": 2,
"catalog_url": "/v1/sellers/acme/catalog"
}
]
}
Read a seller's catalog
GET/v1/sellers/{seller}/catalogcatalog:read
Returns the seller's packages, taxonomy version, deal types, guarantee tiers, and rate class availability. Respects your agreement scope: buyer-scoped (negotiated) packages appear only when your agreement carries them.
Query parameters
| Field | Type | Description |
|---|---|---|
as_of | ISO date | Filter to packages effective on this date. Default: today. |
version | string | Pin to a specific taxonomy_version, e.g. acme-2026q4-v1. |
type | enum | Filter by package type, e.g. ?type=daypart. |
deal_type | enum | Filter to packages supporting a deal type, e.g. ?deal_type=preemptible. |
market | string | Filter by market as scheme:code, e.g. ?market=nielsen_dma:501. Packages with no market are national. |
Example request
GET /v1/sellers/acme/catalog?as_of=2026-10-05
Response
Each entry in packages[] is a package; the field-by-field reference lives there. The interesting parts below: the definition resolves days and local times against the declared timezone, sample_programming lists representative titles (required for ROS and rotator selling titles), and spot_lengths and advertiser_classes bound what a rate card can price.
200 Response
{
"seller": "acme",
"taxonomy_version": "acme-2026q4-v1",
"effective": {
"start": "2026-09-28",
"end": "2026-12-27"
},
"packages": [
{
"package_id": "acme-prime",
"type": "daypart",
"network": "ACME",
"provider": "National ACME",
"definition": {
"selling_title": "Prime",
"days": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
"start": "20:00",
"end": "23:00",
"timezone": "America/New_York",
"sample_programming": ["Gameday Live", "Prime Movie", "Late Slate"]
},
"taxonomy_version": "acme-2026q4-v1",
"effective": {
"start": "2026-09-28",
"end": "2026-12-27"
},
"sm_daypart": "Primetime",
"currencies": ["spots", "hh", "p2plus", "a25_54", "a18_49"],
"guarantee_tiers": ["ng_preemptible", "guaranteed", "audience_guaranteed"],
"deal_types": ["preemptible", "fixed", "audience_as_aired", "audience_guaranteed"],
"spot_lengths": [15, 30, 60],
"advertiser_classes": ["general", "dr", "competitive", "theatrical", "political_candidate_lur", "political_issue"]
}
]
}
Two optional declarations appear when the seller makes them: market ({scheme, code, name, country}) scopes a package to a local market, and inventory_pool ({pool_id, max_per_week}) opts it into a shared pool. A program airing on irregular dates defines itself by occurrences instead of days, start, end:
"definition": {
"selling_title": "Aces Baseball",
"timezone": "America/Chicago",
"occurrences": [
{ "date": "2027-04-09", "start": "18:30", "end": "22:00", "label": "home opener" }
]
}