Skip to main content
PredictStreet streams live data over two WebSocket gateways that share a single client protocol. Pick the gateway by what data you want; do not mix public and private subscriptions on one socket. Both gateways authenticate at handshake with X-Api-Key — the same key you use for HTTP, same scope rules. An invalid key closes the socket with 4401 <reason> before any subscribe command is accepted. A handshake with no credentials at all connects anonymously on /ws/market (public channels only) and is closed with 1008 unauthorized on /ws/user.
Both gateways accept the same two schemes as HTTP — X-Api-Key for partners, Bearer JWT for the first-party frontend. Private channels (user_orders, user_fills, vault_positions, vault_activity, user_activity, notifications, dispute_intent, bond_payout_credited, me_limits_invalidated) require the portfolio:read scope on API keys; JWT callers bypass the scope check as the wallet owner. For vault_positions / vault_activity, ids must be the vault of the wallet the socket is bound to (the vaultAddress in the connected greeting); for dispute_intent, bond_payout_credited and me_limits_invalidated, an API-key socket passes that wallet (the greeting’s walletAddress) as the only id. See /ws/user for the full handshake matrix and close codes.
Same envelope, same commands (subscribe, update_subscription, unsubscribe, list_subscriptions, ping, plus get_book_snapshot for token_book on /ws/market), same per-subscription sid model on both.

WSS /ws/market

Market data gateway — subscribe by tokenId / conditionId.

WSS /ws/user

Private gateway — X-Api-Key (partners) or Bearer JWT (retail).

Commands

All six client → server commands with payloads + responses.

Server events

Per-channel event catalog (push payloads).

Conventions

  • Prices, quantities and amounts are decimal strings ("price": "0.52") — don’t parse into Number. Exceptions are noted per frame (e.g. ohlc_update candle values are JSON numbers).
  • Addresses lowercased; tokenId decimal-string with no leading zeroes; conditionId lowercased 32-byte hex.
  • sid is connection-local, not stable across reconnects.
  • Auth is validated at handshake only — issuing a new key doesn’t affect a socket opened with the old one. Close + reopen to switch identity. Revoking a key closes every live socket bound to that keyId immediately (4401 api_key_revoked); editing the key’s scopes, suspending the partner or changing the partner’s wallet setup closes them the same way.
  • Heartbeat: send { "id": N, "cmd": "ping" } every 20–30 s; the server replies { "id": N, "type": "pong", "ts": <ms> }.

Implementation status (testnet)