Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

WebSocket streaming

Connect to:

wss://lowcapsxyz.com/v1/stream

Authenticate the WebSocket handshake with either Authorization: Bearer <your-api-key> or a valid same-origin session cookie. Then send exactly one JSON subscribe frame.

Subscribe

{
  "filter": {
    "chain_ids": [8453],
    "pool_ids": [
      "0x1111111111111111111111111111111111111111111111111111111111111111"
    ],
    "token_ids": [
      "0x2222222222222222222222222222222222222222222222222222222222222222"
    ]
  },
  "resume_cursor": null
}

Filter arrays must be strictly sorted and unique. Empty pool_ids and token_ids arrays select every routed message for the chosen chains. A null cursor starts live-only delivery.

Message envelope

Durable messages share this envelope:

{
  "stream_sequence": 10842,
  "routing": {
    "chain_id": 8453,
    "pool_ids": [],
    "token_ids": []
  },
  "type": "PRICE_UPSERT",
  "payload": {}
}

stream_sequence is monotonic, not necessarily contiguous. Use it for ordering and recovery. Message types are:

TypeMeaning
PRICE_UPSERTAbsolute current price state; safe to apply repeatedly.
PRICE_RETRACTPreviously published evidence changed or was removed; recompute from the supplied post-change state.
SWAP_OBSERVEDA decoded swap with exact amounts and event position.
FEED_HEALTHA chain feed-health update.
RESET_REQUIREDReplay cannot safely continue; rebuild state and reconnect.

RESET_REQUIRED is a control message and has no stream_sequence.

Resume and replay

For snapshot-plus-delta consumption:

  1. Read every page of GET /v1/pools and retain the minimum snapshot_sequence returned across the pages.

  2. Create a cursor after that boundary:

    curl --fail-with-body -X POST \
      -H 'Authorization: Bearer <your-api-key>' \
      'https://lowcapsxyz.com/v1/session?chain_id=8453&snapshot_sequence=<snapshot-sequence>'
    
  3. Reconnect and send the returned resume_cursor in the subscribe frame.

  4. Apply replayed records, then continue with live records. Ignore overlap at or below the last applied sequence.

The current session cursor is chain-wide. A narrower pool or token filter with that cursor causes RESET_REQUIRED with FILTER_MISMATCH. For resumable delivery, subscribe chain-wide and filter locally.

Heartbeats and slow consumers

The server sends a WebSocket ping every 30 seconds and expects a pong before the next heartbeat. It also responds to client pings.

If a slow consumer falls behind, the connection closes with code 1013 and identifies the last delivered sequence. Create a new session cursor after that sequence and reconnect. If replay is no longer available, discard local state and take a fresh snapshot.

RESET_REQUIRED

{
  "type": "RESET_REQUIRED",
  "payload": {
    "reason": "REPLAY_UNAVAILABLE",
    "server_time_unix_ms": 1784217600000
  }
}

Possible reasons are INVALID_CURSOR, EXPIRED_CURSOR, FILTER_MISMATCH, REPLAY_UNAVAILABLE, and SCHEMA_MISMATCH.

On receipt:

  1. stop applying stream messages;
  2. discard state whose consistency depends on the rejected cursor;
  3. fetch a fresh pool snapshot;
  4. create a new cursor at that snapshot boundary;
  5. reconnect chain-wide.