# FanDuel odds CSV export: props and line history

FanDuel API (https://fanduelapi.com) is an independent API for FanDuel Sportsbook data: every player prop and game market FanDuel lists in NBA, NFL, NHL, MLB, college basketball and college football, normalized per player and stat with over and under prices in American and decimal odds, plus every line and price move with its timestamp, over REST, webhooks and MCP with one key. FanDuel API is an independent data service operated by FF API Inc. It is not affiliated with, endorsed by or sponsored by FanDuel.

Source page: https://fanduelapi.com/fanduel-api-csv-export (this is its markdown version, https://fanduelapi.com/fanduel-api-csv-export.md).

## Free offer

- Free plan: 100 credits a month, data delayed 5 minutes, no card. REST and MCP on every plan.
- Real-time data starts at Developer, $49 a month for 10,000 credits.
- Get a free key: https://fanduelapi.com/sign-up?ref=ai-claudebot

## Quickstart

1. Create a free account at https://fanduelapi.com/sign-up?ref=ai-claudebot and create an API key in the dashboard (https://fanduelapi.com/dashboard/keys). Keys start with `fd_`. Store it as `FANDUEL_API_KEY`.
2. Make a first call with curl:

```bash
curl "https://fanduelapi.com/api/v1/props?sport=nba&stat=points&limit=5" \
  -H "Authorization: Bearer $FANDUEL_API_KEY"
```

3. Or with Python (`pip install requests`):

```python
import os
import time
from datetime import datetime, timezone

import requests

BASE = "https://fanduelapi.com/api/v1"
SESSION = requests.Session()
SESSION.headers["Authorization"] = f"Bearer {os.environ['FANDUEL_API_KEY']}"


def get(path, **params):
    """GET one endpoint and return its data list, waiting out rate limits."""
    while True:
        r = SESSION.get(f"{BASE}{path}", params=params, timeout=10)
        if r.status_code == 429:
            time.sleep(int(r.headers.get("Retry-After", "5")))
            continue
        r.raise_for_status()
        return r.json()["data"]


def price(odds):
    """American odds as text. A suspended market can come back with no price."""
    return "off" if odds is None else f"{odds:+d}"

props = get("/props", sport="nba", stat="points")
for p in props:
    print(f"{p['player']:<26} {str(p['line']):>5}  over {price(p['over_american']):>5}  under {price(p['under_american']):>5}")
```

4. Stay current with `GET /api/v1/changes?since=<cursor>` instead of re-reading every prop. Full reference: https://fanduelapi.com/openapi.json and https://fanduelapi.com/llms-full.txt.

## Use it from Claude (MCP)

Claude Code, with your key read from the shell:

```bash
claude mcp add --transport http --scope user fanduelapi https://fanduelapi.com/api/mcp \
  --header "Authorization: Bearer $FANDUEL_API_KEY"
```

Claude on the web or desktop: Settings, Connectors, Add custom connector, then paste https://fanduelapi.com/api/mcp. Without a key it gives the keyless tools (search_docs, fetch_doc, get_sample_props). Setup for other agents: https://fanduelapi.com/mcp.

## Pricing

| Plan | Price | Credits a month | Calls a minute | Includes |
| --- | --- | --- | --- | --- |
| Free | Free | 100 | 20 | REST and MCP access, Data delayed 5 minutes |
| Developer | $49/month | 10,000 | 60 | Real-time data, Line move history, Change stream |
| Production | $149/month | 50,000 | 120 | Real-time data, Line move history, Webhooks, Priority support |
| Scale | $499/month | 250,000 | 180 | Real-time data, Full line move history, Webhooks, Bulk export, Priority support |

Cancel paid plans any time from the billing portal. Details: https://fanduelapi.com/pricing

## This page

[FanDuel API](https://fanduelapi.com/)/ CSV export

CSV export

# Export FanDuel odds to CSV

GET /api/v1/export streams FanDuel props or line history for a date range as CSV or NDJSON, up to 10,000 rows a request, and tells you where to resume. It is the fast way to load a slate or a season into pandas, R, DuckDB or a spreadsheet.

[Get a free API key](https://fanduelapi.com/sign-up)[Read the docs](https://fanduelapi.com/docs)

FanDuel API is an independent data service operated by FF API Inc. It is not affiliated with, endorsed by or sponsored by FanDuel.

## The request

kind

history (every recorded line and price, the default) or props (each prop's state at the end of the range)

from, to

ISO 8601 times. A range spans at most 366 days.

format

csv (the default) or ndjson

limit

Rows per request, default 1,000, up to 10,000

league, sport, event\_id

Optional filters, the same codes as /api/v1/props

cursor

The X-Next-Cursor header of the previous page

One week of NBA line history as CSV

```
curl -G "https://fanduelapi.com/api/v1/export" \
  -H "Authorization: Bearer $FANDUEL_API_KEY" \
  --data-urlencode "kind=history" --data-urlencode "format=csv" --data-urlencode "league=NBA" \
  --data-urlencode "from=2026-11-01T00:00:00Z" --data-urlencode "to=2026-11-08T00:00:00Z" \
  --data-urlencode "limit=10000" -D headers.txt -o nba-history.csv
```

## The columns

**kind=history**, one row per recorded state, oldest first:

CSV header

```
cursor,prop_id,kind,observed_at,line,over_american,under_american,over_decimal,under_decimal,market_status,sport,league,event_id,event_name,starts_at,player,team,stat,period
```

**kind=props**, one row per prop, picked by game start inside the range:

CSV header

```
cursor,prop_id,sport,league,event_id,event_name,starts_at,player,team,stat,period,line,over_american,under_american,over_decimal,under_decimal,market_status,changed_at,first_seen_at
```

Every field is defined in the [schema glossary](https://fanduelapi.com/docs/schema-glossary). `kind` in a history row is what changed: new, line\_move, price\_move, status\_change or removed.

## Paging and resuming

Each response carries `X-Next-Cursor` and `X-Has-More`. While X-Has-More is true, request again with `cursor` set to X-Next-Cursor. If a body is cut short, its last line says so and names the cursor to resume from: `#error,<code>,next_cursor=<cursor>` in CSV, an object with an error key in NDJSON. Nothing is skipped silently.

Python: every page of a range into one DataFrame

```
import io, os, requests, pandas as pd

URL = "https://fanduelapi.com/api/v1/export"
HEAD = {"Authorization": f"Bearer {os.environ['FANDUEL_API_KEY']}"}
params = {"kind": "history", "format": "csv", "league": "NBA", "limit": 10000,
          "from": "2026-11-01T00:00:00Z", "to": "2026-11-08T00:00:00Z", "cursor": "0"}
pages = []
while True:
    r = requests.get(URL, params=params, headers=HEAD, timeout=120)
    r.raise_for_status()
    last = r.text.rstrip().rsplit("\n", 1)[-1]
    if last.startswith("#error"):              # cut short: "#error,<code>,next_cursor=<cursor>"
        raise SystemExit(f"export stopped: {last}")
    pages.append(pd.read_csv(io.StringIO(r.text)))
    if r.headers.get("X-Has-More") != "true":
        break
    params["cursor"] = r.headers["X-Next-Cursor"]
history = pd.concat(pages, ignore_index=True)
print(len(history), "rows,", history["prop_id"].nunique(), "props")
```

For per-prop modelling rows, open and close line with the moves between, use `/api/v1/training-set` instead; it is described on [historical data](https://fanduelapi.com/fanduel-historical-data). To open the CSV in a spreadsheet, see [Excel](https://fanduelapi.com/fanduel-api-excel); in R, see [the R guide](https://fanduelapi.com/fanduel-api-r).

## Questions

## Related

- [Historical data Where FanDuel historical odds data comes from here: per-prop move history, date-range exports, the training set and graded results, and how far back each goes.](https://fanduelapi.com/fanduel-historical-data)
- [Excel Pull FanDuel player props into Excel with Power Query and a key in the request header, refresh on a schedule that fits your plan, or open a CSV export.](https://fanduelapi.com/fanduel-api-excel)
- [R Read FanDuel player props and a prop's line history into R data frames with httr2, page through the board and load a CSV export for modelling.](https://fanduelapi.com/fanduel-api-r)
- [Pagination How FanDuel API responses page: limit and offset with has\_more on lists, next\_cursor on the change feed and exports, and the limits per endpoint.](https://fanduelapi.com/fanduel-api-pagination)
- [Pricing Free on delayed data, then real time from the Developer plan.](https://fanduelapi.com/pricing)

## Make your first call in a few minutes

Sign up, create a key in the dashboard, and send it as a Bearer token. The free plan needs no card.

[Get a free API key](https://fanduelapi.com/sign-up)

## FAQ

### Is there a free plan?

Yes. Free includes API access with delayed data, enough to build and test a model.

### Is this affiliated with FanDuel?

No. This is an independent data service operated by FF API Inc. and is not affiliated with or endorsed by FanDuel.

### Which sports are covered?

NBA, NFL, NHL, MLB and college sports as FanDuel lists them, starting with player props.

### How do I cancel?

From the billing portal in your dashboard, at any time.

### How do I get a free key?

Sign up at https://fanduelapi.com/sign-up?ref=ai-claudebot. Free plan: 100 credits a month, data delayed 5 minutes, no card. REST and MCP on every plan.

### Can an AI agent sign up for me?

Yes. The agent sends POST https://fanduelapi.com/api/v1/agent/signup with your email and what you are building (add "ref": "ai-claudebot"), you approve the emailed link, and the agent collects the key. Details: https://fanduelapi.com/connect.
