Skip to content

Guides

How do I get NBA play-by-play data in Python?

One call returns a game's plays in order, with shot location, zone, expected points and win probability on each. This pulls the shots from one game into pandas.

Code verified October 10, 2026. One call to get_plays, 10 credits.

The call

game_id comes from list_games or get_schedule.

import requests
import pandas as pd

API_KEY = "YOUR_API_KEY"

resp = requests.post(
    "https://mcp.dunkapi.com/v1/get_plays",
    headers={"x-api-key": API_KEY},
    json={
        "game_id": "401866759",
        "shots_only": True,
        "limit": 100,
    },
    timeout=60,
)
resp.raise_for_status()
data = resp.json()["data"]

plays = pd.json_normalize(data["plays"])
summary = plays.groupby("team").agg(
    attempts=("seq", "count"),
    points=("points", "sum"),
    expected=("shot.expected_points", "sum"),
)
print(summary.round(1))

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.

{
  "plays": [
    {
      "game_id": "401866759",
      "seq": 1,
      "period": 1,
      "clock_seconds": 707,
      "team": "GS",
      "type": "Driving Layup Shot",
      "text": "Draymond Green makes driving layup",
      "shot": {
        "made": true,
        "points_attempted": 2,
        "x": 27,
        "y": 2,
        "distance_ft": 2.8,
        "zone": "restricted_area",
        "expected_points": 1.12
      },
      "points": 2,
      "player_id": "6589",
      "player": "Draymond Green",
      "player2_id": null,
      "home_score": 0,
      "away_score": 2,
      "home_win_prob": 0.601
    },
    {
      "game_id": "401866759",
      "seq": 2,
      "period": 1,
      "clock_seconds": 689,
      "team": "PHX",
      "type": "Jump Shot",
      "text": "Dillon Brooks misses 25-foot three point jumper",
      "shot": {
        "made": false,
        "points_attempted": 3,
        "x": 43,
        "y": 18,
        "distance_ft": 25.5,
        "zone": "above_break_3",
        "expected_points": 1.075
      },
      "points": 0,
      "player_id": "3155526",
      "player": "Dillon Brooks",
      "player2_id": null,
      "home_score": 0,
      "away_score": 2,
      "home_win_prob": 0.584
    },
    "...98 more"
  ],
  "count": 100,
  "next_offset": 100
}

What to do next

  • get_shot_chart (10 credits). Roll the same shots up by zone for a player, a team or a defence.
  • get_game (5 credits). Add both box scores and every sportsbook's line for the game.

More guides

Start with 500 free credits

No card. REST or MCP.