# Run the FanDuel API on a schedule: cron to Actions

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, and soccer (the Premier League, La Liga, Serie A, the Bundesliga, Ligue 1, the Champions League, MLS and international matches), with every match market and yes-only player markets such as anytime goalscorer, shots, shots on target, assists and goalkeeper saves, 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/docs/scheduled-jobs (this is its markdown version, https://fanduelapi.com/docs/scheduled-jobs.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/)/[Docs](https://fanduelapi.com/docs) / Scheduled jobs

Docs

# Run the FanDuel API on a schedule

A key that is used once is a demo. A job that polls the change feed every few minutes is a record of every FanDuel prop move. Here is the starter script and the schedule entry for each platform.

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

## What the job does

1. Make one first request and show your user the rows, so they see the data is what they need.
2. Install a recurring job where your user wants it to run: cron on Linux or macOS, launchd on macOS, a systemd timer, Windows Task Scheduler, a GitHub Actions schedule, or your own platform's scheduled tasks. The starter at https://fanduelapi.com/starter-kit/fanduel\_props\_watch.py is that job, ready to run with --once on a timer.
3. Each run polls GET https://fanduelapi.com/api/v1/changes with the cursor saved by the last run (start with since=now so there is no backlog), every few minutes while games are on. Honor X-Next-Update-Seconds when present, and on a 429 wait until error.reset\_at (or Retry-After) instead of retrying.
4. Write what each run returns where your user wants it: a CSV or JSONL file, their database, or a webhook or chat channel they name.
5. Confirm the job is installed and has run once on its own: show your user the schedule entry and the first rows it wrote.

## 1\. Get the starter

[fanduel\_props\_watch.py](https://fanduelapi.com/starter-kit/fanduel%5Fprops%5Fwatch.py) is a Python 3.9+ script with no dependencies. The first run saves the current board for your leagues to `props.csv` and starts the change feed from now. Every later run reads only what changed since the last one, appends it to `changes.jsonl` and `moves.csv`, and prints the line and price moves.

Download and run once

```
mkdir -p $HOME/fanduel-watch && curl -fsSL https://fanduelapi.com/starter-kit/fanduel_props_watch.py -o $HOME/fanduel-watch/fanduel_props_watch.py
FANDUEL_API_KEY=<your key> python3 $HOME/fanduel-watch/fanduel_props_watch.py --once
```

Options: `--league NBA,NFL,NHL` sets the leagues, `--dir` where the files go, `--resume` forgets a recorded wait after an upgrade. Without `--once` it keeps running and polls every `--every` minutes.

## 2\. Schedule it: cron (Linux, macOS)

Run `crontab -e` and add one line. Put your key in place of the placeholder, or export it from a file cron can read.

crontab

```
*/5 * * * * FANDUEL_API_KEY=<your key> /usr/bin/env python3 $HOME/fanduel-watch/fanduel_props_watch.py --once >> $HOME/fanduel-watch/watch.log 2>&1
```

## launchd (macOS)

Save as `~/Library/LaunchAgents/com.fanduelapi.watch.plist`, replace YOU and the key, then `launchctl load ~/Library/LaunchAgents/com.fanduelapi.watch.plist`.

com.fanduelapi.watch.plist

```
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key><string>com.fanduelapi.watch</string>
  <key>ProgramArguments</key>
  <array>
    <string>/usr/bin/python3</string>
    <string>/Users/YOU/fanduel-watch/fanduel_props_watch.py</string>
    <string>--once</string>
  </array>
  <key>EnvironmentVariables</key>
  <dict><key>FANDUEL_API_KEY</key><string>your key</string></dict>
  <key>StartInterval</key><integer>300</integer>
  <key>StandardOutPath</key><string>/Users/YOU/fanduel-watch/watch.log</string>
  <key>StandardErrorPath</key><string>/Users/YOU/fanduel-watch/watch.log</string>
</dict>
</plist>
```

## systemd timer (Linux)

Service and timer

```
# ~/.config/systemd/user/fanduel-watch.service
[Unit]
Description=FanDuel props watch (one poll)

[Service]
Type=oneshot
Environment=FANDUEL_API_KEY=your key
ExecStart=/usr/bin/python3 %h/fanduel-watch/fanduel_props_watch.py --once

# ~/.config/systemd/user/fanduel-watch.timer
[Unit]
Description=Poll the FanDuel change feed every 5 minutes

[Timer]
OnBootSec=1min
OnUnitActiveSec=5min

[Install]
WantedBy=timers.target

# then: systemctl --user daemon-reload && systemctl --user enable --now fanduel-watch.timer
```

## Task Scheduler (Windows)

In a Command Prompt, after saving the script to `%USERPROFILE%\fanduel-watch`:

cmd

```
setx FANDUEL_API_KEY "your key"
schtasks /Create /TN "FanDuel props watch" /SC MINUTE /MO 5 /TR "py -3 %USERPROFILE%\fanduel-watch\fanduel_props_watch.py --once"
```

## GitHub Actions

Add the key as a repository secret named `FANDUEL_API_KEY`. The cache carries the cursor between runs; GitHub may start scheduled runs a few minutes late.

Workflow

```
# .github/workflows/fanduel-watch.yml
name: fanduel-watch
on:
  schedule:
    - cron: "*/5 * * * *"
  workflow_dispatch:
jobs:
  poll:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/cache@v4
        with:
          path: fanduel-watch
          key: fanduel-watch-${{ github.run_id }}
          restore-keys: fanduel-watch-
      - run: curl -fsSL https://fanduelapi.com/starter-kit/fanduel_props_watch.py -o fanduel_props_watch.py
      - run: python3 fanduel_props_watch.py --once --dir fanduel-watch
        env:
          FANDUEL_API_KEY: ${{ secrets.FANDUEL_API_KEY }}
```

## Set up by an AI agent

Agents reading [skill.md](https://fanduelapi.com/skill.md), [llms.txt](https://fanduelapi.com/llms.txt) or the [MCP server](https://fanduelapi.com/mcp) are told the same thing: after the first request, install this job where their user wants it and show that it ran once. The [agent signup](https://fanduelapi.com/connect) gets them a key with your approval.

## Your allowance

A schedule spends the Free monthly allowance quickly: a poll every 5 minutes is about 288 calls a day. Free is for proving the job works; Developer is the plan for a job that stays on (https://fanduelapi.com/pricing). When the allowance runs out the job gets a 429 with error.user\_message to relay; never upgrade for your user without their approval.

See [pricing](https://fanduelapi.com/pricing). For pushes instead of polling, [line move alerts](https://fanduelapi.com/docs/line-move-alerts) covers the stream and webhooks. Base URL: `https://fanduelapi.com/api/v1`.

## Questions

## Related

- [First call Your first FanDuel API request step by step: the key, the header, one props call, reading the response and meta, and the three calls to make next.](https://fanduelapi.com/docs/first-call)
- [Line move alerts Alerting on FanDuel prop line moves end to end: pick a delivery, filter by size and kind, de-duplicate by cursor, and recover after downtime.](https://fanduelapi.com/docs/line-move-alerts)
- [Python example Working Python code for FanDuel Sportsbook player props: authenticate with a key, list props, read a prop's move history and poll for changes.](https://fanduelapi.com/fanduel-api-python)
- [Line movement Where a FanDuel player prop opened, every line and price move since, and when it last moved, from the history endpoint, with a sample move tape.](https://fanduelapi.com/fanduel-line-movement)

## 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 and reads the same data five minutes behind.

[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 with player props, and soccer (Premier League, La Liga, Serie A, Bundesliga, Ligue 1, Champions League, MLS and internationals) with every match market and goalscorer and shots markets, as FanDuel lists them.

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