WebSocket API — Position Snapshots
Live position data uses the authenticated encrypted trading protocol. It is not a plaintext JSON positions channel and does not send one position per frame.
the WebSocket origin/ws/v1
Authenticate and establish the HPKE session first (see WebSocket Trading). Use an official SDK to encode requests and decrypt pushes.
Subscribe
Send an encrypted SubscribePositions request. Its plaintext protobuf fields are:
account: bytes
interval_seconds: uint32
Allowed refresh intervals are 2, 5, or 10 seconds. Error 7202 rejects any other interval.
Decrypted Push
Each encrypted push contains one complete PositionsSnapshot, not an incremental position object:
account: bytes
rows: PositionRow[]
server_timestamp: uint64
source: INITIAL | PERIODIC | EVENT
correlation_id?: bytes
| Field | Type | Description |
|---|---|---|
account | bytes | Authenticated 32-byte Solana account identity; SDKs expose it as base58 |
rows | PositionRow[] | Full set of open positions at assembly time |
server_timestamp | uint64 | Sequencer assembly time in nanoseconds since Unix epoch |
source | enum | INITIAL for the subscription reply, PERIODIC for interval sweeps, or EVENT after a position-changing fill, flip, or close |
correlation_id | bytes, optional | Echoed for the initial subscription snapshot; absent from periodic and event pushes |
Because every message is authoritative, replace the local position collection with rows; do not apply it as a delta.
PositionRow
Decimal quantities and prices are strings.
| Field | Type / values |
|---|---|
symbol_id | uint64 protocol instrument id |
side | BUY or SELL |
size, entry_price | Required decimal strings |
leverage | uint32 |
mark_price, unrealized_pnl, notional | Optional decimal strings; absent before a usable oracle mark |
mark_publish_time_sec | Optional oracle publish time |
liquidation_price, margin, mmr, mgn_ratio | Optional decimal strings |
margin_ratio_bps | Optional uint64 |
adl_indicator | Optional uint32, 0 (safest) through 5 |
position_status | Optional NORMAL, LIQ, or ADL |
mgn_mode | ISOLATED or CROSS |
take_profit, stop_loss | Optional decimal strings |
tpsl_status, tpsl_parent_order_id | Optional TP/SL lifecycle data |
For the same schema over REST, use authenticated encrypted POST /api/v1/positions. There is no plaintext GET /positions.
Unsubscribe
Send an encrypted UnsubscribePositions request. Re-subscribe to obtain a fresh authoritative snapshot after reconnecting or if local state is in doubt.