> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polynode.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Examples

> Code examples for connecting to the Orderbook Stream in JavaScript, Python, and from the command line.

## Command line (wscat)

```bash theme={null}
# Subscribe to the full firehose (all active markets)
wscat -c "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY" \
  -x '{"action":"subscribe","markets":["*"]}'

# Subscribe by slug (easiest for specific markets)
wscat -c "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY" \
  -x '{"action":"subscribe","markets":["what-price-will-bitcoin-hit-in-march-2026"]}'

# Subscribe by condition ID
wscat -c "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY" \
  -x '{"action":"subscribe","markets":["0x561ffbf7de21ef3781c441f30536b026d2b301d7a4a0145a8f526f98db049ba2"]}'

# Subscribe by token ID
wscat -c "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY" \
  -x '{"action":"subscribe","markets":["73624432805780182150964443951045800666977811185963019133914618974858599458273"]}'
```

## Finding markets

Use the PolyNode REST API to search for markets:

```bash theme={null}
# Search by keyword
curl -s "https://api.polynode.dev/v1/search?q=bitcoin" | python3 -m json.tool

# Look up by slug (from any Polymarket URL: polymarket.com/event/{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"
```

The easiest approach: copy the slug from a Polymarket event URL and pass it directly in your subscribe message.

## JavaScript (firehose)

```javascript theme={null}
const ws = new WebSocket("wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY");

ws.onopen = () => {
  ws.send(JSON.stringify({ action: "subscribe", markets: ["*"] }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.type === "subscribed") {
    console.log(`Firehose active: ${msg.markets} tokens`);
  } else if (msg.type === "batch") {
    console.log(`${msg.count} updates at ${msg.ts}`);
    for (const update of msg.updates) {
      if (update.type === "price_change") {
        for (const asset of update.assets) {
          // size="0" removes the level; otherwise it's the new absolute size at that level.
          console.log(`  ${update.slug} [${asset.outcome}] ${asset.side} ${asset.price} -> ${asset.size}  (bbo ${asset.best_bid}/${asset.best_ask})`);
        }
      }
    }
  }
};
```

## JavaScript (specific markets)

```javascript theme={null}
const ws = new WebSocket("wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY");

ws.onopen = () => {
  // Subscribe by slug — both sides (Yes + No) are included automatically
  ws.send(JSON.stringify({
    action: "subscribe",
    markets: [
      "what-price-will-bitcoin-hit-in-march-2026",
      "netanyahu-out-before-2027"
    ]
  }));
};

// Maintain local orderbook state
const books = {};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  switch (msg.type) {
    case "subscribed":
      console.log(`Subscribed to ${msg.markets} tokens`);
      console.log(`Resolved from: ${JSON.stringify(msg.resolved_from)}`);
      break;

    case "snapshot_batch":
      for (const snap of msg.snapshots) {
        books[snap.asset_id] = { bids: snap.bids, asks: snap.asks };
        console.log(`Snapshot: ${snap.event_title} [${snap.outcome}] - ${snap.bids.length}b/${snap.asks.length}a`);
      }
      break;

    case "batch":
      for (const update of msg.updates) {
        if (update.type === "price_change") {
          for (const asset of update.assets) {
            // Apply directly to local books — price_change carries size + side so you
            // can maintain a tick-accurate book without polling REST.
            const book = books[asset.asset_id];
            if (book) {
              const levels = asset.side === "BUY" ? book.bids : book.asks;
              applyDelta(levels, [{ price: asset.price, size: asset.size }]);
            }
          }
        } else if (update.type === "book_update") {
          const book = books[update.asset_id];
          if (book) {
            applyDelta(book.bids, update.bids);
            applyDelta(book.asks, update.asks);
          }
        }
      }
      break;
  }
};

// Apply incremental orderbook updates
function applyDelta(existing, deltas) {
  for (const delta of deltas) {
    const idx = existing.findIndex(l => l.price === delta.price);
    if (delta.size === "0") {
      if (idx >= 0) existing.splice(idx, 1);
    } else if (idx >= 0) {
      existing[idx].size = delta.size;
    } else {
      existing.push(delta);
    }
  }
}

ws.onclose = () => setTimeout(() => location.reload(), 3000);
```

