Skip to main content
The trades channel streams every public trade for a contract — regardless of which account was involved. Each push message carries its trades in a data array: a live frame always holds exactly one trade, and only the backfill frame sent on subscribe holds several. If you only care about fills from your own account, use the userFills channel instead.

Subscribing

Replace "1" with the contract ID whose trade stream you want to receive, passed as a string.

Push message format

In a live frame, data is always a one-element array — one trade per frame, never batched. The backfill frame on subscribe carries several trades. Parse data as an array in both cases.

Trade object fields

string
Contract ID. Matches the asset in your subscription.
string
Trade execution price (raw string). Apply the contract’s decimal precision before displaying to users.
string
Trade size (raw string). This is the notional quantity that changed hands at px.
string
Indicates which side initiated the trade. "B" means the buyer was the aggressor (taker); "S" means the seller was the aggressor (taker).
number
Globally unique trade ID assigned on-chain. Use this to deduplicate trades if you receive the same block’s data from multiple sources.
number
Trade time in Unix milliseconds in the backfill frame. In live frames it is always 0; use the envelope ts there.
int64
Block height of the block that contains this trade. Same value as height on orderHistory and userFills. Present in both live and backfill frames. Conditional: height and txIndex are either both present or both absent; both absent means the trade has no block position, which does not occur in normal trading.
int32
Index of the transaction within the block. (height, txIndex) identifies the transaction that produced this trade. -1 is a defined value, not a missing one: it marks a block-level event — funding settlement, liquidation, auto-deleveraging, or a TP/SL trigger — that is not produced directly by any user transaction. Present or absent together with height.

Outer envelope fields

number
Server send timestamp in Unix milliseconds. In live frames, use it as the trade timestamp.

Backfill on subscribe

On a successful subscription the server first pushes a history snapshot frame, marked "isSnapshot": true, whose data array holds up to the last 100 trades for the contract in ascending time order. Live incremental frames follow and do not carry isSnapshot. When the contract has no trade history the snapshot frame carries "data": [].
In the backfill frame, time is the real trade time. In live incremental frames time is always 0 — use the envelope ts as the authoritative timestamp there.

Building a trade history feed

1

Subscribe and take the backfill

Send the subscribe message. The first frame carries up to 100 recent trades — render it as your initial tape.
2

Merge the live stream

Subsequent frames arrive without isSnapshot. Ordering between the backfill and the live stream guarantees no gap; a small overlap is possible.
3

Deduplicate using tid

Use tid as the unique key when merging the backfill with the live stream, or when combining with any other source.
For longer history than the 100-trade backfill, or for aggregated OHLCV, use the REST candleSnapshot endpoint.
To build a volume-weighted average price (VWAP) over a rolling window, accumulate px × sz from incoming trade messages, divide by the rolling total sz, and reset the window at your chosen interval.