Skip to main content

Execution Streams

The private execution stream is the primary source of truth for Order Entry clients. It carries the engine's execution results — acknowledgements, amendments, fills, terminal states, and rejects — in real time and in monotonic order. Database reads exist for backfill and recovery, not as the main order lifecycle.

This page covers the Order Entry execution feed specifically. For the shared WebSocket envelope, sequence model, heartbeat, and authentication handshake, see WebSocket Overview and Private Channels. For connectivity, credentials, and request signing, see Authentication — one host per environment, with WebSocket under wss://{host}/api/v1/ws/....

WebSocket endpoint

GET /api/v1/ws/private/{account}?token=<ws-session-token>

The stream is account scoped and emits execution events from the engine result ring. It uses the same envelope, sequencing, heartbeat, and resync behavior as all private channels; see Private Channels for the protocol details rather than restating them here.

Legacy route names

BSL is a legacy alias for Order Entry. The path /api/v1/ws/bsl/{account} remains live only as a compatibility route and maps to /api/v1/ws/private/{account}. New integrations should use the canonical private path.

Event model

Events are monotonic by seq. Clients must persist the latest processed sequence before acknowledging work inside their own system, and deduplicate against it so a replayed range is never applied twice.

Each execution event includes the fields needed for deterministic reconciliation:

FieldPurpose
seqMonotonic venue sequence (account scoped).
clientOrderIdStrategy id supplied in the signed payload.
orderIdVenue order id.
statusTerminal or current order status.
filledQtyFilled quantity for this result.
leavesQtyRemaining live quantity.
fillIdFill identifier when a trade event exists.
rejectCodeStable machine code for rejects.
marketMarket id.
shardMarket shard id.
engineTsMsEngine timestamp.
serverTsMsServer event timestamp.

Sequence numbers and delivery

Private execution events are sequenced per account. Persist the last processed account sequence and use it on reconnect to avoid double-processing fills or terminal order states.

Events are delivered ring-first: the server serves reads from an in-memory, per-account replay buffer before falling back to SQL. The buffer is bounded by both a maximum event count and a retention window (max_events / retention_ms), so it covers the most recent events for each account. The produce path remains DB-write-first — each event is committed and its identifier is derived from the database sequence before being pushed into the replay buffer. As a result, sequence numbers and ordering are identical whether an event is served from the ring or from SQL. FIX drop-copy shares the same replay buffer.

Gap-fill

GET /api/v1/order-entry/accounts/{account}/executions?fromSeq=12345

Use gap-fill after reconnect or when a client detects a sequence jump. Sign the request with your API key triple using SC-* machine-auth headers (see Authentication). The response uses the same private execution stream model returned over WebSocket.

If your last processed sequence is still inside the replay buffer, the gap is served directly from memory. After a longer outage, or for a range older than the retention window, the server transparently falls back to a SQL read to backfill the gap and then resumes from the ring.

Startup and recovery sequence

Run this sequence on startup and after any reconnect:

  1. Fetch the open-orders snapshot.
  2. Open the Order Entry private WebSocket.
  3. Gap-fill from the snapshot sequence to the stream sequence.
  4. Apply stream deltas monotonically, deduplicating against the last processed account sequence.

Stop applying deltas when a gap is detected, recover through gap-fill, and resume only after continuity is restored. For the general WebSocket reconnect loop (backoff, re-authentication, replay on resume), see Reconnect Strategy.

Do not use periodic private reads as the normal lifecycle source for high-rate strategies. They add read-plane latency and make cancel/replace behavior feel worse than the engine actually is. The execution stream — not HTTP polling — is the lifecycle source.

Token model

Private execution reads use a short-lived WebSocket session token. Obtain it with one SC-* signed REST call:

POST /api/v1/ws/token

Send the returned token in the socket auth frame (or as the token query parameter on the WebSocket URL above). The token is accepted by Order Entry private read endpoints even when the HTTP platform plane and trading plane do not share an in-memory registry; revocation and credential checks still consult persistent control-plane state. See Authentication for the full token flow.

Next