## Python (firehose)

```python theme={null}
import asyncio
import json
import websockets

async def stream_firehose():
    url = "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY"

    async with websockets.connect(url, max_size=10_000_000) as ws:
        await ws.send(json.dumps({
            "action": "subscribe",
            "markets": ["*"]
        }))

        async for message in ws:
            data = json.loads(message)

            if data["type"] == "subscribed":
                print(f"Firehose active: {data['markets']} tokens")

            elif data["type"] == "batch":
                for update in data["updates"]:
                    if update["type"] == "price_change":
                        for asset in update["assets"]:
                            # size="0" removes the level; otherwise it's the new absolute size.
                            print(f"  {update['slug']} [{asset['outcome']}] {asset['side']} {asset['price']} -> {asset['size']}  (bbo {asset['best_bid']}/{asset['best_ask']})")

asyncio.run(stream_firehose())
```

<Tip>
  Set `max_size` to at least 10 MB when connecting to the firehose (full data stream). Batch messages can be large when many markets update in the same 100ms window.
</Tip>

## Python (specific markets)

```python theme={null}
import asyncio
import json
import websockets

async def stream_orderbook():
    url = "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY"

    async with websockets.connect(url) as ws:
        # Subscribe by slug — resolves to all token IDs for those events
        await ws.send(json.dumps({
            "action": "subscribe",
            "markets": [
                "what-price-will-bitcoin-hit-in-march-2026",
                "netanyahu-out-before-2027",
            ]
        }))

        async for message in ws:
            data = json.loads(message)

            if data["type"] == "subscribed":
                print(f"Subscribed to {data['markets']} tokens")
                print(f"Resolved from: {data['resolved_from']}")

            elif data["type"] == "snapshot_batch":
                for snap in data["snapshots"]:
                    print(f"Snapshot: {snap['event_title']} [{snap['outcome']}]")
                    print(f"  Bids: {len(snap['bids'])} levels")
                    print(f"  Asks: {len(snap['asks'])} levels")

            elif data["type"] == "batch":
                for update in data["updates"]:
                    if update["type"] == "price_change":
                        for asset in update["assets"]:
                            print(f"  {update['slug']} [{asset['outcome']}] {asset['side']} {asset['price']} -> {asset['size']}  (bbo {asset['best_bid']}/{asset['best_ask']})")

                    elif update["type"] == "book_update":
                        bids = len(update.get("bids", []))
                        asks = len(update.get("asks", []))
                        print(f"  Book delta: {update['slug']} [{update['outcome']}] +{bids}b/+{asks}a")

asyncio.run(stream_orderbook())
```

## Python with compression

```python theme={null}
import asyncio
import json
import zlib
import websockets

async def stream_compressed():
    url = "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY&compress=zlib"

    async with websockets.connect(url) as ws:
        await ws.send(json.dumps({
            "action": "subscribe",
            "markets": ["what-price-will-bitcoin-hit-in-march-2026"]
        }))

        async for message in ws:
            if isinstance(message, bytes):
                text = zlib.decompress(message, -zlib.MAX_WBITS).decode("utf-8")
                data = json.loads(text)
            else:
                data = json.loads(message)

            print(f"[{data.get('type')}] {json.dumps(data)[:200]}")

asyncio.run(stream_compressed())
```

## Mixed identifier subscribe

You can mix slugs, condition IDs, and token IDs in a single subscribe:

```python theme={null}
await ws.send(json.dumps({
    "action": "subscribe",
    "markets": [
        "what-price-will-bitcoin-hit-in-march-2026",                              # slug
        "0xd1796c09d0d6f876f8580086ae9808ec991784e3a74b25a1830a25de71a78c96",      # condition ID
        "73624432805780182150964443951045800666977811185963019133914618974858599458273"  # token ID
    ]
}))
```
