Polymarket V2 cutover: April 28, 2026 at ~11am UTC. If you place orders via our trading SDK, upgrade to the V2-ready version and flip one config line before cutover. See the V2 Migration Guide for the full checklist.
PolyNode API
PolyNode delivers Polymarket settlement data 2–5 seconds before on-chain confirmation (1–2 Polygon blocks). Connect via WebSocket for real-time streaming, or query the REST API for markets, candles, and orderbook data.WebSocket streaming
Real-time settlements with filtered subscriptions. The core product.
Markets & pricing
Enriched market metadata, OHLCV candles, and volume analytics.
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"}'
2. Query the REST API
curl -s -H "x-api-key: pn_live_YOUR_KEY" \
"https://api.polynode.dev/v1/markets?count=5"
const resp = await fetch("https://api.polynode.dev/v1/markets?count=5", {
headers: { "x-api-key": "pn_live_YOUR_KEY" },
});
const data = await resp.json();
console.log(data.markets[0].question, data.markets[0].last_price);
import requests
resp = requests.get(
"https://api.polynode.dev/v1/markets",
params={"count": 5},
headers={"x-api-key": "pn_live_YOUR_KEY"},
)
for m in resp.json()["markets"]:
print(f"{m['question']} — {m['last_price']}")
3. Stream live settlements via WebSocket
const ws = new WebSocket("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY");
ws.onopen = () => {
ws.send(JSON.stringify({ action: "subscribe", type: "settlements" }));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "settlement") {
const d = msg.data;
console.log(`${d.taker_side} ${d.taker_size} @ ${d.taker_price} | ${d.market_title}`);
}
};
import asyncio, json, websockets
async def stream():
async with websockets.connect("wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY") as ws:
await ws.send(json.dumps({"action": "subscribe", "type": "settlements"}))
async for message in ws:
msg = json.loads(message)
if msg["type"] == "settlement":
d = msg["data"]
print(f"{d['taker_side']} {d['taker_size']} @ {d['taker_price']} | {d.get('market_title')}")
asyncio.run(stream())
npx wscat -c "wss://ws.polynode.dev/ws?key=pn_live_YOUR_KEY"
# then send:
{"action":"subscribe","type":"settlements"}
4. Stream a live orderbook
const ws = new WebSocket("wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY");
ws.onopen = () => {
// Subscribe by condition ID (from the REST API) or token ID
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}`);
}
}
}
}
};
import asyncio, json, websockets
async def stream_orderbook():
async with websockets.connect("wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY") as ws:
await ws.send(json.dumps({
"action": "subscribe",
"markets": ["0x7cb525e831729325d651017f81cbcb6f1adde5011c7b2283babea00b4ae93ae7"]
}))
async for message in ws:
data = json.loads(message)
if data["type"] == "snapshot_batch":
for snap in data["snapshots"]:
print(f"{snap['question']} [{snap['outcome']}]: {len(snap['bids'])} bids, {len(snap['asks'])} asks")
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['price']}")
asyncio.run(stream_orderbook())
npx wscat -c "wss://ob.polynode.dev/ws?key=pn_live_YOUR_KEY"
# then send:
{"action":"subscribe","markets":["0x7cb525e831729325d651017f81cbcb6f1adde5011c7b2283babea00b4ae93ae7"]}
What makes PolyNode different
| Feature | PolyNode | Other providers |
|---|---|---|
| Pending settlements (pre-chain) | 2–5 seconds early (1–2 blocks) | Not available |
| Decoded Polymarket data | Enriched with market titles, outcomes, slugs | Raw logs only |
| WebSocket filtering | By wallet, token, slug, side, size | Generic log filters |
| Orderbook, candles, stats | CLOB proxying + enriched analytics | Separate service |
Base URL
REST: https://api.polynode.dev
WebSocket: wss://ws.polynode.dev/ws?key=YOUR_KEY
x-api-key header (REST) or ?key= query param (WebSocket).
