Rates
Publish rate cards
PUT/v1/me/rate-cardscatalog:write
Publish a versioned rate card commit. Entries are live for buyers the moment the commit lands, and drift detection runs on every commit: buyers with in-flight orders referencing the superseded version receive catalog.stale_rate_card events with a per-line diff. See Rates for how entries resolve and the price-clearance invariant for what the version pin buys you.
Request body
| Field | Type | Description |
|---|---|---|
commit required | string | Your id for this card version, e.g. acme-2026q4-v2. Orders pin it as rate_version. |
supersedes | string | The commit this one replaces. Drift diffs are computed against it. |
effective.start required | ISO date | First day the card applies. |
effective.end required | ISO date | Last day the card applies. |
currency required | ISO 4217 | The trade currency: one per commit, echoed on every entry by read surfaces, locked into an order with its rates, carried and never converted. |
agreement_scope | string | Default: null, an open card. Set an agreement id to publish a buyer-scoped card; negotiated rates and quotes live on these. |
commit_kind | enum | standing (default) or quote. A quote commit is a per-campaign price minted inside a plan; it requires agreement_scope and quote_expires_at, and locks under the price-clearance invariant on confirm. See Disclosure. |
quote_expires_at | ISO datetime | Required on quote commits. After it, the entries are a stale card (STALE_RATE_CARD): the buyer re-requests, nothing books at a lapsed price. |
proposal_ref | string | On quote commits: the proposal order this quote answers. |
entries[] required | array of object | The rate entries. Fields below. |
entries[]
| Field | Type | Description |
|---|---|---|
package_id required | string | The package the rate prices. Must exist in your published catalog. |
week | ISO week | Omit for a rate that holds across the effective window; set it to price a single week. |
advertiser_class required | enum | One of your declared advertiser classes. |
spot_length required | integer | Creative length in seconds. |
guarantee_tier required | enum | One of the guarantee tiers. |
clearance_tier required | enum | One of the clearance tiers. |
class required | enum | One of the market classes, the entry's market timing. |
gross_rate_unit | number | Gross rate for one unit at this spot_length. Set per-length rates or cost_per_second, not both. |
gross_rate_weekly | number | Gross rate for a full week of units. Stated by you, never back-computed from gross_rate_unit. |
rate_basis | string | Set to cost_per_second to price per second instead of per length. |
cost_per_second | number | Per-second gross rate; requires rate_basis: cost_per_second. The unit cost resolves as cost_per_second x spot_length at order time. |
Example request
PUT /v1/me/rate-cards
{
"commit": "acme-2026q4-v2",
"supersedes": "acme-2026q4-v1",
"effective": { "start": "2026-09-28", "end": "2026-12-27" },
"currency": "USD",
"agreement_scope": null,
"entries": [
{
"package_id": "acme-prime",
"week": "2026-W41",
"advertiser_class": "general",
"spot_length": 30,
"guarantee_tier": "ng_preemptible",
"clearance_tier": "P2",
"class": "scatter",
"gross_rate_unit": 405.00,
"gross_rate_weekly": 4050.00
}
]
}
Response
The response acknowledges the commit as the current version and reports drift detection: stale_notifications_sent counts buyers with in-flight orders that referenced the superseded version, each of whom receives a catalog.stale_rate_card event with the per-line diff. Buyers read the resulting rate entries through avails and catalog surfaces.
200 Response
{
"commit": "acme-2026q4-v2",
"supersedes": "acme-2026q4-v1",
"entries_written": 840,
"integrity_status": "pass",
"stale_notifications_sent": 3
}
Errors
Error bodies carry the structured shape described in Errors; the conflict report on a rejected commit names every package in the overlapping set.
| Status | Code | When |
|---|---|---|
| 422 | INVALID_INPUT | Malformed commit: an unknown package_id, a bad ISO week, an entry missing part of its rate key. |
| 409 | DAYPART_CONFLICT | The commit would leave two Available packages overlapping in days-intersect-time for some network and week outside a shared pool, or an inventory_pool reference fails to resolve. The whole update rejects with a conflict report. See Packages. |