Skip to main content
The private stream carries your own orders and positions on two channels. The orders channel costs token. The positions channel carries your positions. Name each channel in the private field of a subscribe. To drop both, unsubscribe the subject PRIVATE. Each channel covers only the subaccount of the key that signed the handshake.
To follow an order from start to finish, see Track order state.

Snapshot

orders.seq counts the order events of your subaccount, not of one connection. It’s independent of every market’s seq. A seq of 0 means no event has occurred. A server restart resets the seq. Never compare a seq across connections. A subscribe that names only private gets an empty snapshot.

Events

Events arrive in the orders field of a delta, as one batch with one seq. Within a batch, an order’s fill events come before its open, cancel, or reject.
The order rests. This event, not the 201, confirms that the order rests.qty is the resting quantity.clientId appears only when the placement sent one. An order with an expiry also carries expiresAt, in Unix milliseconds.

Positions

The snapshot lists your nonzero positions under positions. In a delta, positions holds a seq and a deltas list of the positions that changed. Positions already account for washes and neutralizations.
  • A wash is a self-match: your order traded against another of yours, possibly in another subaccount. You get a fill, but your position doesn’t change and nothing appears on trades.
  • A neutralization is a cash-out. We cancel your resting orders in the market with reason: "NEUTRALIZED", and may place a hedge order that closes your position.
  • A qty of 0 in a delta means the position closed.
  • 100 × cost / qty is the average price.
  • The positions seq is independent of orders.seq.

Slow consumer

A slow consumer is a client that reads too slowly, so its queue fills up. A seq gap or a heartbeat shows a dropped orders or positions frame. A seq gap shows a dropped market frame. A write that stalls for 15 s closes the connection with code 1008 and reason SLOW_CONSUMER.
After SLOW_CONSUMER, reconnect, subscribe again, and take the snapshot. Don’t resume from the old seq.

Recovery

Every 15 s, we send a heartbeat with your last seq on each private channel you subscribe to. A quiet channel still reports its seq. A heartbeat seq above your last seq means you lost a message.
subscribe { private: [orders] }snapshot { orders: { seq: 907, open } }POST /v3/orders (REST)201 { orderId }delta { orders: { seq: 908, [open] } }delta { orders: { seq: 909, [fill remaining 70] } }CONNECTION DROPSreconnect, subscribe { private: [orders] }snapshot { orders: { seq: 911, open } }diff open against your state on orderIdCLIENTEXCHANGE

Arrows are messages, top to bottom in time.

On a seq gap, or a heartbeat seq above your last seq, send snapshot with the channel in private.
  • After a reconnect, subscribe and take the snapshot. Then diff open against your state on orderId.
  • If you get no 201 for an order, match clientId against open and fill before you resend.
Without a connection, GET /v3/account/orders and GET /v3/account/positions return the same snapshots. Each comes with its seq and an ETag. A matching If-None-Match gets 304.

Data on other routes