Stream real-time, normalized prediction market data over WebSocket. One connection gives you cross-venue orderbooks, trades, and probability distributions from both Kalshi and Polymarket — no venue-specific code needed.
Data is addressed by what, not where. You subscribe to dist:fomc-2026-04-29 or dist:btc-5m-2026-03-24-0830-et, not a venue-specific ticker. Both venues arrive on the same channel, tagged by venue field.
Two feeds are available:
- Macro feed — FOMC, CPI, NFP, GDP, unemployment, equities, commodities
- Crypto feed — BTC and ETH prediction markets enriched with real-time Binance spot/futures data
wss://feeds.oddpool.com/ws
Authentication
Send an auth message with your API key after connecting. The server responds with your tier and limits.
// Send
{"action": "auth", "api_key": "oddpool_abc123..."}
// Response
{
"type": "auth",
"status": "ok",
"user_id": 42,
"tier": "pro",
"limits": {
"max_events": 10,
"max_connections": 3,
"channels": ["dist", "book", "trade", "snapshot"]
}
}
max_events: 0 means unlimited (Premium tier and above). Any positive number is the cap.
Subscribe and unsubscribe
Subscribe to channels by event. Events count as concurrent subscriptions — unsubscribing frees up slots.
| Format | Example | Scope |
|---|
{type}:{event_key} | dist:fomc-2026-04-29 | All outcomes for that event |
{type}:{event_key}:{outcome} | book:fomc-2026-04-29:hold | Single outcome |
Example
// Subscribe to multiple channels at once
{"action": "subscribe", "channels": ["dist:fomc-2026-04-29", "book:fomc-2026-04-29:hold"]}
// Response
{"type": "subscribed", "channels": ["dist:fomc-2026-04-29", "book:fomc-2026-04-29:hold"]}
// Unsubscribe
{"action": "unsubscribe", "channels": ["book:fomc-2026-04-29:hold"]}
Subscribe response shape
channels lists the channels that were actually subscribed. If any submitted channel was dropped, the response also includes a rejected array — only present when there is at least one rejection. Each entry has a channel and a reason:
reason | When it fires |
|---|
unknown_event_key | The event_key is not currently served. Use Catalog to find valid keys; venue-native IDs (Kalshi market tickers, Polymarket condition IDs) are not event keys. |
unknown_channel_type | The prefix is not one of dist, book, trade, snapshot. |
missing_event_key | The channel string has no event_key after the type prefix. |
// Mixed batch
{"action": "subscribe", "channels": ["dist:fomc-2026-04-29", "dist:not-a-real-event"]}
// Response
{
"type": "subscribed",
"channels": ["dist:fomc-2026-04-29"],
"rejected": [
{"channel": "dist:not-a-real-event", "reason": "unknown_event_key", "event_key": "not-a-real-event"}
]
}
dist, book, and trade are change-driven — messages emit only when the underlying state changes, so an idle channel is normal during quiet windows. For current state on connect, also subscribe to snapshot:{event_key}, which delivers a full state message every 60 seconds.