← Back to product·Simulmedia Switchboard Docs · v1 draft·API reference / Catalog
API reference

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

FieldTypeDescription
taxonomy_version requiredstringThe 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[] requiredarray of objectThe 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 objectShared 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.

StatusCodeWhen
422INVALID_INPUTMalformed package: an unknown type, a definition missing its selling_title, a bad time or timezone.
409DAYPART_CONFLICTTwo 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.
409DAYPART_CONFLICTAn 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.
Publishing for the first time? Publish your catalog walks the full flow: packages, rate card, first avails push.

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

FieldTypeDescription
as_ofISO dateFilter to packages effective on this date. Default: today.
versionstringPin to a specific taxonomy_version, e.g. acme-2026q4-v1.
typeenumFilter by package type, e.g. ?type=daypart.
deal_typeenumFilter to packages supporting a deal type, e.g. ?deal_type=preemptible.
marketstringFilter 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" }
  ]
}