Tutorial · 9 min · endpoints verified 2026-09-22

How to build an NHL xG explorer

Rank the served leaderboard, make all-situations scope explicit, and keep unavailable model values separate from real zeroes.

API coverage and endpoint overview: Explore the NHL API

Why this is hard

Expected goals is useful only when its scope stays attached

An xG value without season, sample and strength-state context invites a false comparison. The explorer should make those qualifiers more visible than the ranking.

  • The current leaderboard is all-situations, not a five-on-five split.
  • Null xG means unavailable; it does not mean zero expected goals.
  • Goals above expected is derived from goals and xG and needs the same sample.
  • Different seasons can have different model availability.

Path 1 · recommended

Have your AI agent build it

Use MCP for coverage and player context, then call the NHL leaderboard over REST for the xG fields.

1. Connect the MCP server

Add the server in your MCP client and sign in with your Big Balls account. Your client registers itself and handles the token exchange — there is no key to copy.

MCP client configjson
{
  "mcpServers": {
    "bigballs-sports-data": {
      "url": "https://mcp.bigballsdata.com/mcp"
    }
  }
}

2. Tools your agent gets

  • get_player_stats

    Per-player career or per-season totals and per-game rates.

  • get_coverage

    Machine-readable map of what we hold and what we do not.

3. Ask for what you want

Paste this at your agent. It is written to make the model check coverage before it designs anything, which is what stops it inventing a field we do not serve.

Prompttext
Build an NHL expected-goals explorer. Check ice_hockey coverage, then
fetch /v1/nhl/leaders with stat=xg over REST. Label the board all-situations,
show season and games played, and keep null values out of numeric rankings.
Compare goals, xg and goals_above_xg without inventing five-on-five splits.

What the agent cannot reach

The NHL leaderboard is REST-only in MCP today. The agent can inspect coverage and player stats, but must fetch the xG ranking over HTTP.

Path 2 · hand-coded

Build it yourself

The explorer reads the leaderboard in one call and carries its season and situation fields into every view.

  1. 01

    Confirm xG coverage

    Read the hockey coverage response before populating a season picker. Counting stats and computed xG can span different seasons.

    Read hockey coveragebash
    curl -s "https://api.bigballsdata.com/v1/coverage?sport=ice_hockey" \
      -H "Authorization: Bearer $BBS_API_KEY"
  2. 02

    Fetch the xG leaderboard

    Request the xG stat and keep the response season, situation and minimum-games context.

    Fetch NHL xG leadersbash
    curl -s "https://api.bigballsdata.com/v1/nhl/leaders?stat=xg&min_games=20&limit=100" \
      -H "Authorization: Bearer $BBS_API_KEY"
  3. 03

    Rank only comparable rows

    Exclude null model values from numeric ranking while preserving them in a separately labelled unavailable state.

    Prepare comparable rowstypescript
    const ranked = leaders
      .filter((row) => row.xg != null && row.goals_above_xg != null)
      .sort((a, b) => b.xg - a.xg);

Reference

Every endpoint this tutorial uses

All on the gateway at api.bigballsdata.com. Verified against production on 2026-09-22.

MethodPathReturnsWhy you need itPlan
GET/v1/nhl/leaders?stat=xgAll-situations NHL leaders with goals, xG and goals above expectedThe ranking and comparison rows. Read the NHL xG scope guide.Free
GET/v1/coverage?sport=ice_hockeyPer-data-type availability and season depthConstrains the season picker to modelled data.Free

Pricing, honestly

The xG leaderboard works on Free

The served leaderboard and coverage response are Free. Solo can add a position-adjusted player tier, but the explorer should keep that model separate from raw xG.

Free xG explorer

texttext
GET /v1/nhl/leaders?stat=xg

Optional Solo tier

texttext
GET /v1/players/:id/tier
  • Free includes the xG ranking.
  • The leaderboard is all-situations.
  • Solo tiers are separate model output.
  • No plan fills a model season that is not loaded.

More tutorials

Other build guides

Known gaps

What this explorer does not claim

Keep the model scope explicit.

  • No inferred five-on-five split.
  • No shot map unless a separate coordinate surface supplies one.
  • No replacement of null model values with zero.

Questions

Is the leaderboard five-on-five?
No. It is all-situations, and the explorer should label it that way.
What does goals_above_xg mean?
It is goals minus expected goals on the same served sample. Positive and negative values describe finishing relative to the model.
Can I compare null xG as zero?
No. Null means the model value is unavailable for that row.
Do counting-stat and xG seasons always match?
No. Read coverage per data type before enabling a season.

Build the scoped xG explorer

Keep season, sample and all-situations scope attached to every number.