The Undocumented NHL Stats API
This post is mostly documentation for personal reference on a project I'm working on. As such it's not a full, detailed writeup but mostly just some notes and reminders of how the NHL stats API works. I have a need to query certain stats about NHL players and games and started looking for ways to get that information. There are a couple of paid services available which I quickly found to be WAY to expensive for just a little hobby project. Who knew live sports stats was such a lucrative business? The most affordable option is MySportsFeeds which offers free access for educational purposes or just hobby projects like mine. If you want the paid version it varies anywhere from $50/month to get stats post-game all the way up to $1000/month to get stats in real-time.
As a maker and somebody who genuinely likes to figure things out I found another way to get raw NHL stats; use the actual NHL stats API. You didn't know one existed? Neither did I until I stumbled across it looking at the Chrome Developer Tools window while browsing NHL.com and looking at player stat pages. It's not something that's documented or even mentioned when searching for "NHL stats API" on Google. So here's what I found.
The main API URL is https://statsapi.web.nhl.com/api/v1. All URLs begin with that and I must say the good folks of the NHL have done a pretty great job of creating a logically organized API that is easy to explore and understand. Talk about a cool job. Where do I apply for that one? As indicated the API is still on version 1. I tried several valid endpoints with v2 but got 404 responses.
From the main URL this is what I've figured out so far.
|teams||Returns a list of all teams. Includes venue info, franchise id, conference, division and team id which can be used to query specific team data. My Washington Caps are team 15.|
|teams/:id||Returns info about a specific team. Can also be passed query params like "?expand=team.roster" to get player info and "?expand=team.schedule.next" to get info about when the next game is.|
|teams/:id/roster||Get the current team roster. Can pass query param "?expand=roster.person,person.names"(can pass one or both expand items).|
|divisions||Returns a list of current divisions|
|divisions/:id||Return information about a specific division, including inactive ones that don't exist anymore (13 is the old Patrick division).|
|conferences||Returns a list of the current conferences|
|conferences/:id||Return information about a specific conference including inactive ones. ID 7 returns "World Cup of Hockey"|
|people/:id||Get information about a specific player. Call the roster endpoint above to get a list of players with their id. Sidney Crosby is 8471724. You can pass query param "?expand=person.stats&stats=yearByYear" to get season stats for the player. This will go all the way back to minor league seasons.|
|people/:id/stats||Gets stats for specific timeframes. Must be passed with query param like "?stats=gameLog" to get a list of stats for every game in a season. To specify a specific season include it in the param like "?stats=gameLog&season=20152016"|
|game/:id/feed/live||This is the big one. From the schedule info on the teams/:id endpoint you can get the game id. From this API you can get a massively in-depth look at live game stats. This includes everything from goals scored to shots (including type like slap/snap/wrap-around), missed shots, blocked shots, stoppages (with reason), faceoffs, hits, period start/stop, takeaways and giveaways. The data is rich and will include descriptive text and even the X,Y coordinate on the ice of where the event occurred.|
This data is incredibly detailed and fun to look through. As you look through the API you will see links to other portions of the API that I haven't documented here. I even got to a point where I was getting MP4 links to highlight videos from game action. It was insane. That's what I know so far and I can't wait to apply this to the project I'm working on which hopefully will warrant a blog post of it's own someday in the future before hockey season starts.