Synpath
Live Market Data

Order book

Subscribe to live order books for one or more markets, both sides, over a single connection.

WSSawait stream.watch_order_book(market_ids)SDK stream · your process · venue credentials

Self-hosted. Opened from your own process straight to the venue. Nothing here runs on Synpath's servers.

A snapshot arrives on subscribe, then a delta for every change. The stream keeps a local copy of each book too, readable at any time with stream.book(market_id, side).

On Kalshi and Polymarket US one book serves both sides and the NO view is the mirror. On Polymarket each side is its own token and its own book, so a subscription to a market watches both tokens.

Gaps are detected where the venue makes it possible and repaired with a fresh snapshot; until it arrives the local book is marked not ready. Subscriptions are re-sent after every reconnect.

Venues

VenueSupportNotes
PolymarketSupportedPolymarketMarketStream, no credentials. A book per side.
KalshiSupportedKalshiStream, needs a Kalshi key: the venue signs the handshake even for market data.
Polymarket USSupportedPolymarketUSMarketStream, needs the retail API key. The venue sends the whole visible book every time.
OpinionSupportedOpinionMarketStream, needs an Opinion API key. Single-level changes with no snapshot or sequence: the book is read over REST once subscribed, and re-read every minute to catch a missed change.

Parameters

NameTypeDescription
market_idslist[str]Synpath ids to watch. Call again to add more; unwatch (Polymarket) to drop some.

BookEvent

The book changed.

NameTypeDescription
venuestringWhich venue the event came from.
received_atintegerWhen this process received it, ms since epoch.
market_idstringSynpath id.
sideyes | noWhich side's book, and the terms its prices are in.
kindsnapshot | deltasnapshot replaces the book; delta lists only changed levels, each with its size after the change (0 means removed).
bids, askslistLevels, {price, size} in the terms of side. Best first.
best_bid, best_askdecimal | nullThe local book's top after applying this event.
sequenceinteger | nullThe venue's sequence number, where it has one (Kalshi).
timestampinteger | nullThe venue's time, ms.

StreamStatusEvent: gap when a message was missed, resynced once a fresh snapshot repaired the book.

import asyncio
from synpath import PolymarketMarketStream

stream = PolymarketMarketStream()                              # no credentials

from synpath import BookEvent

async def main():
    async with stream:
        await stream.watch_order_book(["polymarket:2252244"])
        async for event in stream:
            if isinstance(event, BookEvent):
                print(event.side, event.kind, event.best_bid, event.best_ask)

asyncio.run(main())
BookEvent
{
  "venue": "polymarket",
  "received_at": 1790077592174,
  "market_id": "polymarket:2252244",
  "side": "yes",
  "kind": "delta",
  "bids": [
    {
      "price": "0.41",
      "size": "120"
    }
  ],
  "asks": [],
  "best_bid": "0.41",
  "best_ask": "0.43",
  "sequence": null,
  "timestamp": 1789655011496,
  "info": {}
}