# Live odds API: in-play observations and streamed price changes

GetOdds gives you two live paths. /api/v1/events/live lists FanDuel games with an in-play market observed in the last 15 minutes, and you can then read those games' FanDuel markets and prices. For pregame lines that keep moving, a WebSocket at wss://getoddsapi.com/api/v1/odds/stream pushes retained DraftKings price changes every five seconds. It is not a sub-second in-play trading feed.

Canonical page: https://getoddsapi.com/live-odds-api

**Price.** Free development allowance: 1,000 requests per UTC day and 60 per minute per account, with no payment step. Paid: the Developer Bundle at $149 per month, with 10,000 monthly requests or credits on each of four sources.

## Free API key

Get a free GetOdds API key: **1,000 requests per UTC day and 60 per minute, no card**. One key covers REST and the hosted MCP server.

Sign up: https://getoddsapi.com/sign-up?ref=ai-claudebot

## Quickstart

1. Create an account at https://getoddsapi.com/sign-up?ref=ai-claudebot, open https://getoddsapi.com/dashboard and issue a key with the sources you need (draftkings, fanduel, betrivers, prizepicks or underdog). Keep it in a server environment variable named GETODDS_API_KEY.
2. Read current DraftKings NBA spreads with curl:

```bash
curl --fail-with-body "https://getoddsapi.com/api/v1/odds?sport=NBA&market=spread&fresh_only=true&limit=50" \
  -H "Authorization: Bearer $GETODDS_API_KEY"
```

3. The same request in Python (standard library only):

```python
import json, os, urllib.request

req = urllib.request.Request(
    "https://getoddsapi.com/api/v1/odds?sport=NBA&market=spread&fresh_only=true&limit=50",
    headers={"Authorization": "Bearer " + os.environ["GETODDS_API_KEY"]},
)
with urllib.request.urlopen(req) as res:
    rows = json.load(res)["data"]
for row in rows:
    print(row["away"], "at", row["home"], row["side"], row["line"], row["american"], row["observed_at"])
```

4. Check `observed_at`, `age_seconds` and `stale` on every row before using a price. Full reference: https://getoddsapi.com/docs

## Use with Claude (MCP)

```bash
claude mcp add --transport http getodds https://getoddsapi.com/api/mcp \
  --header "Authorization: Bearer $GETODDS_API_KEY"
```

The MCP tools follow the key's source grants and share its allowance. Setup guide: https://getoddsapi.com/use-with-claude

## Pricing

| Plan | Allowance | Price |
| --- | --- | --- |
| Free key | 1,000 requests a day, 60 a minute | $0, no card |
| Developer Bundle | 10,000 requests or credits a month on each of four sources | $149 a month |

Free development allowance: 1,000 requests per UTC day and 60 per minute per account, with no payment step. Paid: the Developer Bundle at $149 per month, with 10,000 monthly requests or credits on each of four sources.
Details: https://getoddsapi.com/bundle

## Facts

- **In-play source:** FanDuel (NJ)
- **Stream:** WebSocket, 5-second polls
- **Freshness window:** 15 minutes
- **Concurrent sockets:** 2 per account

## Find games that are in play right now

Create an account at /sign-up, open /dashboard and issue a key with the source grants you need (draftkings, fanduel, betrivers, prizepicks or underdog). Keep the key in a server environment variable named GETODDS_API_KEY and send it as a bearer token. Never put it in a URL or in browser code.

The live events endpoint needs a key with the fanduel grant but not a bookmaker selection, because it returns no prices. A game qualifies when one of its non-futures markets was open or suspended, flagged in_play, and observed in the last 15 minutes. Take an event_id from the response and read its markets with /api/v1/sportsbook/markets, which does require FanDuel to be selected on the account.

```bash
curl --fail-with-body "https://getoddsapi.com/api/v1/events/live?league=NBA&limit=20" \
  -H "Authorization: Bearer $GETODDS_API_KEY"

curl --fail-with-body "https://getoddsapi.com/api/v1/sportsbook/markets?event_id=FANDUEL_EVENT_ID&limit=100" \
  -H "Authorization: Bearer $GETODDS_API_KEY"
```

## Stream price changes over a WebSocket

The stream needs the draftkings grant and DraftKings selected. Connect from a server, because browsers cannot set the Authorization header on a WebSocket. Frames are welcome, changes, checkpoint and replay_complete. Save pagination.next_after only after you have processed a frame, and reconnect from that checkpoint: sessions close after at most 240 seconds with code 1012 by design.

```javascript
import WebSocket from "ws";

let checkpoint = "0"; // persist this in your database in production
function connect() {
  const socket = new WebSocket(
    `wss://getoddsapi.com/api/v1/odds/stream?after=${checkpoint}&sport=NBA&limit=100`,
    { headers: { Authorization: `Bearer ${process.env.GETODDS_API_KEY}` } }
  );
  socket.on("message", raw => {
    const frame = JSON.parse(String(raw));
    if (frame.type === "changes") for (const row of frame.data) console.log(row.event_id, row.side, row.american, row.observed_at);
    if (frame.pagination?.next_after) checkpoint = frame.pagination.next_after;
  });
  socket.on("close", code => { if (code === 1012) setTimeout(connect, 1000); else console.error("closed", code); });
}
connect();
```

## Know the limits before you build on it

- FanDuel unchanged markets refresh their stored observation about every five minutes; a changed price is recorded when the collector sees it.
- An event missing from /events/live may simply be unobserved. Absence never means the game ended.
- The stream delivers what was captured. A live socket does not make an old observation new, and capture is not complete across every market.
- Each successful five-second poll on the socket costs one data credit, including empty polls. A full hour on one socket is 720 credits.
- For true in-play trading with sub-second latency and dozens of books, an enterprise feed such as OpticOdds is the better fit.

## FAQ

### Does GetOdds have live in-play odds?

Partly. FanDuel in-play market observations are available through /api/v1/events/live and /api/v1/sportsbook/markets. DraftKings data is pregame. Neither is a guaranteed sub-second in-play feed.

### Is the stream a WebSocket or Server-Sent Events?

A real WebSocket at wss://getoddsapi.com/api/v1/odds/stream. A plain HTTP GET to that URL returns 426.

### How many live connections can I open?

Two sockets per account across all keys. A third upgrade returns 429.

### What happens if my socket drops?

Reconnect with the last checkpoint you committed. The server does not track acknowledgements, so tolerate repeated seq values and deduplicate on them.

---

GetOdds is an independent developer product and is not affiliated with any sportsbook or pick’em operator. Prices describe data, not betting advice.
