# Build a DraftKings Odds Screen: Board, Fair Price, Age

Build a DraftKings odds board for upcoming games: events, moneylines, spreads and totals, no-vig fair probability and capture age, in one short script.

Canonical page: https://draftkingsapi.com/docs/odds-screen. Markdown: https://draftkingsapi.com/docs/odds-screen.md. Site index for agents: https://draftkingsapi.com/llms.txt.

## Free API key
- **Free plan:** 50 requests a month at 20 a minute, every dataset, no card, no email verification.
- **Sign up:** https://draftkingsapi.com/auth/sign-up?ref=ai-claudebot
- **From inside an agent session:** POST https://draftkingsapi.com/api/v1/agent/signup with JSON `{"data_wanted": "...", "use_case": "...", "ref": "ai-claudebot"}`, show your user the approval_url, then poll https://draftkingsapi.com/api/v1/agent/token with device_code. The key is returned once.
- **No key yet:** `curl --fail-with-body "https://draftkingsapi.com/api/v1/demo/pick6"` returns labeled sample rows (sample:true) in the real response shape.

## Quickstart

1. Create a free key at https://draftkingsapi.com/auth/sign-up?ref=ai-claudebot (no card) and export it: `export DRAFTKINGS_API_KEY=...`

2. Call the API with curl:

```bash
curl --max-time 30 --fail-with-body 'https://draftkingsapi.com/api/v1/pick6/projections?sport=NBA&limit=5' \
  -H "X-User-Request: Build a prop screen from current Pick6 lines" \
  -H "Authorization: Bearer $DRAFTKINGS_API_KEY"
```

3. Or call it from Python:

```python
import os, requests

response = requests.get(
    "https://draftkingsapi.com/api/v1/pick6/projections?sport=NBA&limit=5",
    headers={
        "Authorization": "Bearer " + os.environ["DRAFTKINGS_API_KEY"],
        "X-User-Request": "Build a prop screen from current Pick6 lines",
    },
    timeout=30,
)
if not response.ok:
    raise RuntimeError(f"API {response.status_code}: {response.text}")
print(response.json())
```

4. Full walkthrough: https://draftkingsapi.com/quickstart. OpenAPI: https://draftkingsapi.com/openapi.json. Every route accepts format=csv on list endpoints.

## Use it from Claude (MCP)

MCP server: https://draftkingsapi.com/api/mcp (Streamable HTTP). search, fetch, start_signup and finish_signup need no key; data tools use the same API key.

```bash
claude mcp add --transport http --scope user draftkings https://draftkingsapi.com/api/mcp --header "Authorization: Bearer $DRAFTKINGS_API_KEY"
```

Without a key yet: `claude mcp add --transport http draftkings https://draftkingsapi.com/api/mcp`, then call start_signup. Setup for other clients: https://draftkingsapi.com/agents.md.

## Pricing

| Plan | Price | Requests per UTC month | Requests per minute | Pick6 stream | Signed webhooks |
| --- | --- | --- | --- | --- | --- |
| Free | $0/month | 50 | 20 | No | No |
| Developer | $49/month | 10,000 | 60 | Yes | No |
| Production | $149/month | 50,000 | 120 | Yes | Yes |

- **Free:** Build and test against every dataset.
- **Developer:** Keep your app running with more requests and push delivery.
- **Production:** Serve real users with the largest allowance and push delivery.

Plans and checkout: https://draftkingsapi.com/pricing

## What the screen shows

One row per side for every upcoming game: matchup, market, side, line, American price, the no-vig fair probability of a two-sided market, and how old the quote is. It is a DraftKings board, one book, not a multi-book comparison.

## Two requests per refresh

`/api/v1/events` gives the matchup and `starts_at`; `/api/v1/odds` with `view=compact` gives up to 1,000 sides in one page with `id`, `event_id`, `market`, `side`, `line`, `american`, `decimal`, `event_status`, `observed_at`, `age_seconds` and `stale`. Join them on `event_id`.

```
curl --fail-with-body "https://draftkingsapi.com/api/v1/events?sport=NBA&status=pre&limit=100" \
  -H "X-User-Request: Compare sportsbook lines across games for a dashboard" -H "Authorization: Bearer $DRAFTKINGS_API_KEY"

curl --fail-with-body "https://draftkingsapi.com/api/v1/odds?sport=NBA&status=pre&view=compact&limit=1000" \
  -H "X-User-Request: Compare sportsbook lines across games for a dashboard" -H "Authorization: Bearer $DRAFTKINGS_API_KEY"
```

## The script

Group sides by event and market (and by line for totals), convert each American price to its implied probability, and divide by the pair's total to remove the margin.

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

