hockey data hub

The Ice Hockey API for developers ballers.

The JSON you parse for a hockey game is the JSON you parse for a soccer match: same field names, same coordinate conventions, same envelope. Period-by-period linescores, computed expected-goals leaderboards, skater and goalie season stats, and a matchup endpoint that assembles the preview in one call. One hockey league is loaded today, the NHL, and a second would arrive in this same shape without a parser change on your side. There is a free tier; pricing lists what each plan covers.

Aggregate sport hub · choose a league before league-specific detail calls

250 req/day free (500 with GitHub). No credit card.

Ice hockey · one cross-sport envelope · NHL loaded · a new league arrives in the same shape

Seasons: 1997-98, 1998-99, 1999-00, 2000-01, 2001-02, 2002-03, 2003-04, 2005-06, 2006-07, 2007-08, 2008-09, 2009-10, 2010-11, 2011-12, 2012-13, 2013-14, 2014-15, 2015-16, 2016-17, 2017-18, 2018-19, 2019-20, 2020-21, 2021-22, 2022-23, 2023-24, 2024-25, 2025-26, 2026-27

Looking for the league and not the sport? The NHL API page owns the season, its teams, its games and its props. Go to the NHL API →

Featured league example · not aggregate coverage

NHL

single-league example · response shape, not coverage

1period · clock
2home · away
3linescore[] · status
Open the NHL authority →

Leagues in this sport

29
seasons in the archive
36,061 finished games, back to 1997-98

How far back the National Hockey League archive goes

29 seasons are on record, back to 1997-98 — 36,061 finished games you can query today. One route serves the full span. These figures are measured from the customer-facing routes listed below, so this page cannot silently drift from the product.

ArchiveRouteSeasonsReaches back toFinished games
National Hockey League/v1/matches291997-98 – 2026-2736,061

What each plan reaches

Edge & Pro
all 29 seasons
Solo & Trio
5 seasons
Free
the current season

Edge and Pro reach everything listed above. Solo and Trio reach five seasons. Free covers the current season.

Unified schema

One hockey envelope. League context stays explicit.

Canonical IDs, league keys, status and timestamps travel with the row. The hub describes shared fields; each league authority documents its own depth.

ice_hockey
sport
selected key
league
canonical
id
served
status

No featured-league field is promoted to a sport-wide guarantee.

Event surface

League-native events inside the hockey hub.

Event granularity differs by competition. Discover a match and league first, then use that authority’s event contract rather than assuming one featured feed applies everywhere.

  1. 1/v1/nhl/games/:game_id/matchupFull matchup: records, linescore, and state for both teams in one callfree
  2. 2/v1/nhl/players/:player_id/props?market=shots_on_goalPlayer props (shots_on_goal, goals, assists, points, saves) with linesedge
  3. 3/v1/players/:id/stats?sport=ice_hockeySkater + goalie season stats (goals, assists, save%, GAA)free
  4. 4/v1/injuries?sport=ice_hockeyActive NHL injury reports (status, type, expected return)free

League directory

Choose the hockey competition you are actually building.

League pages own seasons, participants, examples and measured depth. This hub owns discovery across them.

League authorityRoleNext step

Coverage strength

What the aggregate hockey surface connects.

Counts below describe published route rows on this hub, not a promise that every league fills every field.

0

League authorities

7

Published routes

6

Build patterns

8

FAQ answers

Endpoints

On the gateway at api.bigballsdata.com. Authenticate with the bearer token from /dashboard/keys.

MethodPathReturnsPlan
GET/v1/matches?sport=ice_hockey&league=nhlNHL games with final + period-by-period linescoresFree
GET/v1/standings?sport=ice_hockey&league=nhlConference + division standings (W-L-OTL, streak)Free
GET/v1/nhl/leadersSeason leaders with expected goals (xG) and goals-above-expectedFree
GET/v1/nhl/games/:game_id/matchupFull matchup: records, linescore, and state for both teams in one callFree
GET/v1/nhl/players/:player_id/props?market=shots_on_goalPlayer props (shots_on_goal, goals, assists, points, saves) with linesEdge
GET/v1/players/:id/stats?sport=ice_hockeySkater + goalie season stats (goals, assists, save%, GAA)Free
GET/v1/injuries?sport=ice_hockeyActive NHL injury reports (status, type, expected return)Free

What you get, by plan

One row per capability, not per field per endpoint. Season spans are counted from rows that are actually populated, and each capability names the simplest endpoint that returns it.

