OI reward eligibility threshold increased to $5M
The OI reward eligibility threshold is now 1M. Accounts without an entity mapping qualify
independently. The 6% APR rate and calculation on the account’s full daily
average gross OI across all instruments are unchanged.
Concurrent WebSocket posts and HTTP overload shedding
Concurrent WebSocket posts and HTTP overload shedding. No breaking changes.Added
- Concurrent WebSocket posts (MM gateway). Up to 16 signed writes per
connection now run concurrently. Posts touching the same order, by client
order id or engine order id, still reach the engine in send order.
cancelAlland leverage or margin updates act as barriers. Responses can arrive out of order across different orders: send a uniqueidand match on it. Ordering is per connection. - HTTP overload shedding. Requests over the server or per-IP concurrency
limit are shed before execution:
503,{"status":"err","error":"service_unavailable"}, withRetry-After. Batch routes return a one-element array. The request did not execute, so retry with backoff. The per-IP cap is 128 in-flight on the MM API against healthy usage under 10. Tell us if you NAT many bots through one IP.
- Cancel by client order id. A recently completed order now returns
order_already_terminal, notorder_unknown. A cancel racing its own order’s creation waits briefly (~1ms, capped at 150ms) and succeeds instead of answeringorder_unknown. TP/SLcoids are unchanged. - Funding. Funding for a just-closed window now settles even if you flattened or flipped just before settlement was sequenced; previously the window could be skipped for the whole instrument. Drop any assumption that a closed position means no funding.
- Reduce-only market closes. These now fill only within the price band
around the last mark. Expect partial fills or
ioc_no_fillon a dislocated book. Quotes resting far outside the band will no longer be hit by them. - Balances. REST
valueis now the USD equivalent at the asset’s index price, not the raw amount: same for pUSD, different for other collateral.balanceuses asset-native decimals, matching WebSocket. 429shape on modify routes.PATCH /v1/trade/ordersandPATCH /v1/trade/orders-coidreturn the one-element array instead of a bare object.- Idle connections. HTTP connections with no complete header for 120s
are closed. A per-pod ceiling resets excess connections rather than
serving a
503.
- Deposits. Many-per-transaction deposits credit reliably; a batching edge case could previously delay or drop credits.
- Price continuity. The index survives a full outage of one oracle source, with marks, margin, and funding still updating. Don’t assume prices freeze when a provider goes down.
- Referrals. Concurrent binds for one account resolve to one winner; the
loser gets HTTP
400,account already has a referrer.
- Pending-modify expiry. A modify left risk-undecided for 200ms will be
swept: the order stays open and you retry with a new
modify_id. We’ll notify before enabling. - Per-account rate-limit tiers. Still inactive. We’ll notify before activation.
Response timestamps, rejection references, and liquidation metadata
Rejections and acknowledgements now carry inspectable timing, every WebSocket
push is stamped with engine event time, and backstop liquidation fills include
optional metadata.Added
- Timestamps on rejections. All rejection responses — orders, cancels,
modifies, withdrawals, and transfers — now include
ts(engine decision time),arts(gateway arrival time), andref(a support reference for locating the server-side trace). All three are nullable, except on cancel rejections wheretsis always present. - Timestamps on acknowledgements. Accepted create-order items now include
tsandarts. Accepted cancels, which already carriedts, now also includearts. - Event time on every WebSocket push. Push envelopes across all channels
now carry
ets, the engine event time for the update. This field is always present and is the one to use for event-time analysis. - Liquidation metadata on fills. Fills and trades from backstop
liquidations carry an optional
liquidation_detailsobject withmark,method, andliquidated_user. Available on private WebSocket fills,GET /v1/account/fills, position fills, and public trades. The anonymous trade tape omitsliquidated_user. Ordinary order-book liquidations do not carry this object yet — only backstop liquidations, wheremethodisbackstop. The object is absent where metadata was not captured.
- WebSocket envelope
tsis now server send time. Push frames previously stamped the envelopetswith internal stream time, which could lag actual send time on quiet channels or during catch-up. Engine event time is now carried separately inets. Per-itemtsinsidedatais unchanged. If you measure latency aslocal_receive − envelope_ts, your values will decrease after this release. Earlier measurements included server-internal lag and are not comparable — re-baseline at the deploy timestamp. - Backstop liquidations publish fills to both parties. The liquidated
account and each absorbing account now receive private WebSocket fills for
backstop liquidations. The liquidated account previously received no fills
event. These fills are system-generated, with order id
0and no client order id, matching the shape of ADL fills. order_already_terminalreplacesorder_not_in_orderbookfor terminal orders. Canceling an order that has already filled or canceled now returnsorder_already_terminalto the order’s owner. Unknown and foreign order ids continue to returnorder_not_in_orderbook. Treat unrecognized error codes as non-retryable.
FillsUpdate.dataandTradesUpdate.dataare documented as arrays. The specification previously described objects. The wire format is unchanged; regenerate your client/bindings if you generated the object form.
Current position fills endpoint added
Added
GET /v1/info/position-fills, a public endpoint returning every fill
in a registered account’s current open position cycle for one instrument. A
cycle begins when the position opens from flat or flips direction, and a
multi-leg flip stays in one cycle. Pages of up to 100 fills are linked by an
opaque cursor returned alongside the data; the cursor is validated against
the live position on every page and returns 400 if the position changed
mid-pagination. GET /v1/account/fills has returned the same opaque
cursor field since Jul 24 — passing the last fill’s trade ID as cursor
still works there.Equity and PnL history honour the requested interval
GET /v1/account/equity and GET /v1/account/pnl now bucket the returned
series by the interval query parameter. Previously the parameter was
validated but ignored: every accepted value returned the same
fixed-granularity series (per minute for equity, per hour for PnL), and long
windows were truncated at 1000 rows instead of aggregated. Each equity point
is now the last sample in its interval bucket; each PnL point is the PnL
realized inside its bucket — not a running total — and empty buckets are
omitted. Buckets are aligned to the Unix epoch, points keep real sample
timestamps, and the 1000-entry cap now counts buckets, so a coarser interval
covers a longer window before more is set. Responses for the finest
intervals (1m equity, 1h PnL) are unchanged.Deposit and withdrawal history amounts are always decimal token units
GET /v1/account/deposits and GET /v1/account/withdrawals now serialize
every amount (and withdrawal fee) in decimal token units, e.g. "10" for
10 pUSD. Previously, deposit rows in pending or removed status reported
raw on-chain base units ("10000000" for the same 10 pUSD), and pending
withdrawal rows could serve base-unit amounts and fees as well, so rows for
the same transfer disagreed on units across statuses. Clients that divided
pending amounts by 10^decimals to compensate must drop that conversion.
Confirmed rows and the WebSocket deposits and withdrawals channels are
unchanged — they were already decimal. Signed operation inputs (POST /v1/account/withdraw) still take base-unit amounts matching the EIP-712
signature.Fill history flags maker fills executed under liquidation
GET /v1/account/fills and account trade history previously reported
liquidation: false on every maker fill, even when the maker’s own account
was under liquidation on the instrument — while the WebSocket fills channel
already reported liq: true for the same fill. The two surfaces now agree:
any maker or taker fill on an instrument in the account’s active liquidation
scope reports liquidation: true. Rows written before the change are
unaffected. Such maker legs are also excluded from leaderboard win counts.Fills gain an adl flag; liq no longer set on ADL counterparty legs
Fill entries now carry a required boolean
adl field on both the WebSocket
fills channel and GET /v1/account/fills, set on both legs of an
auto-deleveraging match. Behavior change: the counterparty leg of an ADL match
previously reported liq: true on the WebSocket fills channel; it now
reports liq: false. liq marks only the leg whose own position is being
liquidated. Clients that detect forced closes via liq alone will no longer
see ADL counterparty fills — check adl as well.Position deleveraged notification added
Added the
position_deleveraged notification, sent to the
counterparty of an auto-deleveraging match when its profitable position is
closed or reduced to settle a liquidation on the other side. Delivered on the
WebSocket notifications channel and in the notifications history.Exchange info reports engine version and cancel-only state
GET /v1/info/exchange now includes engine_version, the engine release
version of the build serving the response. The response also documents
cancel_only, which reports whether the exchange is in cancel-only
(maintenance) mode; the flag has been returned since maintenance mode shipped
on Jul 15.Portfolio margin summary includes available order margin
The portfolio response and
portfolio WebSocket channel now
include margin.available_order_margin: the collateral available
for additional order initial margin after existing exposure, open orders,
orders and isolated-margin additions awaiting risk processing, and pending
withdrawals or transfers.Cancel all orders added
Added
DELETE /v1/trade/orders/all to cancel all open orders in
one request, optionally scoped to a single instrument. Available in the SDKs
as cancelAllOrders (TypeScript) and
cancel_all_orders (Python).Cancel responses include order IDs
Cancel responses now include
oid and coid fields.Taker delay added for immediately matching orders
Added a 20ms taker delay for orders that immediately match on entry.
Reduce-only orders added
Added the reduce-only field to order submission and order updates.
Auto-cancel and rate-limit updates
- Added
PATCH /v1/trade/auto-cancelto arm or clear a dead man’s switch that cancels all open orders at a specified time. - Added
GET /v1/account/auto-cancelto check the current auto-cancel status, trigger count, and daily reset time. - Auto-cancel is limited to 1000 triggers per UTC day per account.
- Added
updateLeverageandautoCancelWebSocket post messages. portfolioandbalancesWebSocket channels no longer push updates on every order or fill, only periodically.- Rate limit error messages now distinguish between
ip_rate_limited,action_rate_limited, andmessage_rate_limited.