# DraftKings API in R: Pick6, Odds and DFS With httr2

Pull DraftKings Pick6 lines, sportsbook odds and DFS salaries into R data frames with httr2, cursor paging and native CSV. Free API key, no card.

Canonical page: https://draftkingsapi.com/draftkings-api-r. Markdown: https://draftkingsapi.com/draftkings-api-r.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

## One function for every endpoint

Every endpoint is plain HTTPS with a Bearer header, so R needs no SDK. `httr2` sends the header, `jsonlite` (through `resp_body_json`) turns the response into a data frame. Keep the key in `~/.Renviron` as `DRAFTKINGS_API_KEY`; the API rejects keys passed in a URL.

```
# install.packages(c("httr2", "jsonlite"))
library(httr2)

base <- Sys.getenv("DRAFTKINGS_API_BASE", "https://draftkingsapi.com")
key <- Sys.getenv("DRAFTKINGS_API_KEY")  # set it in ~/.Renviron, never in a script

dk_get <- function(path, ...) {
  request(base) |>
    req_url_path(path) |>
    req_url_query(...) |>
    req_headers(
      Authorization = paste("Bearer", key),
      `X-User-Request` = "Pull DraftKings rows into R for analysis"
    ) |>
    req_timeout(30) |>
    req_perform() |>
    resp_body_json(simplifyVector = TRUE)
}
```

## Pick6 lines into a data frame

`view=compact` returns flat rows, one column per field, and allows up to 1,000 rows a page. `is_default` marks the main target for a player and stat; the other rows are ladder rungs.

```
page <- dk_get("/api/v1/pick6/projections",
  sport = "NBA", stat = "Points", status = "open", view = "compact", limit = 1000)
lines <- page$data
main <- lines[lines$is_default %in% TRUE, ]  # one main target per player and stat
main[order(-main$target_value), c("player", "team", "opponent", "target_value",
  "more_multiplier", "less_multiplier", "observed_at", "stale")]
```

`more_multiplier` and `less_multiplier` are Pick6 standings multipliers. They are not decimal odds, a probability or an entry payout, so do not convert them like prices. `observed_at` is when the row was captured, and `stale` turns true after 900 seconds.

## Paging without spending your quota

Each call is one request against your monthly allowance. Follow `pagination.next_cursor` unchanged, and cap the number of pages so a loop in an R session cannot drain the plan.

```
# Follow next_cursor, and stop at a page budget so a loop cannot spend your quota.
dk_rows <- function(path, ..., max_pages = 3) {
  out <- list(); cursor <- NULL
  for (i in seq_len(max_pages)) {
    page <- if (is.null(cursor)) dk_get(path, ...) else dk_get(path, ..., cursor = cursor)
    out[[i]] <- page$data
    if (!isTRUE(page$pagination$has_more)) break
    cursor <- page$pagination$next_cursor
  }
  do.call(rbind, out)
}

odds <- dk_rows("/api/v1/odds", sport = "NFL", status = "pre", view = "compact", limit = 1000)
odds$line <- as.numeric(odds$line)  # a numeric string, or empty on a moneyline
table(odds$market, odds$side)
```

## Native CSV with read.csv

Pick6, sportsbook mainlines and DFS accept `format=csv`. The native file keeps the source record in one JSON `data` column so nothing is lost; use `view=compact` JSON when you want one column per field.

```
# Native CSV, read straight into a data frame.
csv <- request(base) |>
  req_url_path("/api/v1/dfs/players") |>
  req_url_query(sport = "NFL", limit = 100, format = "csv") |>
  req_headers(Authorization = paste("Bearer", key)) |>
  req_perform() |>
  resp_body_string()
salaries <- read.csv(text = csv)
nrow(salaries)
```

## Joining to box scores

Statistics come from independent ESPN snapshots at `/api/v1/stats/player-games`, JSON only, with required `sport` and `season`. IDs there are ESPN IDs, not DraftKings IDs, so match on player and game with care and keep `observed_at` from each side to avoid look-ahead in a model.

```
games <- dk_get("/api/v1/stats/player-games", sport = "NBA", season = 2027, completed = "true", limit = 200)
str(games$data, max.level = 1)
# Next page: pass games$pagination$next as after. Statistics use after, not cursor.
```

The [player game logs guide](/guides/player-game-logs) covers season conventions and IDs, and [point-in-time data](/guides/point-in-time-data) covers leakage.

```
curl --fail-with-body "https://draftkingsapi.com/api/v1/coverage" \
  -H "X-User-Request: Check which DraftKings datasets fit a new app" -H "Authorization: Bearer $DRAFTKINGS_API_KEY"
```

## FAQ

### Is there an R package for the DraftKings API?
No package is needed. Any HTTP client that can send an Authorization header works, and the examples on this page use httr2.

### Can I read the data with read.csv?
Yes. Pick6, sportsbook mainlines and DFS accept format=csv. Read the response body as a string and pass it to read.csv. Statistics are JSON only.

### How many requests does an R session use?
Each API call is one request. The Free plan includes 50 requests a month at 20 a minute, so cap your paging loops and cache results locally while you explore.

### Should I put the key in my R script?
No. Keep it in ~/.Renviron or another secret store and read it with Sys.getenv. Keys in URLs are rejected.

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