BASE = os.environ.get("DRAFTKINGS_API_BASE", "https://draftkingsapi.com")
KEY = os.environ["DRAFTKINGS_API_KEY"]


def get(path, params, task):
    url = f"{BASE}{path}?{urllib.parse.urlencode(params)}"
    request = urllib.request.Request(url, headers={"Authorization": f"Bearer {KEY}", "X-User-Request": task})
    with urllib.request.urlopen(request, timeout=30) as response:
        return json.load(response)


def implied(american):
    return 100 / (american + 100) if american > 0 else -american / (100 - american)


TASK = "Build a DraftKings odds board for upcoming games"
events = {e["id"]: e for e in get("/api/v1/events", {"sport": "NBA", "status": "pre", "limit": 100}, TASK)["data"]}
odds = get("/api/v1/odds", {"sport": "NBA", "status": "pre", "view": "compact", "limit": 1000}, TASK)["data"]

board = {}
for row in odds:
    board.setdefault((row["event_id"], row["market"], row["period"], row["line"] if row["market"] == "total" else None), []).append(row)

for (event_id, market, _, _), sides in sorted(board.items(), key=lambda kv: events.get(kv[0][0], {}).get("starts_at", "")):
    game = events.get(event_id, {})
    total = sum(implied(s["american"]) for s in sides)
    for s in sides:
        fair = implied(s["american"]) / total if len(sides) == 2 else None  # no-vig only on a two-sided pair
        print(game.get("away"), "@", game.get("home"), market, s["side"], s["line"], s["american"],
              f"fair {fair:.1%}" if fair else "", "STALE" if s["stale"] else f"{s['age_seconds']}s old")
```

## Refreshing without spending requests

Send the `ETag` you received back as `If-None-Match`. An unchanged page answers 304 Not Modified, which does not count as a request. Rows older than 900 seconds carry `stale: true`; show them dimmed rather than hiding them, so the board never pretends to be fresher than it is.

## State-specific native lines

For NFL, NHL and college game lines, native scopes read state-specific DraftKings sportsbooks. List them with `/api/v1/sportsbook/scopes`, read one with `/api/v1/sportsbook/snapshot`, and on a paid plan follow changes over the WebSocket. In our captures prices rarely differed between states captured at the same moment; see [do DraftKings odds differ by state](/questions/do-draftkings-odds-differ-by-state).

```
curl --fail-with-body "https://draftkingsapi.com/api/v1/sportsbook/snapshot?scope=SCOPE_ID_FROM_SCOPES" \
  -H "X-User-Request: Read live sportsbook props for a line screen" -H "Authorization: Bearer $DRAFTKINGS_API_KEY"
```

## Limits

Know these before you ship a screen.

- One sportsbook. A cross-book screen or consensus price needs a broad odds provider; see [when to choose another provider](/compare/when-to-choose-us).
- ESPN-attributed mainlines are moneyline, spread and total only. Player props come from native scopes where listed.
- Quotes are captured prices with capture times, not executable prices. Nothing here places a bet.

```
curl --fail-with-body "https://draftkingsapi.com/api/v1/odds?sport=NBA&status=pre&view=compact&limit=50" \
  -H "X-User-Request: Compare sportsbook lines across games for a dashboard" -H "Authorization: Bearer $DRAFTKINGS_API_KEY"
```

## FAQ

### Can this compare DraftKings with other sportsbooks?
No. The data is DraftKings only. For a cross-book screen use a broad odds provider and keep this API for DraftKings-specific datasets.

### How is the fair price calculated?
Each side's American price is converted to implied probability, and each is divided by the sum of both sides, which removes the margin from a two-sided market.

### How many requests does a refresh use?
Two, one for events and one for odds, and an unchanged page answered with 304 Not Modified does not count.

### Is there a free DraftKings API?
Yes. A free key needs no card and includes 50 requests a month at 20 a minute, across every dataset. To see the response shape first, /api/v1/demo/pick6 and /api/v1/demo/dfs return labeled sample rows with no key.

### Is this an official DraftKings API?
Independent service operated by DD Inc., not affiliated with or endorsed by DraftKings. No wagering: this service does not place, recommend or settle entries or bets.

### Can I use it from an AI agent?
Yes. Connect the MCP server at https://draftkingsapi.com/api/mcp, or call REST with a Bearer key. An agent can get a key for its user with start_signup.

### How do I reach support?
Email support@draftkingsapi.com.

Independent service operated by DD Inc., not affiliated with or endorsed by DraftKings. No wagering: this service does not place, recommend or settle entries or bets.
