Skip to main content
DraftKings API: NFL Lines, Player Props and History in Code
Back to Blog

DraftKings API: NFL Lines, Player Props and History in Code

James Whitfield

James Whitfield

•9 min read

DraftKings does not publish a public API for its sportsbook odds. There is no developer portal and no API key to apply for. To use DraftKings prices in your own code, you read them from an odds API that carries the book.

This guide shows how that works on the Odds-API.io v3 API: which bookmaker name to request, what a DraftKings NFL board contains, how player props are returned, and how to pull in-play prices, price history and closing lines. Every number below comes from responses captured on 6 October 2026.

Find the right bookmaker name

Start with /bookmakers. It needs no key and lists every book the API carries, 365+ in total. DraftKings is one entry.

curl --compressed "https://api.odds-api.io/v3/bookmakers"
{"name": "DraftKings", "active": true, "createdAt": "2025-10-11T11:38:05.549931Z"}

Wherever an endpoint takes a bookmaker, pass the name exactly as /bookmakers lists it. Responses are gzip-compressed, so use curl --compressed or a client that decompresses for you, as Python requests does.

List the games DraftKings prices

/events accepts a bookmaker filter, so the response only holds fixtures that already carry DraftKings odds.

curl --compressed -G "https://api.odds-api.io/v3/events" \
  --data-urlencode "apiKey=YOUR_KEY" \
  --data-urlencode "sport=american-football" \
  --data-urlencode "league=usa-nfl" \
  --data-urlencode "bookmaker=DraftKings"

On 6 October this returned 29 NFL games. With no to parameter, the window is the next 14 days. Each event comes back with its id, teams, kickoff, sport and league, and the id is what every odds endpoint asks for.

The same call without a league shows how wide the book runs. DraftKings was pricing 97 American football games (66 of them college), 118 ice hockey games across 17 leagues, 117 basketball games across 41 leagues, 726 football matches across 121 leagues, 318 tennis matches and 48 handball matches. Baseball in October was down to 11 games: the MLB playoffs, Korea and Japan. Golf, MMA, boxing and cricket returned none.

What a DraftKings NFL board contains

Pass an event id and bookmakers=DraftKings to /odds. For Dallas Cowboys v Tampa Bay Buccaneers on 9 October, under three days before kickoff, the response carried 15 DraftKings markets.

The game lines use the API's standard names: ML for the moneyline, Spread for the point spread and Totals for the points total. The first half has its own set, ML HT, Spread HT and Totals HT. Around them sit Player Props, Team Total Home and Team Total Away, and team totals for touchdowns, the first quarter and the first half.

Most applications need a handful of those. The markets parameter takes up to 20 names, is case-insensitive, and trims the response to what you ask for.

curl --compressed -G "https://api.odds-api.io/v3/odds" \
  --data-urlencode "apiKey=YOUR_KEY" \
  --data-urlencode "eventId=71515872" \
  --data-urlencode "bookmakers=DraftKings" \
  --data-urlencode "markets=ML,Spread,Totals"
{
  "id": 71515872,
  "home": "Dallas Cowboys",
  "away": "Tampa Bay Buccaneers",
  "date": "2026-10-09T00:15:00Z",
  "status": "pending",
  "sport": {"name": "American Football", "slug": "american-football"},
  "league": {"name": "USA - NFL", "slug": "usa-nfl"},
  "urls": {
    "DraftKings": "https://sportsbook.draftkings.com/event/34118137"
  },
  "bookmakerIds": {"DraftKings": "34118137"},
  "bookmakers": {
    "DraftKings": [
      {
        "name": "ML",
        "updatedAt": "2026-10-06T03:45:40.464Z",
        "odds": [{"home": "1.21", "away": "4.60"}]
      },
      {
        "name": "Spread",
        "updatedAt": "2026-10-06T03:45:40.464Z",
        "odds": [{"hdp": -9.5, "home": "1.95", "away": "1.86"}]
      },
      {
        "name": "Totals",
        "updatedAt": "2026-09-29T19:13:56.033Z",
        "odds": [{"hdp": 47.5, "over": "1.90", "under": "1.90"}]
      }
    ]
  }
}

hdp is the line. On Spread it is the home team's handicap, so -9.5 means Dallas gives 9.5 points. Odds arrive as decimal strings, so parse them before you compare, and convert them if your product shows American odds. The urls object holds the DraftKings event link, and bookmakerIds holds the DraftKings event id on its own.

Each market carries its own updatedAt, the time that price last changed. The total above had not moved since 29 September, so its stamp is a week old.

On this NFL board DraftKings came back with one main line for Spread and one for Totals. The alternate spread and total ladders were not in the response.

Player props

