Skip to main content
PolyNode’s Orderbook Stream delivers live orderbook snapshots, depth updates, and price changes for every active Polymarket market. Subscribe to the markets you care about and get enriched, human-readable data pushed to your connection in real time.

108,000+ markets

Every active Polymarket market is tracked. Subscribe to specific markets or get everything at once.

Enriched data

Snapshots include the event title, market question, outcome label, slug, and condition ID. Streaming updates include the slug and outcome for lightweight routing.

250ms batching

Updates are batched into 250ms windows for efficient delivery. One message per tick with all changes for your subscribed markets.

Compression included

Add &compress=zlib to your connection URL for ~50% bandwidth savings. Recommended for production.

Quick start

1

Get an API key

curl -s -X POST https://api.polynode.dev/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"name": "my-app"}'
Save the pn_live_... key from the response.
2

Connect and subscribe

Subscribe using a condition ID or token ID from the REST API. Both sides of the market (Yes + No) are included automatically.
const ws = new WebSocket("wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY");

ws.onopen = () => {
  // Subscribe by condition ID — resolves to both Yes + No tokens
  ws.send(JSON.stringify({
    action: "subscribe",
    markets: ["0x7cb525e831729325d651017f81cbcb6f1adde5011c7b2283babea00b4ae93ae7"]
  }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  if (msg.type === "snapshot_batch") {
    for (const snap of msg.snapshots) {
      console.log(`${snap.question} [${snap.outcome}]: ${snap.bids.length} bids, ${snap.asks.length} asks`);
    }
  } else if (msg.type === "batch") {
    for (const update of msg.updates) {
      if (update.type === "price_change") {
        for (const asset of update.assets) {
          console.log(`${update.slug} [${asset.outcome}]: ${asset.price}`);
        }
      }
    }
  }
};
Use the REST API to find condition IDs: curl -s -H "x-api-key: pn_live_YOUR_KEY" "https://api.polynode.dev/v1/search?q=bitcoin" — each result includes the condition_id you can pass directly to the orderbook subscribe.
3

Receive data

You’ll immediately receive an orderbook snapshot for each subscribed token, then live batched updates:
{
  "type": "book_snapshot",
  "asset_id": "73624432805780182150964443951045800666977811185963019133914618974858599458273",
  "market": "0x561ffbf7de21ef3781c441f30536b026d2b301d7a4a0145a8f526f98db049ba2",
  "condition_id": "0x561ffbf7de21ef3781c441f30536b026d2b301d7a4a0145a8f526f98db049ba2",
  "event_title": "What price will Bitcoin hit in March?",
  "question": "Will Bitcoin reach $150,000 in March?",
  "outcome": "Yes",
  "slug": "what-price-will-bitcoin-hit-in-march-2026",
  "bids": [
    { "price": "0.001", "size": "8604930.58" },
    { "price": "0.002", "size": "4851192.42" }
  ],
  "asks": [
    { "price": "0.999", "size": "6152045.08" },
    { "price": "0.998", "size": "55007.54" },
    { "price": "0.997", "size": "5000" }
  ]
}

Ways to subscribe

You can identify markets using any of these formats:
Subscribe to every active market with a single message. Pass "*" as the market identifier to get the full firehose of all 100,000+ tokens.
{
  "action": "subscribe",
  "markets": ["*"]
}
The server responds with "firehose": true and the total number of active tokens. Live updates start flowing immediately while snapshots stream in the background.
You can mix formats in a single subscribe:
{
  "action": "subscribe",
  "markets": [
    "what-price-will-bitcoin-hit-in-march-2026",
    "0xd1796c09d0d6f876f8580086ae9808ec991784e3a74b25a1830a25de71a78c96",
    "73624432805780182150964443951045800666977811185963019133914618974858599458273"
  ]
}

Finding markets

Use the PolyNode REST API to search for markets and find their slugs, condition IDs, or token IDs:
# Search by keyword
curl -s "https://api.polynode.dev/v1/search?q=bitcoin" | python3 -m json.tool

# Look up by slug
curl -s "https://api.polynode.dev/v1/markets/slug/what-price-will-bitcoin-hit-in-march-2026"

# Look up by condition ID
curl -s "https://api.polynode.dev/v1/markets/condition/0x561ffbf7de21ef3781c441f30536b026d2b301d7a4a0145a8f526f98db049ba2"
Or just grab the slug from any Polymarket event URL: polymarket.com/event/{slug}.

Connection URL

wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY
With compression (~50% bandwidth savings):
wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY&compress=zlib

Subscription limits

All paid tiers can subscribe to every active market with no token limit. Access is gated by the number of simultaneous WebSocket connections you can open to the Orderbook Stream.
TierConnectionsMarket subscriptionsSession limit
Free1Unlimited1 hour/day
Starter ($50/mo)2UnlimitedUnlimited
Growth ($200/mo)10UnlimitedUnlimited
Enterprise ($750/mo)UnlimitedUnlimitedUnlimited
Each Polymarket market has two tokens (one per outcome). Subscribing to both tokens of a market gives you the full two-sided orderbook.
Free tier includes the full firehose. Subscribe to every market and see the full data flow. The only limit is a 1-hour daily session so you can properly evaluate the product before upgrading.
Orderbook connections are separate from main WebSocket connections. Your plan’s WebSocket and firehose limits (shown on the rate limits page) apply to the main feed at ws.polynode.dev. The limits above apply only to the Orderbook Stream at ob.polynode.dev. Session time resets at midnight UTC.

Connection lifecycle

Connect   -> wss://ob.polynode.dev/ws?key=pn_live_...
          <-  (connection established)

Send      -> {"action": "subscribe", "markets": ["*"]}
          <-  {"type": "subscribed", "firehose": true, "markets": 104972}
          <-  {"type": "batch", "ts": ..., "updates": [...]}         (live data starts immediately)
          <-  {"type": "snapshot_batch", "count": 50, "snapshots": [...]}  (snapshots stream in parallel)
          <-  {"type": "batch", ...}                                  (every 100ms)
          <-  {"type": "snapshot_batch", ...}                         (every 200ms)
          <-  {"type": "snapshots_done", "total": 67}
          <-  Ping frame                                              (every 30s)
          ->  Pong frame                                              (automatic)
Live updates start flowing immediately. You don’t have to wait for snapshots to finish. Snapshots are delivered in batches of 50 every 200ms for tokens that have active book data.

Separate from the main WebSocket

The Orderbook Stream runs on a separate endpoint (ob.polynode.dev) from the main PolyNode WebSocket (ws.polynode.dev). They are independent services:
Main WebSocketOrderbook Stream
Endpointwss://ws.polynode.dev/wswss://ob.polynode.dev/ws
DataOn-chain events (settlements, trades, blocks)Off-chain orderbook (bids, asks, prices)
TimingPre-confirmation (pending + confirmed)Real-time (live order placement/cancellation)
Use caseTrade detection, copy trading, alertsMarket making, pricing, depth analysis
You can connect to both simultaneously with the same API key.