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

Avails

Push availability

PUT/v1/me/availscatalog:write

Push availability with impression estimates per audience. Updates are batched and partial: only the packages and weeks you include are updated, others are unchanged.

Request body

FieldTypeDescription
as_of requiredISO datetimeWhen this batch was true in your system. Applies to every entry; echoed to buyers on every read.
entries[] requiredarray of objectThe avail entries to write. Fields below.

entries[]

FieldTypeDescription
package_id requiredstringThe package the entry speaks for.
week requiredISO weekThe air week, e.g. 2026-W41.
grainenumweek or date. Default: week. A week-grain entry states availability for the whole week at your own precision; a date-grain entry speaks for one slot.
dateISO dateRequired at date grain: the slot's air date. Omit at week grain.
slot_idstringSet with date at date grain: {package_id}:{date}, e.g. acme-prime:2026-10-07.
state requiredenumOne of the avail states.
basis requiredenumactual or projected: whether the figures come from live inventory data or a forward projection.
spots.available requiredintegerUnits available at this grain. On a pooled package, report the smaller of the package's remaining cap and the pool's remaining capacity.
spots.total requiredintegerTotal units at this grain.
poolobjectOptional echo on a pooled package: pool.pool_id and pool.remaining. See shared pools.
impressionsobjectsource (the measurement basis, e.g. nielsen, comscore, seller_model) and stream (the measurement stream the figures are read on: c3, c7, live_sd) declared once, alongside one key per audience code carrying per_spot, the gross estimated delivery per spot.
sellout_levelnumber0.0 (empty) to 1.0 (sold out).
The write payload is a batch envelope: as_of is declared once per batch and source/stream once per entry. Reads return the normalized avail form, echoing as_of on every entry and source and stream on every impression figure.

Example request

PUT /v1/me/avails

{
  "as_of": "2026-10-01T08:00:00Z",
  "entries": [
    {
      "package_id": "acme-prime",
      "week": "2026-W41",
      "grain": "week",
      "state": "available",
      "basis": "actual",
      "sellout_level": 0.62,
      "spots": { "available": 42, "total": 80 },
      "impressions": {
        "source": "nielsen",
        "stream": "c3",
        "hh":     { "per_spot": 128000 },
        "p2plus": { "per_spot": 195000 },
        "a25_54": { "per_spot":  82000 }
      }
    }
  ]
}

Response

The response acknowledges the batch and echoes its as_of. warnings lists non-fatal issues, e.g. a week in the past or an unknown package_id; warned entries are skipped, the rest are written.

200 Response
{
  "entries_written": 1,
  "as_of": "2026-10-01T08:00:00Z",
  "warnings": []
}

Errors

Error bodies carry the structured shape described in Errors.

StatusCodeWhen
422INVALID_INPUTMalformed entry: a bad state value, a date-grain entry missing its date, a week that is not an ISO week.
Impression figures are seller-declared estimates, not guarantees. The source field records the measurement basis so buyers can weight them appropriately. Audience-guaranteed orders settle on the agreed currency, not on these avail estimates.

Read availability

GET/v1/sellers/{seller}/availscatalog:read

Returns availability and impression estimates for requested packages and weeks. Entries come back at the seller's declared grain: a week-grain entry states availability for every slot in that week at the seller's own precision, a date-grain seller returns one entry per slot, adding date and slot_id. An avail entry is not a guarantee of clearance; confirmed availability is established at order validation.

This endpoint answers inline only for packages whose avails_policy is published (as resolved for you, after any agreement override). A package set to on_request returns 202 with a request resource to poll; one set to withheld returns 409 AVAILS_WITHHELD. The async contract is below.

Query parameters

FieldTypeDescription
package_id requiredstringRepeatable. One or more package ids: ?package_id=acme-prime&package_id=acme-news.
weeks requiredISO weekRepeatable. The air weeks to check: ?weeks=2026-W41&weeks=2026-W42.
audiencesenumRepeatable. Request audience codes beyond the defaults. Default: hh, p2plus, and a25_54 are always returned.
rate_classenumFilter the returned rate lines to one market class, e.g. ?rate_class=remnant.
spot_lengthintegerFilter the returned rate lines to a creative length in seconds, e.g. ?spot_length=30.
marketstringFilter to packages in a market as scheme:code, e.g. ?market=nielsen_dma:501.

Example request

