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
"1" with the contract ID whose trade stream you want to receive, passed as a string.
Push message format
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.