How do I get NBA line movement before tip-off in Python?
Snapshots of each sportsbook's moneyline, spread and total from the day before a game to tip-off, with the final score, to see when the line moved and if it was right.
Code verified October 12, 2026. One call to get_line_movement, 10 credits.
The call
game_id comes from list_games or get_schedule. Pass provider to keep one sportsbook. Spreads are the home team's. Some books have no spread in their first snapshots, which the Python drops.
import requests
import pandas as pd
API_KEY = "YOUR_API_KEY"
resp = requests.post(
"https://mcp.dunkapi.com/v1/get_line_movement",
headers={"x-api-key": API_KEY},
json={
"game_id": "401810439",
},
timeout=60,
)
resp.raise_for_status()
data = resp.json()["data"]
game = data["game"]
margin = game["home"]["score"] - game["away"]["score"]
rows = []
for book, snaps in data["movement"].items():
df = pd.DataFrame(snaps).dropna(subset=["home_spread"]).sort_values("captured_at")
jump = df["home_spread"].diff().abs().idxmax()
rows.append({
"book": book,
"snapshots": len(df),
"spread_first": df["home_spread"].iloc[0],
"spread_last": df["home_spread"].iloc[-1],
"total_first": df["total"].iloc[0],
"total_last": df["total"].iloc[-1],
"biggest_jump_at": df.loc[jump, "captured_at"][5:16],
})
moves = pd.DataFrame(rows)
print(game["away"]["abbrev"], "at", game["home"]["abbrev"], "final margin (home):", margin)
print(moves.to_string(index=False))
print("home covered the last spread at:", moves.loc[moves["spread_last"] + margin > 0, "book"].tolist())
Replace YOUR_API_KEY with a key from your dashboard. Python needs requests and pandas (pip install requests pandas). JavaScript runs on Node 18 or newer, or in the browser.
What comes back
The data object of the response, trimmed to the first rows. Every field is real output from the run above.
{
"game": {
"game_id": "401810439",
"season": 2026,
"season_type": "regular",
"date": "2026-01-15",
"starts_at": "2026-01-16T03:00:00.000Z",
"status": "final",
"home": {
"team_id": "9",
"abbrev": "GS",
"name": "Golden State Warriors",
"score": 126
},
"away": {
"team_id": "18",
"abbrev": "NY",
"name": "New York Knicks",
"score": 113
},
"periods": 4,
"overtime_periods": 0,
"neutral_site": false,
"conference_game": false,
"venue": "Chase Center",
"city": "San Francisco",
"attendance": 18064
},
"movement": {
"DraftKings": [
{
"captured_at": "2026-01-14T23:50:38.000Z",
"home_ml": -155,
"away_ml": 130,
"home_spread": -3.5,
"total": 231.5
},
{
"captured_at": "2026-01-15T00:50:38.000Z",
"home_ml": -155,
"away_ml": 130,
"home_spread": -3.5,
"total": 231.5
},
{
"captured_at": "2026-01-15T02:20:37.000Z",
"home_ml": -162,
"away_ml": 136,
"home_spread": -3.5,
"total": 230.5
},
"...9 more"
],
"Pinnacle": [
{
"captured_at": "2026-01-15T11:55:37.000Z",
"home_ml": -281,
"away_ml": 237,
"home_spread": -7.5,
"total": 226
},
{
"captured_at": "2026-01-15T18:50:38.000Z",
"home_ml": -231,
"away_ml": 203,
"home_spread": -6.5,
"total": 229
},
{
"captured_at": "2026-01-15T23:50:38.000Z",
"home_ml": -251,
"away_ml": 220,
"home_spread": -7.5,
"total": 227.5
},
"...4 more"
],
"...": "6 more bookmakers"
},
"snapshots": 80
}What to do next
- get_odds (5 credits). Opening and closing lines for a day of games in one call, with whether the home side covered.
- get_ratings (2 credits). Our team Elo ratings, to set a model's win chance beside the market's.
More guides
Start with 500 free credits every month
No card. REST or MCP.