# Closing Line Value With DraftKings Odds History

Measure closing line value on DraftKings sides: find the last recorded quote before start in odds history, compare it with your price, and know the limits.

Canonical page: https://draftkingsapi.com/docs/closing-line-value. Markdown: https://draftkingsapi.com/docs/closing-line-value.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 closing line value measures

Closing line value compares the price you took with the price at the close. If the closing implied probability is higher than the one you took, the market moved toward your side after you bet. It is a process measure, not a result, and it says nothing certain about any one bet.

## Finding the close in the history

`/api/v1/history` returns recorded changes for a side, in order, each with `observed_at` and the quote in `data`. History stores changes only, so the last change before the scheduled start is the price still standing at the start, as far as captures saw. `/api/v1/events` gives `starts_at`.

```
curl --fail-with-body "https://draftkingsapi.com/api/v1/odds?sport=NFL&status=pre&view=compact&limit=25" \
  -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/history?offer_id=OFFER_ID_FROM_ODDS&limit=100" \
  -H "X-User-Request: Compare sportsbook lines across games for a dashboard" -H "Authorization: Bearer $DRAFTKINGS_API_KEY"
```

## The script

Keep your own bet log with the offer id and the price you took. The script finds each side's last recorded quote before start and reports the difference in implied probability.

```
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)
from datetime import datetime

TASK = "Measure closing line value on my recorded bets"


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


def when(text):
    return datetime.fromisoformat(text.replace("Z", "+00:00"))


def closing_quote(offer_id, starts_at):
    """Last recorded state of one side before its scheduled start. History stores changes, in order."""
    page = get("/api/v1/history", {"offer_id": offer_id, "limit": 100}, TASK)
    before = [h for h in page["data"] if when(h["observed_at"]) < when(starts_at)]
    return before[-1]["data"] if before else None


# Your own bet log: the offer id from /api/v1/odds and the American price you took.
bets = [{"offer_id": "OFFER_ID_FROM_ODDS", "event_id": "EVENT_ID", "taken": -105}]
for bet in bets:
    event = get("/api/v1/events", {"event_id": bet["event_id"], "limit": 1}, TASK)["data"][0]
    close = closing_quote(bet["offer_id"], event["starts_at"])
    if close is None:
        print(bet["offer_id"], "no recorded quote before start")
        continue
    clv = implied(close["american"]) - implied(bet["taken"])   # positive: you beat the recorded close
    print(bet["offer_id"], "took", bet["taken"], "close", close["american"], f"CLV {clv:+.2%}", "closing quote captured", close["observed_at"])
```

## How far before start the last change was

Measured on 11 Nov 2026 over games that started from 4 Nov: the median time between the last recorded change and the scheduled start was about 6.7 hours in NBA, 8 hours in NHL and college basketball, 31 hours in NFL and 58 hours in college football. A long gap usually means the price did not move, not that capture stopped, but the history alone cannot prove which.

| League | Sides measured | Median minutes, last change to start | Median changes before start |
| --- | --- | --- | --- |
| NBA | 762 | 399 | 2 |
| NCAAB | 624 | 480 | 1 |
| NHL | 330 | 488 | 3 |
| NFL | 152 | 1,848 | 2 |
| NCAAF | 596 | 3,464 | 1 |
| MLS | 117 | 46 | 5 |
| EPL | 76 | 992 | 3 |

## Limits of this close

Treat it as a recorded close, not the official one.

- Captures run on rotating schedules, so a move in the final minutes before start can be missed. Check [reliability](/reliability) for measured intervals.
- This works on ESPN-attributed moneylines, spreads and totals, which have a history endpoint. Native sportsbook changes arrive over the WebSocket; keep your own log of them if you need a native close.
- History began in early November 2026; there are no seasons of closes to compare against.
- Nothing here places or settles a bet.

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

## FAQ

### What is closing line value?
The difference between the price you took and the closing price, usually expressed in implied probability. Positive means the market moved toward your side after you bet.

### Is the recorded close the official closing line?
No. It is the last quote captured before the scheduled start. A late move between captures can be missed.

### Can I measure CLV on player props?
Not from a history endpoint. ESPN-attributed mainlines have one; native sportsbook props stream changes over the WebSocket on paid plans, so log them yourself.

### 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.
