Skip to content

Guides

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

Every event in a game in order, with rink coordinates, strength state, zone and the players involved, loaded into pandas.

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

The call

game_id is a string and comes from get_games or get_schedule. Filter with team, strength, type or shot_attempts_only.

import requests
import pandas as pd

API_KEY = "YOUR_API_KEY"

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

plays = pd.DataFrame(data["plays"])
print(data["summary"]["by_type"])
attempts = plays[plays["type"].isin(["goal", "shot-on-goal", "missed-shot", "blocked-shot"])]
print(attempts.groupby(["team", "strength"]).size().unstack(fill_value=0))

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": [
    {
      "event_id": 52,
      "period": 1,
      "time_in_period": "00:00",
      "type": "period-start",
      "team": null,
      "strength": "5v5",
      "x_coord": null,
      "y_coord": null,
      "zone": null,
      "shot_type": null,
      "shooting_player_id": null,
      "home_score": null,
      "away_score": null
    },
    {
      "event_id": 51,
      "period": 1,
      "time_in_period": "00:00",
      "type": "faceoff",
      "team": "NYR",
      "strength": "5v5",
      "x_coord": 0,
      "y_coord": 0,
      "zone": "N",
      "shot_type": null,
      "shooting_player_id": null,
      "home_score": null,
      "away_score": null
    },
    "...298 more"
  ],
  "summary": {
    "returned": 300,
    "scope": "this page of results, not the full filter",
    "by_type": {
      "period-start": 3,
      "faceoff": 40,
      "shot-on-goal": 53,
      "missed-shot": 23,
      "giveaway": 36,
      "penalty": 3,
      "blocked-shot": 42,
      "stoppage": 32,
      "hit": 56,
      "takeaway": 5,
      "goal": 3,
      "period-end": 3,
      "game-end": 1
    },
    "shot_attempts": 121,
    "goals": 3
  },
  "count": 300,
  "next_offset": null
}

What to do next

  • get_shot_map (10 credits). Only the shot attempts, with shooter and goalie, for a game, a team's season or a player.
  • get_game_detail (10 credits). The box score, odds and goalie starts for the same game.

More guides

Start with 500 free credits

No card. REST or MCP.