Ratings and derived intelligence

CapabilityFreeSoloTrioEdgeProEndpoint
Current Elo rating—PENDINGPENDINGPENDINGPENDING/v1/teams/{id}/elo

Measured against production on 2026-09-13. A capability appears here only when it has rows, an endpoint that returns it, and a source we may both serve and quote.

Stats included

Every hockey stat field the API returns today — 76 in total, grouped by how they are produced. Each group carries its own freshness, because a sport is rarely uniformly current.

Per-game player stats

Historical

Held and queryable, but not currently being ingested. Last ingested 2026-06-06.

Endpoint
/v1/players/:id/stats
Last updated
2026-06-06

Fields (30)

Assists, Blocked Shots, Even Strength Goals Against, Even Strength Saves, Even Strength Shots Against, Even Strength Line, Faceoff Win %, Giveaways, Goals, Goals Against, Hits, Penalty Minutes, Plus/Minus, Points (goals + assists), Power Play Goals, Power Play Goals Against, Power Play Saves, Power Play Shots Against, Power Play Line, Save %, Saves, Shifts, Shorthanded Goals Against, Shorthanded Saves, Shorthanded Shots Against, Shorthanded Line, Shots Against, Shots on Goal, Takeaways, Time on Ice

Season player stats

Historical

Held and queryable, but not currently being ingested. Last ingested 2026-06-06.

Endpoint
/v1/nhl/leaders
Last updated
2026-06-06

Fields (34)

Assists, Blocked Shots, Faceoff Losses, Faceoff Wins, Games Played, Giveaways, Goals, Goals Against, Hits, Penalty Minutes, Plus/Minus, Points (goals + assists), Power Play Goals, Saves, Shifts, Shots Against, Shots on Goal, Shutouts, Takeaways, Time on Ice Seconds, Individual Goals, Individual Points, Primary Assists, Secondary Assists, Individual Shots on Goal, Individual xGoals, Individual xGoals (adjusted), Individual xGoals (with rebounds), Ice Time (seconds), On-Ice xG Against, On-Ice xG For, On-Ice xG %, Situation, Team Abbr

Goalie fields (15)

Freezes, High-Danger Goals, High-Danger Shots, High-Danger xGoals, Low-Danger Goals, Low-Danger Shots, Low-Danger xGoals, Medium-Danger Goals, Medium-Danger Shots, Medium-Danger xGoals, Rebounds, X Freezes, Expected Rebounds, Expected Goals (xG), xGoals (flurry-adjusted)

Team stats (per game)

Historical

Held and queryable, but not currently being ingested. Last ingested 2026-08-07.

Endpoint
/v1/matches/:id/statistics
Last updated
2026-08-07

Fields (15)

Blocked Shots, Faceoff Win %, Faceoffs Won, Giveaways, Hits, Penalties, Penalty Minutes, Power Play Goals, Power Play Opportunities, Power Play %, Score, Shootout Goals, Short Handed Goals, Shots Total, Takeaways

Not included

  • Not shown here — player_per_game_eav: a SECOND source for per-game player stats alongside the primary one; listing both would double-count the same stats.
  • Not shown here — play_by_play: play-by-play events, not a stat line — mostly identifiers once classified.
  • Not shown here — standings_history: standings snapshots — reference data, not a player or team stat.
  • Not shown here — props: betting lines and prices, not stats — they belong on the odds surface.
  • player_per_game is not currently ingesting (last 2026-06-06).
  • team_per_game is not currently ingesting (last 2026-08-07).
  • player_season is not currently ingesting (last 2026-06-06).

Missing a stat?

We build what people actually ask for. If a field you need is not on this page, tell us — requests are how we decide what to add next.

Name the field or the endpoint shape. Specifics help more than categories.

Goes straight to the team as a product signal. No newsletter, no account, nothing else done with your address.

Player availability

hockey availability is league-scoped.

Injury, lineup and participant availability vary by league and season. Missing rows stay missing; the hub does not borrow another league’s records.

Nullable by design

Check the selected league authority and response timestamp before presenting a status as current.

Next up

Schedules across hockey competitions.

Each league publishes its own schedule and its own season boundaries. Call the league you selected and read the status and kickoff on the rows it returns, rather than inferring a season from this hub.

DiscoverGET /v1/leagues

Choose a real league key

Schedule/v1/matches?sport=ice_hockey&league=nhl

Keep league + season

DetailGET /v1/matches/{id}

Traverse canonical IDs