GET /v1/sellers/acme/avails?package_id=acme-prime&weeks=2026-W41

Response

Each entry is an avail: a state, its basis and sellout_level, unit counts, per-audience impression estimates, and the rate lines that apply, each carrying the locked_rate_id your order references under the price-clearance invariant. A projected entry is quotable but not firmly clearable: orders against it validate at submission, and INVENTORY_UNAVAILABLE is possible if actuals differ when they land. On a pooled package, spots.available is the smaller of the package's remaining cap and the pool's remaining capacity, and the entry may echo pool ({pool_id, remaining}). Remnant and opportunistic rate lines add a window (the standing remnant cadence closes Monday 9:00A ET of the air week) and an optional signal payload agents can trigger on.

200 Response
{
  "seller": "acme",
  "avails": [
    {
      "package_id": "acme-prime",
      "week": "2026-W41",
      "grain": "week",
      "state": "available",
      "basis": "actual",
      "as_of": "2026-10-01T08:00:00Z",
      "sellout_level": 0.62,
      "spots": {
        "available": 42,
        "total": 80
      },
      "impressions": {
        "hh": {
          "per_spot": 128000,
          "total_avail": 5376000,
          "source": "nielsen",
          "stream": "c3"
        },
        "p2plus": {
          "per_spot": 195000,
          "total_avail": 8190000,
          "source": "nielsen",
          "stream": "c3"
        },
        "a25_54": {
          "per_spot": 82000,
          "total_avail": 3444000,
          "source": "nielsen",
          "stream": "c3"
        }
      },
      "rates": [
        {
          "class": "scatter",
          "advertiser_class": "general",
          "spot_length": 30,
          "guarantee_tier": "ng_preemptible",
          "clearance_tier": "P2",
          "gross_rate_unit": 405.00,
          "gross_rate_weekly": 4050.00,
          "locked_rate_id": "lr_88c1",
          "currency": "USD"
        },
        {
          "class": "remnant",
          "advertiser_class": "general",
          "spot_length": 30,
          "guarantee_tier": "ng_preemptible",
          "clearance_tier": "P3",
          "gross_rate_unit": 260.00,
          "locked_rate_id": "lr_f2a9",
          "currency": "USD",
          "window": {
            "opens": "2026-09-22T00:00:00Z",
            "closes": "2026-09-28T13:00:00Z"
          },
          "signal": {
            "sellout_pressure": "low",
            "expected_volume_pct": -0.30
          }
        }
      ]
    }
  ]
}
Check availability twice. Plan against cached avails, then re-request exactly the packages and weeks you are about to order immediately before POST /orders: a narrow re-check catches inventory that moved since planning and cuts rejections at the source. Validation's INVENTORY_UNAVAILABLE remains the backstop for the residual race between the re-check and the order.

On-request and withheld avails

When a package's resolved avails_policy is not published, the read does not answer inline:

on_request. The call returns 202 Accepted with a Location header and a correlation id; the seller answers asynchronously, possibly coarsened. Discover the answer two ways (hints, then the authoritative resource): an avails.answered event carrying the same avails_request_id, or poll the request resource. Auth is catalog:read, same as the feed.

202 Accepted
Location: /v1/sellers/acme/avails/requests/avr_6c1d90
{
  "avails_request_id": "avr_6c1d90",
  "status": "pending",
  "expires_at": "2026-10-01T20:00:00Z"
}

GET/v1/sellers/{seller}/avails/requests/{id}catalog:read

Poll the request. status is pending, answered, declined (the seller will not answer; next points to the proposal path), or expired (no answer by expires_at). When answered, avails[] is the same shape the published feed returns, at the seller's chosen precision.

200 Response : answered
{
  "avails_request_id": "avr_6c1d90",
  "status": "answered",
  "as_of": "2026-10-01T18:30:00Z",
  "avails": [
    { "package_id": "acme-prime", "week": "2026-W41", "grain": "week",
      "state": "available", "basis": "actual", "sellout_level": 0.7,
      "spots": { "available": 20, "total": 80 } }
  ]
}

200 Response : declined
{
  "avails_request_id": "avr_6c1d90",
  "status": "declined",
  "next": { "path": "/v1/orders", "deal_type": "proposal" }
}

withheld. The read returns 409 AVAILS_WITHHELD; the body's next points to the proposal path. Availability resolves inside the plan or at seller review, never here.