# NHL Stats and Play-by-Play Scraper (`parselab/nhl-hockey-stats-scraper`) Actor

Get NHL player and team stats, standings, game results, boxscores, draft picks and full play-by-play with shot coordinates. One wide row per player with time on ice, power play, penalties and shot attempts. Any season since 1917. Export to CSV or Excel.

- **URL**: https://apify.com/parselab/nhl-hockey-stats-scraper.md
- **Developed by:** [ParseLab](https://apify.com/parselab) (community)
- **Categories:** Sports, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $13.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## NHL Hockey Stats Scraper: Players, Games and Play-by-Play

This NHL scraper collects official NHL data and returns it as clean rows you can sort, filter and export. Get season stats for every skater and goalie, team stats, standings for any date, game results with optional boxscores, draft picks, full player profiles with career totals, game logs and play-by-play events with shot coordinates. Data goes back to the 1917-18 season.

The main difference from other hockey scrapers is depth. A skater row does not stop at goals and assists. It merges the separate NHL stat reports into one wide row with time on ice, power play and penalty kill numbers, penalties drawn, hits, blocks, giveaways, takeaways, shot attempts, Corsi-style percentages, faceoffs by zone, shootout record and bio details such as draft position and birthplace. You get the whole picture without stitching six downloads together.

Fantasy players, betting analysts, sports journalists, data scientists and hockey fans use it to build models, dashboards and newsletters.

### What can you do with this NHL scraper?

- Get all NHL skater stats for a season, sorted by points
- Compare goalies by save percentage, quality starts and saves by strength
- Find the top penalty drawers or best shot-attempt percentages in the league
- Download NHL standings for any date, with home, road and last 10 splits
- List every game between two dates with scores, venues and TV networks
- Pull full boxscores with every player's line
- Get play-by-play with x and y coordinates for every shot, hit and faceoff
- Build expected goals models from shot distance and angle
- Load the game log of any player for a season or the playoffs
- List all picks of any NHL draft, with amateur club and league
- Export NHL data to CSV or Excel

### What data can you extract from the NHL?

| Mode | One row is | Highlights |
|---|---|---|
| Skater season stats | One skater and season | Goals, assists, points, shots, plus/minus, time on ice, power play, shorthanded, penalties, hits, blocks, takeaways, giveaways, shot attempts, faceoffs, shootouts, bio |
| Goalie season stats | One goalie and season | Wins, losses, save percentage, goals against average, quality starts, saves by strength, started versus relieved, penalty shots |
| Team season stats | One team and season | Goals for and against, power play and penalty kill, faceoffs, hits, shot attempt percentages, goals against by strength |
| Standings | One team on a date | Points, regulation wins, home, road and last 10 records, goal differential, streak |
| Games and results | One game | Date, teams, score, shots, venue, how it ended, broadcasts, optional boxscore |
| Play-by-play | One event | Event type, period, clock, strength, coordinates, distance and angle to the net, players involved |
| Player profiles | One player | Bio, draft, career totals, every season, awards, last five games |
| Game logs | One player and game | Full stat line for each game |
| Draft picks | One pick | Round, pick, team, player, position, amateur club |

### How to scrape NHL stats

1. Choose **What to collect**, for example Skater season stats.
2. Enter one or more seasons such as `2024-25`. Leave it empty for the current season.
3. Pick regular season, playoffs or preseason.
4. Add optional filters: teams, positions or a minimum number of games played.
5. Set **Max Items** and click **Start**.
6. Export the dataset as CSV, Excel or from the Apify console.

### Input example

```json
{
  "mode": "skaters",
  "seasons": ["2024-25"],
  "gameType": "regular",
  "depth": "full",
  "minGames": 50,
  "maxItems": 100
}
```

### Output example

```json
{
  "playerId": 8476453,
  "playerName": "Nikita Kucherov",
  "season": "2024-25",
  "gameType": "regular",
  "team": "TBL",
  "gamesPlayed": 78,
  "goals": 37,
  "assists": 84,
  "points": 121,
  "plusMinus": 22,
  "ppPoints": 46,
  "shots": 265,
  "shootingPct": 0.13962,
  "timeOnIcePerGameMinutes": 21.19,
  "penaltiesDrawn": 28,
  "satPct": 0.526795,
  "draftYear": 2011,
  "draftOverall": 58,
  "birthCountryCode": "RUS"
}
```

### Play-by-play example

```json
{
  "gameId": 2024020700,
  "eventType": "shot-on-goal",
  "period": 1,
  "timeInPeriod": "00:22",
  "team": "CGY",
  "strength": "5v5",
  "xCoord": -62,
  "yCoord": 23,
  "distanceToNetFt": 35.5,
  "angleToNetDeg": 40.4,
  "shotType": "wrist",
  "shootingName": "Nazem Kadri",
  "goalieName": "Jordan Binnington"
}
```

Distance and angle are calculated for shots in the offensive zone, so you can feed them straight into a model.

### How much does it cost to scrape the NHL?

You pay per result: $18 per 1,000 rows plus a tiny start fee. The free plan returns up to 10 rows per run. A full season of skaters is about 900 rows, and a full game of play-by-play is roughly 300 events.

### Tips for better results

- Use **Basic** detail when you only need the standard stat line. Full detail is the default.
- Names and IDs work together. Look up a player by name once, then reuse the player ID in later runs.
- Filter play-by-play by event type, for example goals and shots on goal, to keep datasets small.
- Times on ice are given in seconds by the NHL. The Actor adds a version in minutes.
- Games in the future or in progress have no final boxscore yet.

### Who uses NHL data?

- **Fantasy hockey players** rank players by real usage such as time on ice and power play minutes.
- **Betting analysts** build models from shot quality and team form.
- **Journalists and bloggers** pull numbers for stories and graphics.
- **Students and data scientists** practice on real event data.

### Automate and connect

Schedule the Actor to refresh standings every morning, or pull yesterday's games and play-by-play after each game night. Send finished datasets to Google Sheets, Zapier, Make or n8n, or trigger a webhook when a run ends.

### FAQ

**Do I need an NHL account?**
No. The Actor works without any login.

**How far back does the data go?**
Season stats go back to 1917-18. Play-by-play with shot coordinates is available from about the 2010-11 season. Earlier games have fewer events and no coordinates.

**Can I get playoff stats?**
Yes. Choose Playoffs under season part.

**What is the difference between skater stats and player profiles?**
Skater stats give the numbers of every skater for a season. Player profiles give one full record for a player, with all seasons and career totals.

**How do I find a game ID?**
Run games mode for a date range. Each row has its game ID.

### Legal note

This Actor collects information that is publicly visible on the website. Check the source site's terms and your local rules before using the data. Nothing here is betting or financial advice.

### Support

Missing a field or found a bug? Open an issue from the Actor page.

# Actor input Schema

## `maxItems` (type: `integer`):

Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000.

## `mode` (type: `string`):

Skaters and goalies give one row per player and season. Teams gives one row per team and season. Standings gives the league table for a date. Games gives results and optional boxscores. Play-by-play gives one row per event with shot coordinates. Players gives full profiles with career totals. Game logs gives one row per game for chosen players. Draft gives every pick of a draft year.

## `seasons` (type: `array`):

Seasons to collect, for example 2024-25 or 2023-24. Works for skaters, goalies, teams and game logs. Leave empty for the current season. Data goes back to 1917-18.

## `gameType` (type: `string`):

Regular season, playoffs or preseason.

## `depth` (type: `string`):

Full merges every stat report into one wide row (time on ice, power play, penalties, shot attempts, Corsi, faceoffs, shootouts and more). Basic returns only the main stat line and bio.

## `teams` (type: `array`):

Team abbreviations such as EDM, TOR, BOS. Filters skaters, goalies, teams and games. In players mode it loads the current roster of each team.

## `positions` (type: `array`):

Skater positions to keep: C for centers, L for left wings, R for right wings, D for defensemen.

## `minGames` (type: `integer`):

Only return skaters and goalies who played at least this many games in the season.

## `playerNames` (type: `array`):

Look up players by name, for example Connor McDavid. Used in players and game logs modes.

## `playerIds` (type: `array`):

NHL player IDs, for example 8478402. Used in players and game logs modes, and as a filter for skaters and goalies.

## `dateFrom` (type: `string`):

First game date, YYYY-MM-DD. Used in games and play-by-play modes. Default is seven days before the end date.

## `dateTo` (type: `string`):

Last game date, YYYY-MM-DD. Default is today.

## `includeBoxscores` (type: `boolean`):

In games mode, add the full player stat lines of every finished game.

## `gameIds` (type: `array`):

NHL game IDs such as 2024020700 for play-by-play mode. If empty, finished games in the date range are used.

## `eventTypes` (type: `array`):

Keep only these play-by-play events, for example goal, shot-on-goal, missed-shot, blocked-shot, hit, giveaway, takeaway, faceoff, penalty.

## `standingsDate` (type: `string`):

Date of the standings table, YYYY-MM-DD. Leave empty for today.

## `draftYears` (type: `array`):

Draft years for draft mode, for example 2023. Leave empty for the most recent draft.

## Actor input object example

```json
{
  "maxItems": 10,
  "mode": "skaters",
  "seasons": [
    "2024-25"
  ],
  "gameType": "regular",
  "depth": "full",
  "includeBoxscores": false
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxItems": 10,
    "seasons": [
        "2024-25"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("parselab/nhl-hockey-stats-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "maxItems": 10,
    "seasons": ["2024-25"],
}

# Run the Actor and wait for it to finish
run = client.actor("parselab/nhl-hockey-stats-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxItems": 10,
  "seasons": [
    "2024-25"
  ]
}' |
apify call parselab/nhl-hockey-stats-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parselab/nhl-hockey-stats-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/SAlywxNx9zMEuhY7x/builds/78sY74YRIwQfaIw8a/openapi.json
