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
| Field | Type | Description |
|---|---|---|
as_of required | ISO datetime | When this batch was true in your system. Applies to every entry; echoed to buyers on every read. |
entries[] required | array of object | The avail entries to write. Fields below. |
entries[]
| Field | Type | Description |
|---|---|---|
package_id required | string | The package the entry speaks for. |
week required | ISO week | The air week, e.g. 2026-W41. |
grain | enum | week 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. |
date | ISO date | Required at date grain: the slot's air date. Omit at week grain. |
slot_id | string | Set with date at date grain: {package_id}:{date}, e.g. acme-prime:2026-10-07. |
state required | enum | One of the avail states. |
basis required | enum | actual or projected: whether the figures come from live inventory data or a forward projection. |
spots.available required | integer | Units 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 required | integer | Total units at this grain. |
pool | object | Optional echo on a pooled package: pool.pool_id and pool.remaining. See shared pools. |
impressions | object | source (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_level | number | 0.0 (empty) to 1.0 (sold out). |
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.
| Status | Code | When |
|---|---|---|
| 422 | INVALID_INPUT | Malformed entry: a bad state value, a date-grain entry missing its date, a week that is not an ISO week. |
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.
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
| Field | Type | Description |
|---|---|---|
package_id required | string | Repeatable. One or more package ids: ?package_id=acme-prime&package_id=acme-news. |
weeks required | ISO week | Repeatable. The air weeks to check: ?weeks=2026-W41&weeks=2026-W42. |
audiences | enum | Repeatable. Request audience codes beyond the defaults. Default: hh, p2plus, and a25_54 are always returned. |
rate_class | enum | Filter the returned rate lines to one market class, e.g. ?rate_class=remnant. |
spot_length | integer | Filter the returned rate lines to a creative length in seconds, e.g. ?spot_length=30. |
market | string | Filter 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
}
}
]
}
]
}
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.