Player Props is a single market holding every player line for the game. For Cowboys v Buccaneers it held 89 selections across 29 players and 15 prop types: Anytime TD, Receiving Yards, Receptions, Rushing Yards, Rush Attempts, Longest Rush, Longest Reception, Rushing + Receiving Yards, Passing Yards, Passing Attempts, Completions, TD Passes, Interceptions, Longest Pass Completion and Passing + Rushing Yards.

{"label": "Bucky Irving (Receiving Yards)", "hdp": 13.5, "over": "1.85", "under": "1.93"},
{"label": "Bucky Irving (Receptions)", "hdp": 2.5, "over": "2.18", "under": "1.66"},
{"label": "Bucky Irving (Anytime TD)", "hdp": 0.5, "over": "2.85"}

The label is the player name followed by the prop type in brackets, so one split gives you both. hdp is the line. Yes or no props such as Anytime TD carry an over price only. The player props guide on this blog has more on props.

A short Python example

This lists the next NFL games DraftKings prices, then prints the moneyline, spread and total for ten of them in American odds. /odds/multi takes up to ten event ids and counts as a single request against your hourly limit.

import os
import requests

BASE = "https://api.odds-api.io/v3"
KEY = os.environ["ODDS_API_KEY"]
BOOK = "DraftKings"


def american(decimal):
    d = float(decimal)
    return f"{round((d - 1) * 100):+d}" if d >= 2 else f"{round(-100 / (d - 1)):+d}"


events = requests.get(f"{BASE}/events", params={
    "apiKey": KEY,
    "sport": "american-football",
    "league": "usa-nfl",
    "bookmaker": BOOK,
}).json()
events.sort(key=lambda e: e["date"])

ids = ",".join(str(e["id"]) for e in events[:10])
boards = requests.get(f"{BASE}/odds/multi", params={
    "apiKey": KEY,
    "eventIds": ids,
    "bookmakers": BOOK,
    "markets": "ML,Spread,Totals",
}).json()

for board in sorted(boards, key=lambda b: b["date"]):
    markets = {m["name"]: m["odds"][0] for m in board["bookmakers"].get(BOOK, [])}
    if not {"ML", "Spread", "Totals"} <= markets.keys():
        continue
    ml, spread, total = markets["ML"], markets["Spread"], markets["Totals"]
    print(f'{board["home"]} v {board["away"]}: '
          f'ML {american(ml["home"])} / {american(ml["away"])}  '
          f'spread {spread["hdp"]:+g} ({american(spread["home"])} / {american(spread["away"])})  '
          f'total {total["hdp"]:g} (o {american(total["over"])} / u {american(total["under"])})')

Run against the live API on 6 October, the first lines of output were:

Dallas Cowboys v Tampa Bay Buccaneers: ML -476 / +360  spread -9.5 (-105 / -116)  total 47.5 (o -111 / u -111)
Jacksonville Jaguars v Philadelphia Eagles: ML -294 / +235  spread -7 (-105 / -116)  total 42.5 (o -119 / u -102)
Miami Dolphins v Cincinnati Bengals: ML +275 / -357  spread +7 (-109 / -112)  total 42.5 (o -105 / u -116)
New England Patriots v Las Vegas Raiders: ML -192 / +160  spread -3.5 (-111 / -111)  total 45.5 (o -105 / u -116)
New Orleans Saints v Minnesota Vikings: ML +105 / -125  spread +1.5 (-111 / -111)  total 41.5 (o -116 / u -105)
New York Jets v Cleveland Browns: ML -132 / +110  spread -2.5 (-109 / -112)  total 39.5 (o -116 / u -105)

The conversion works from decimals rounded to two places, so a figure can land a point away from the one on the DraftKings site. 1.90 converts to -111.

To put a second book next to DraftKings, add its name to bookmakers. Odds Comparison API: 30 Bookmakers, One Request covers that pattern.

MLB, NHL, NBA and soccer boards

The board changes shape by sport. For Atlanta Braves v Los Angeles Dodgers in the MLB playoffs, DraftKings returned 17 markets: ML, Spread and Totals, the First 5 Innings versions of all three, team totals for runs and hits, and a Player Props market with 238 selections, including Total Bases, Home Runs, Hits, Runs Batted In and Stolen Bases.

Montreal Canadiens v Carolina Hurricanes in the NHL had 12 markets, with 59 Player Props selections across Goals, Assists, Points and Shots On Goal. An NBA preseason game, Charlotte Hornets v Brooklyn Nets, carried ML, Spread and Totals only, with no player props 12 hours before tip-off.

Soccer is priced the European way. Arsenal v Leeds United had 16 markets with a three-way ML, four Spread lines and four Totals lines in quarter steps, Both Teams To Score, Half Time / Full Time, and first and second half markets.

In-play prices

