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

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

FieldTypeDescription
commit requiredstringYour id for this card version, e.g. acme-2026q4-v2. Orders pin it as rate_version.
supersedesstringThe commit this one replaces. Drift diffs are computed against it.
effective.start requiredISO dateFirst day the card applies.
effective.end requiredISO dateLast day the card applies.
currency requiredISO 4217The trade currency: one per commit, echoed on every entry by read surfaces, locked into an order with its rates, carried and never converted.
agreement_scopestringDefault: null, an open card. Set an agreement id to publish a buyer-scoped card; negotiated rates and quotes live on these.
commit_kindenumstanding (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_atISO datetimeRequired 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_refstringOn quote commits: the proposal order this quote answers.
entries[] requiredarray of objectThe rate entries. Fields below.

entries[]

FieldTypeDescription
package_id requiredstringThe package the rate prices. Must exist in your published catalog.
weekISO weekOmit for a rate that holds across the effective window; set it to price a single week.
advertiser_class requiredenumOne of your declared advertiser classes.
spot_length requiredintegerCreative length in seconds.
guarantee_tier requiredenumOne of the guarantee tiers.
clearance_tier requiredenumOne of the clearance tiers.
class requiredenumOne of the market classes, the entry's market timing.
gross_rate_unitnumberGross rate for one unit at this spot_length. Set per-length rates or cost_per_second, not both.
gross_rate_weeklynumberGross rate for a full week of units. Stated by you, never back-computed from gross_rate_unit.
rate_basisstringSet to cost_per_second to price per second instead of per length.
cost_per_secondnumberPer-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.

StatusCodeWhen
422INVALID_INPUTMalformed commit: an unknown package_id, a bad ISO week, an entry missing part of its rate key.
409DAYPART_CONFLICTThe 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.