What “resume” means
After a successful login, the server returns aresume block in login_ok:
serverEpoch— identifies the current gateway session (changes on restart)resumeWindowMs— how long replayable data is bufferedreplayChannels— channels eligible for replayserverEntryIds— server’s latest cursor per channel
What clients must persist
To resume safely, persist:serverEpoch- The most recent
entryIdyou processed per channel
entryId format
Each streamed message includes anentryId:
ts_ms— server timestamp (UTC, milliseconds)seq— monotonic per-channel sequence
entryIdis a cursor, not a delivery guarantee- Gaps are normal (upstream behavior, coalescing, backpressure)
Resume login example
On reconnect, send the sameserverEpoch and your stored cursors:
snapshot_required (when replay is not possible)
Sometimes replay cannot be done safely. In that case the server sends:Possible reasons
server_restarted— gateway restarted, cursors invalidresume_window_exceeded— your cursor is older than the replay bufferclient_backpressure— your client couldn’t consume replay fast enough
Important nuance
Replay eligibility depends on cursor age, not disconnect duration:How clients should handle snapshot_required
When you receivesnapshot_required:
- Fetch a fresh snapshot via REST for the listed channels
(e.g.
/fixtures,/fixtures/odds,/futures) - Clear
lastSeenIdfor those channels - Continue processing live updates
The gateway continues streaming after snapshot_required.
This message is your signal that local state must be rebuilt.
Python reconnect example (FULL TEMPLATE)
This example:- Persists
serverEpochand per-channellastSeenId - Sends cursors only for replayable channels
- Handles
snapshot_required - Automatically reconnects on failure