From response to product

A featured league example, rendered and raw.

This is visibly scoped to NHL, single-league example · response shape, not coverage; it demonstrates the shared envelope without claiming that league represents all hockey.

Featured league example

NHL

single-league example · response shape, not coverage

period · clockhome · awaylinescore[] · status
{
  "data": [
    {
      "id": "canonical-id-from-response",
      "sport": "ice_hockey",
      "league": "selected-league-key",
      "status": "finished",
      "home": {
        "name": "Home participant"
      },
      "away": {
        "name": "Away participant"
      },
      "score": {
        "home": null,
        "away": null
      }
    }
  ],
  "meta": {
    "example_scope": "NHL · single-league example · response shape, not coverage",
    "note": "Shape example; request the API for current values."
  }
}

hockey resources

Docs, comparisons and build guides.

Every card is a real destination. League authorities remain separate from supporting product and documentation routes.

Real API example

Start at aggregate hockey discovery.

The request deliberately omits a featured league when the route supports sport-wide discovery. Select a returned league key before league-specific calls.

curl -H "Authorization: Bearer $BBS_API_KEY" "https://api.bigballsdata.com/v1/matches?sport=ice_hockey&league=nhl"
{
  "data": [
    {
      "id": "canonical-id-from-response",
      "sport": "ice_hockey",
      "league": "selected-league-key",
      "status": "finished",
      "home": {
        "name": "Home participant"
      },
      "away": {
        "name": "Away participant"
      },
      "score": {
        "home": null,
        "away": null
      }
    }
  ],
  "meta": {
    "example_scope": "NHL · single-league example · response shape, not coverage",
    "note": "Shape example; request the API for current values."
  }
}

Integrate in a few lines

Node.js, @bigballsdata/sdktypescript
const API = 'https://api.bigballsdata.com';
const headers = { 'x-api-key': process.env.BBS_API_KEY };

// Recent NHL games with final score + period-by-period linescore.
const res = await fetch(`${API}/v1/matches?sport=ice_hockey&league=nhl&limit=5`, { headers });
const { data: games } = await res.json();

for (const g of games) {
  const periods = (g.linescore?.home ?? [])
    .map((h, i) => `${h}-${g.linescore.away[i]}`)
    .join('  ');
  console.log(`${g.away.name} @ ${g.home.name}  ${g.score.away}-${g.score.home}  [${periods}]`);
}

MCP

Connect an agent. Choose scope first.

An agent should discover hockey leagues, select one explicitly, then traverse matches and players by returned canonical IDs.

1get_leaguessport: ice_hockey
2get_matchesleague: selected key
3get_match_detailsmatch_id: returned UUID

Data freshness

Freshness belongs to the selected league and dataset.

The hub never turns a single-league example into a current sport-wide claim, and it states no season of its own.

Scoped

Schedules

Current when populated

Source: League response

Scoped

Scores

Event-driven

Source: Match response

Scoped

Stats

Category-specific

Source: Dataset response

Scoped

Example

single-league example · response shape, not coverage

Source: Static label

CurrentResults through · next fixture · odds partial

Read live from GET /v1/coverage — the same endpoint you can call yourself. Dates are absolute, not a build timestamp.

Plan decision

Choose by endpoint, not by the hub headline.

Each row preserves its league or sport scope and resolves against the endpoint plan registry when that route has a canonical entry.

EndpointScopeMinimum plan
/v1/matches?sport=ice_hockey&league=nhlLeague-specificfree
/v1/standings?sport=ice_hockey&league=nhlLeague-specificfree
/v1/nhl/leadersLeague-specificfree
/v1/nhl/games/:game_id/matchupLeague-specificfree
/v1/nhl/players/:player_id/props?market=shots_on_goalLeague-specificedge
/v1/players/:id/stats?sport=ice_hockeySport/sharedfree
/v1/injuries?sport=ice_hockeySport/sharedfree

Founder pricing

Start with hockey. Add depth as the product grows.

Prices and included dimensions come from the shared billing manifest; league coverage remains documented on each authority page.

Free

$0
  • ✓ 1 sport
  • ✓ 250 requests / day (500 with GitHub)
  • ✓ Current season
  • ✓ Scores, schedules, fixtures
Get a key

Solo

$19per month
  • ✓ Everything in Free, plus
  • ✓ 1 sport
  • ✓ 10,000 requests / day
  • ✓ Up to 5 seasons
Choose Solo

Trio

