WebSocket API — Orders Channel

Live order lifecycle events are encrypted end to end. The edge forwards ciphertext; the SDK decrypts the protobuf OrderUpdateMessage locally.

the WebSocket origin/ws/v1

Authenticate with op: login first (see WebSocket Trading).

Subscribe

{ "id": "c-2", "op": "subscribe", "args": { "channel": "orders" } }

Response:

{ "id": "c-2", "op": "subscribe", "code": 0, "data": { "channel": "orders", "seq_start": 1 } }

Event Flow

snapshot → snapshot → ... → snapshot (snapshot_complete: true) → update → update → ...

The server first replays every currently live order as a snapshot frame, then emits update frames as state changes. The final snapshot frame carries snapshot_complete: true; that is the signal to start applying buffered updates.

Incremental updates that arrive while snapshot delivery is in progress should be buffered and replayed after snapshot_complete: true.

Encrypted frame

Transport frames carry encrypted payload metadata rather than a plaintext order object. After SDK decryption, the payload has the schema below.

{
  "encrypted": true,
  "message_type": "ORDER_UPDATE",
  "encrypted_body": "<base64 ciphertext>",
  "nonce": 12,
  "fencing_epoch": 7,
  "correlation_id": "100"
}
FieldDescription
The SDK must authenticate/decrypt the body before interpreting any order values.

Decrypted OrderUpdateMessage

message_typeMeaning
ACK, OPEN, PARTIALLY_FILLED, FILLEDAcknowledgement and working/fill lifecycle
CANCELLED, REJECTEDTerminal cancellation/rejection
MODIFIEDAmend applied
CANCEL_REJECTED, MODIFY_REJECTEDRequested operation rejected

Field Reference

FieldTypeDescription
message_typestringSee table above
order_id, symbol_id, timestampu64Venue ids and event time
account, correlation_idbytesOwner account (32-byte Solana identity, exposed as base58 by SDKs) and client correlation key
side, order_type, order_status, message_typeenumUppercase SDK enum values
price, quantity, filled_qty, remaining_qty, cum_filldecimal stringExact decimal values; do not parse as binary float
avg_fill_price, realized_pnl, trading_feeoptional decimal stringFill/accounting values
leverageu32Applied leverage
cancel_reason, close_reason, tpsl_statusoptional enumStructured lifecycle reasons
reject_reason_codeoptional u32Product error code
msgoptional stringHuman-readable reject detail
take_profit, stop_loss, trigger_priceoptional decimal stringTrigger attributes
peg_offset_bpsoptional signed i32Original Pyth peg offset
reduce_only, post_onlybooleanPlacement attributes

Rejection Reasons

Use reject_reason_code and the trade ACK/error-code catalog. msg is supplementary and must not be used as a stable programmatic enum.

Cancellation Reasons

Values for cancel_reason when message_type is cancelled:

ValueDescription
USER_REQUESTEDUser cancellation
IOC_REMAINDERUnfilled portion of an IOC order
FOK_NOT_FILLEDFOK order could not fully fill
EXPIREDReached expiry_time on a GTD order (ACK catalog: GTD_EXPIRED / 2026)
SYSTEMSystem cancellation
ADLAuto-deleveraging cancellation
LIQUIDATED_CANCELEDPosition liquidation cancelled the order
MARGIN_CANCELEDMargin protection cancelled the order
REDUCE_ONLYReduce-only constraints cancelled the remainder
STP_EXPIRE_TAKERSelf-trade prevention expired the taker
STP_CANCEL_RESTINGSelf-trade prevention cancelled the resting order

Gap Recovery

Clients should track seq. If a gap appears (seq_n > seq_{n-1} + 1):

  1. op: unsubscribe { channel: "orders" }
  2. op: subscribe { channel: "orders" } — receive a fresh snapshot
  3. Resume applying updates from the new seq series

Unsubscribe

{ "id": "c-9", "op": "unsubscribe", "args": { "channel": "orders" } }