Skip to main content

Deprecation policy

When we remove or materially change a public endpoint or field:
  1. Announce the replacement — what to use instead, with a migration example.
  2. List affected endpoints — every route, field, or WS channel touched.
  3. Set a dated removal window — at least 90 days from announcement for breaking REST changes, unless the change is a security fix.
  4. Log reversals — if we roll back a deprecation, it is recorded here with the reason.
Non-breaking additions (new optional fields, new endpoints, new error codes) ship without a deprecation window. Closed-schema endpoints reject unknown fields — do not send fields you have not seen documented. Subscribe via the page RSS feed (/changelog/rss.xml when published).
RESTWebSocketBreaking
Cancel batch, introspection, dead-man, WS update

Breaking — cancel batch verb

Batch cancel moved off a separate POST path.Body unchanged: { "order_ids": ["…"] } (≤ 20 decimal-string ids). Response is per-item, index-aligned; partial success is normal.POST /v1/portfolio/orders/batch remains batch placement only.Affected: any client still calling …/cancel_batch. Migrate before relying on production traffic — the old path is gone (no dual-write window; the route never had external consumers).

Breaking — cancel-all empty body

DELETE /v1/portfolio/orders must have an empty body. A non-empty body returns 400 unexpected_body instead of cancelling. This prevents a misrouted batch-cancel (missing /batch) from wiping the book.Affected: DELETE /v1/portfolio/orders only.

Round status vocabulary

Round rows use: trading, frozen, proposed, settled, void. There is no created status on round objects.

WebSocket channel inventory

Live: orderbook_delta, trades, user, oracle, rounds. ticker is not implemented (subscribe → wscode 4).

exchange_active honesty

GET /v1/exchange/status always returns exchange_active: true in v1. Per-round freeze/settle is the operational pause — see Pauses and rounds.

New introspection endpoints

Dead-man switch

POST /v1/portfolio/deadman with { "timeout_ms": N } (1000–60000) arms a gateway-side timer. Refresh by POSTing again. On fire: one user-wide cancel-all, then disarm. DELETE /v1/portfolio/deadman disarms without cancelling.This is not Kalshi-style order-group fill-velocity limiting — that remains deferred.

WebSocket update_subscription

Actions: get_snapshot, add_markets, delete_markets.

429 shape

Rate limits answer with details.retry_after_ms in the error body. There is no Retry-After HTTP header.