DraftKings stays on the board after the start, with a smaller set of markets. At 10:58 UTC on a Tuesday, it was pricing 7 of the 8 live baseball games (Korea and Japan), 8 of the first 10 live tennis matches and the one live basketball game, a Korean league match at half time. None of the 7 live football matches had DraftKings prices. They were youth and lower-division fixtures. The one live ice hockey game had none.

The live baseball and basketball boards held ML, Spread and Totals. Live tennis held ML only. No player props were in the in-play responses.

The updatedAt stamps on the live baseball prices were between 29 seconds and two minutes old at request time. On three of the eight tennis matches the ML had not changed for over an hour. Read updatedAt before you use a live price.

To poll, list what is in play with /events/live and fetch prices with /odds/multi. Live events also carry a clock object with the period and whether the clock is running. For more than a handful of games, the WebSocket stream pushes each change as it happens. The live odds guide covers the stream, reconnects and replay.

Price history for a DraftKings market

DraftKings is one of the books the API records movement history for. /odds/movements returns the opening price and each recorded change for one market on one event.

curl --compressed -G "https://api.odds-api.io/v3/odds/movements" \
  --data-urlencode "apiKey=YOUR_KEY" \
  --data-urlencode "eventId=71515872" \
  --data-urlencode "bookmaker=DraftKings" \
  --data-urlencode "market=ML"
{
  "opening": {"timestamp": 1779913584864, "home": 1.5, "away": 2.64},
  "movements": [
    {"timestamp": 1779913584864, "home": 1.5, "away": 2.64},
    {"timestamp": 1783434082725, "home": 1.48, "away": 2.7},
    ...
    {"timestamp": 1791244083060, "home": 1.2, "away": 4.7},
    {"timestamp": 1791258340463, "home": 1.21, "away": 4.6}
  ]
}

The response is shortened here. DraftKings opened Dallas at 1.50 on 27 May, and the history held 30 points up to 1.21 on 6 October. Timestamps are Unix milliseconds.

For a market with a line, add marketLine, for example market=Spread&marketLine=-9.5. Each line has its own history. The -9.5 spread started on 29 September at 1.90 a side and held six points. In a Totals history the over price is reported as home and the under price as away.

Closing lines for backtesting

Closing odds are the usual benchmark for grading a pricing model. /historical/closing-lines returns them for every settled event across up to ten leagues in one request, for up to 30 bookmakers and a date range of up to 366 days. It is available on paid plans.

curl --compressed -G "https://api.odds-api.io/v3/historical/closing-lines" \
  --data-urlencode "apiKey=YOUR_KEY" \
  --data-urlencode "sport=american-football" \
  --data-urlencode "leagues=usa-nfl" \
  --data-urlencode "from=2026-10-01T00:00:00Z" \
  --data-urlencode "to=2026-10-06T12:00:00Z" \
  --data-urlencode "markets=ML,Spread,Totals" \
  --data-urlencode "bookmakers=DraftKings"

Each event comes back with its final score, the score by quarter and the closing board. DraftKings closing lines for last week's NFL games:

Game                                        Score   ML home/away   Spread  Total 
Cleveland Browns v Pittsburgh Steelers      27-24   2.24 / 1.67    +2.5    38.5  
Washington Commanders v Indianapolis Colts  13-30   2.90 / 1.43    +4.5    46.5  
Minnesota Vikings v Miami Dolphins          15-10   1.18 / 5.00    -10     38.5  
Las Vegas Raiders v Kansas City Chiefs      27-30   2.60 / 1.52    +3.5    47.5  
Seattle Seahawks v Los Angeles Chargers     30-23   1.28 / 3.75    -7      43.5  
San Francisco 49ers v Denver Broncos        24-14   1.60 / 2.40    -3      48.5  
Carolina Panthers v Detroit Lions           32-26   2.85 / 1.44    +4.5    52.5  
New Orleans Saints v Atlanta Falcons        24-45   1.84 / 1.98    -1.5    47.5  

The request returned all 16 games of the week with scores. Eight had a DraftKings closing board. The eight games in the Sunday 17:00 UTC slot came back with scores and no closing odds, so check for an empty bookmakers object before you grade against it.

To go deeper on one game, find past fixtures with /historical/events and fetch the full board with /historical/odds. For Cleveland Browns v Pittsburgh Steelers on 2 October it returned 18 DraftKings markets, stamped six seconds before kickoff, including 124 player prop selections. Value Bets API: Track Closing Line Value in Python shows how to grade prices against a close.

Getting started

Create a key at odds-api.io, add DraftKings to your selected bookmakers, and run the Python example above. The DraftKings page in the sportsbooks section lists the sports we cover for it, and the API docs describe every endpoint used here. The script is also in the examples folder of the Python SDK on GitHub.

OddsNotifier and OddsHub run on the same real-time feed you get with the API.

See what's built with Odds API →