API · Riferimento

Polymarket ha due sistemi in tempo reale, su due host diversi. Il WebSocket del CLOB trasmette l'order book e gli aggiornamenti dei tuoi ordini; il feed RTDS trasmette i dati di prezzo in tempo reale (crypto, azioni) e i commenti. Confondere i due è l'errore più comune - questa pagina li tiene distinti, con gli endpoint esatti, l'heartbeat e un reconnect corretto.

I due host
  • CLOB - wss://ws-subscriptions-clob.polymarket.com/ws/ · canali market (pubblico, order book), user (auth, i tuoi ordini/fill), sports (stato live delle partite per i mercati sportivi) e un gateway rfq (stato live delle Request-for-Quote - vedi la sezione RFQ).
  • RTDS - wss://ws-live-data.polymarket.com · topic crypto_prices, crypto_prices_chainlink, equity_prices, comments.

Canale market del CLOB (senza auth)

Fai la subscribe a uno o più token ID e ricevi l'order book e gli aggiornamenti: uno snapshot iniziale book, poi eventi price_change, tick_size_change e last_trade_price. Nessuna credenziale richiesta.

import asyncio, json, websockets

async def stream(token_ids):
    url = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
    async with websockets.connect(url, ping_interval=10) as ws:
        await ws.send(json.dumps({"assets_ids": token_ids, "type": "market"}))
        async for msg in ws:
            evt = json.loads(msg)
            print(evt.get("event_type"), evt)

asyncio.run(stream([TOKEN_ID]))
import WebSocket from "ws";
const ws = new WebSocket("wss://ws-subscriptions-clob.polymarket.com/ws/market");
ws.on("open", () => ws.send(JSON.stringify({ assets_ids: [TOKEN_ID], type: "market" })));
ws.on("message", (d) => console.log(JSON.parse(d)));

Canale user del CLOB (auth)

Il canale user riporta il ciclo di vita dei tuoi ordini (piazzamenti, match, cancellazioni). Richiede API key/secret/passphrase e fai la subscribe per condition_id (mercato), non per token ID. Connettiti a wss://ws-subscriptions-clob.polymarket.com/ws/user e includi la tua auth nel payload di subscribe:

await ws.send(json.dumps({
    "type": "user",
    "markets": [CONDITION_ID],          # subscribe by condition_id, not token_id
    "auth": {"apiKey": API_KEY, "secret": SECRET, "passphrase": PASSPHRASE},
}))
# events: "order" (placed/cancelled) and "trade" (your fills)

Feed prezzi RTDS

Un host separato - wss://ws-live-data.polymarket.com - per i dati di prezzo in tempo reale, non per gli order book. Fai la subscribe a un topic: crypto_prices (Binance), crypto_prices_chainlink (oracolo Chainlink), equity_prices o comments. Utile per il segnale sottostante nei bot su mercati di previsione crypto/azionari.

Heartbeat e reconnect

  • Heartbeat - invia un PING circa ogni 10 secondi; il server risponde PONG. Se lo salti, la connessione cade.
  • Modifica live - puoi aggiungere/rimuovere topic o asset su una connessione aperta; non devi riconnetterti per cambiare la tua subscription.
  • Riconnettiti correttamente - dopo ogni caduta, riscarica lo snapshot REST dell'order book (GET /book) prima di fidarti di nuovo degli aggiornamenti incrementali. I delta trasmessi che hai perso mentre eri disconnesso sono persi; lo snapshot REST risincronizza il tuo order book locale.

L'intero pattern in un unico loop resiliente - heartbeat, reconnect con backoff e una risincronizzazione REST a ogni (ri)connessione:

import asyncio, json, time, requests, websockets

async def resilient_stream(token_id, on_event):
    url = "wss://ws-subscriptions-clob.polymarket.com/ws/market"
    backoff = 1
    while True:
        try:
            async with websockets.connect(url, ping_interval=10) as ws:
                # 1) REST snapshot first so the local book is correct before deltas
                book = requests.get("https://clob.polymarket.com/book",
                                    params={"token_id": token_id}).json()
                on_event({"event_type": "snapshot", "book": book})
                # 2) subscribe and stream
                await ws.send(json.dumps({"assets_ids": [token_id], "type": "market"}))
                backoff = 1                       # reset after a clean connect
                async for msg in ws:
                    on_event(json.loads(msg))
        except Exception as e:
            print("ws drop, resync in", backoff, "s:", e)
            await asyncio.sleep(backoff)
            backoff = min(backoff * 2, 30)        # exponential backoff, capped
Non confondere gli host. Gli order book e i tuoi ordini arrivano dall'host CLOB (ws-subscriptions-clob); i prezzi crypto/azionari e i commenti arrivano dall'RTDS (ws-live-data). Sono servizi diversi con payload diversi.

Avanti: Riferimento REST del CLOB · Rate limit e backoff · Progetto: streamma l'order book in un bot.