Real-time sports odds

Odds WebSocket API

Stop polling. One authenticated WebSocket delivers a snapshot of everything you subscribed to, then only the markets that changed — with optional permessage-deflate compression.

01Real-time sports odds

Subscribe with filters

Send {"type":"subscribe","sports":["soccer"],"live":true,"markets":["moneyline","total"]} and the server filters before sending. Change the subscription at any time without reconnecting.

02Real-time sports odds

Delta updates

After a chunked snapshot, every message is a delta batch: market upserts with full outcome prices and explicit removals when a market is suspended, settled or the event ends.

03Real-time sports odds

Built for production

Heartbeats every 20 seconds, documented close codes, a sequence number per batch, per-key connection limits and back-pressure protection. Reconnect and resubscribe to resync.

04Real-time sports odds

Any language

It is a plain WebSocket with JSON frames. Our docs include working clients in Python and Node.js; anything that speaks WebSocket works.

# pip install websockets
import asyncio, json, os, websockets

async def main():
    url = "wss://pinnfeed.io/v1/stream"
    async with websockets.connect(url, additional_headers={"x-api-key": os.environ["PINNSOCKET_KEY"]}) as ws:
        await ws.send(json.dumps({"type": "subscribe", "sports": ["soccer"], "live": True}))
        async for raw in ws:
            msg = json.loads(raw)
            if msg["type"] == "ping": await ws.send('{"type":"pong"}')
            elif msg["type"] == "delta":
                for c in msg["changes"]:
                    if c["kind"] == "market" and c["op"] == "upsert":
                        m = c["market"]; print(m["key"], [(o["name"], o["decimal"], o["fair"]) for o in m["outcomes"]])

asyncio.run(main())
{
  "type": "delta", "seq": 48213, "ts": 1762679412093,
  "changes": [{
    "kind": "market", "op": "upsert",
    "market": {
      "id": "1640278226:s;0;m", "eventId": 1640278226,
      "type": "moneyline", "period": 0, "main": true, "live": true,
      "margin": 0.0357, "maxStake": 1500,
      "outcomes": [
        { "name": "home", "american": -128, "decimal": 1.781, "fair": 1.845, "fairProb": 0.5421 },
        { "name": "draw", "american": 262,  "decimal": 3.62,  "fair": 3.750, "fairProb": 0.2667 },
        { "name": "away", "american": 405,  "decimal": 5.05,  "fair": 5.230, "fairProb": 0.1912 }
      ]
    }
  }]
}
FAQ

Odds WebSocket API: common questions

Is compression supported?

Yes. Clients that negotiate permessage-deflate receive compressed frames, typically 5–10× smaller.

How many connections can I open?

Hobby 1, Builder 3, Pro 10, Enterprise custom — per account, across all keys.

Is there a REST fallback?

Yes. Every plan includes REST snapshot endpoints with the same schema.

Try it free today.

Delayed REST data free forever. Real-time WebSocket from $29/mo.