$49per month
  • ✓ Everything in Solo, plus
  • ✓ 3 sports
  • ✓ 25,000 requests / day
  • ✓ Up to 5 seasons
Choose Trio

Edge

$149per month
  • ✓ Everything in Trio, plus
  • ✓ All sports
  • ✓ 100,000 requests / day
  • ✓ All available history
Choose Edge

Pro

$299per month
  • ✓ Everything in Edge, plus
  • ✓ All sports
  • ✓ 200,000 requests / day
  • ✓ All available history
Choose Pro

Start on the free tier

100 requests per minute and 250 per day, free — the highest per-minute burst of any free sports API we checked. Burst is what matters when something asks several questions in a row and waits on each answer.

  • Every sport and league we cover — the paid tiers add history depth and premium fields, not more leagues.
  • Calls are counted one for one — no credit weighting, no markets-times-regions arithmetic.
  • Link GitHub and the daily cap goes to 500.
  • No credit card.
Get a key →

Or ask your AI tool directly

Connect your account to Claude, ChatGPT, Cursor, Perplexity or any other MCP-compatible tool and ask for hockey data in conversation — scores, standings, player stats and Elo ratings, with no API key to paste and no code to write. Your plan and limits carry over exactly as they do here.

Connect your AI tool →

Free covers a real app. Scale when you need to.

250 req/day free (500 with GitHub). Production starts at $49/mo. Live WebSocket push on Pro+.

Frequently asked

Answers before you choose a league.

Is there a free hockey API?

Yes. It covers NHL scores with period-by-period linescores, standings, expected-goals leaders, skater and goalie stats, injuries, and a matchup endpoint. There is a free tier; pricing lists what each plan covers. Player props need the Edge plan ($149/mo) or higher, with odds and the rest of the model layer. Free keys get 250 req/day (500 with GitHub). No credit card.

How many seasons of NHL data are there?

29 seasons of game coverage reach back to the 1997-98 season — 36,061 finished games from 1997-10-01 onward (2004-05 was not played). Free covers the current season, Solo and Trio five, and Edge and Pro the full 29. Licensed counting-stat leaderboards are a separate, shallower surface covering season-start years 2023 through 2025, and computed xG currently covers 2025. The coverage manifest remains the machine-readable source for game-season availability.

Does the hockey API include expected goals (xG)?

Yes. /v1/nhl/leaders returns season leaders with expected goals (xG) and goals-above-expected, so you can rank skaters by finishing over or under their xG.

Does it include goalie stats?

Yes. /v1/players/:id/stats returns goalie aggregates (save percentage, GAA, saves) alongside skater stats, and "saves" is one of the player-prop markets.

Does the hockey API include player props?

Yes. /v1/nhl/players/:player_id/props returns five markets — shots on goal, goals, assists, points, and saves — with the line and over/under juice from sportsbooks.

Does it include full game betting odds (moneyline / puck line)?

Yes, in two places, and they answer different questions. The archive: /v1/odds/historical serves archived closing-line snapshots, plus a T-24h snapshot, for finished NHL games — that is the endpoint to backtest against real closing lines. It needs the Edge plan ($149/mo) or higher. Every response names the snapshot types it actually contains in meta.snapshot_types_present, and /v1/coverage reports how many games carry them under data_types.odds_historical, so you can size the archive from the API rather than from this page. The live board: /v1/matches/:id/odds serves current pre-match and in-play moneyline, puck line and totals for games that are on the board now. It returns nothing for a game that has already finished, because a finished game has no current price — that is the archive endpoint’s job, not a gap. Player props carry their own lines via /v1/nhl/players/:player_id/props.

Can I get live NHL scores?

Yes. Scores refresh from the stored feed while games are on (typical REST round trip ~0.2–2s), and between games the endpoint serves the most recently completed games. Whether the league is playing right now is something to read from the API rather than from this page: GET /v1/coverage?sport=ice_hockey reports freshness.data_through (the newest result we hold) and freshness.next_event (the next scheduled puck drop). The finished-game archive reaches back to 1997-98 across 29 seasons, and licensed counting-stat seasons from 2023 through 2025 plus computed 2025 xG are available immediately.

Is this the same as the NHL API?

Same data, different question. This page is about ice hockey as a sport — how it maps into the one schema we use for every sport, and which fields you get. The NHL API page is about the league: the current season, its teams and its games. The NHL is the hockey league we cover, so the endpoints overlap; pick the page that matches what you are looking up.

Get an API key in 30 seconds