NBA Stats API Deep Dive

Beginner 10 min read 1 views Nov 27, 2025
# NBA Stats API Deep Dive ## Introduction The NBA Stats API provides programmatic access to comprehensive basketball statistics directly from NBA.com. This guide covers authentication, endpoints, and data extraction techniques. ## Python Implementation ```python import requests import pandas as pd from time import sleep class NBAStatsAPI: def __init__(self): self.base_url = "https://stats.nba.com/stats" self.headers = { 'User-Agent': 'Mozilla/5.0', 'Referer': 'https://stats.nba.com/', 'Accept': 'application/json' } def get_player_stats(self, season='2023-24', per_mode='PerGame'): """Fetch player statistics for a given season""" endpoint = f"{self.base_url}/leaguedashplayerstats" params = { 'Season': season, 'SeasonType': 'Regular Season', 'PerMode': per_mode, 'MeasureType': 'Base' } response = requests.get(endpoint, headers=self.headers, params=params) data = response.json() # Convert to DataFrame headers = data['resultSets'][0]['headers'] rows = data['resultSets'][0]['rowSet'] return pd.DataFrame(rows, columns=headers) def get_team_stats(self, season='2023-24'): """Fetch team statistics""" endpoint = f"{self.base_url}/leaguedashteamstats" params = { 'Season': season, 'SeasonType': 'Regular Season' } sleep(0.6) # Rate limiting response = requests.get(endpoint, headers=self.headers, params=params) data = response.json() headers = data['resultSets'][0]['headers'] rows = data['resultSets'][0]['rowSet'] return pd.DataFrame(rows, columns=headers) # Usage api = NBAStatsAPI() player_stats = api.get_player_stats(season='2023-24') print(player_stats.head()) ``` ## R Implementation ```r library(httr) library(jsonlite) library(dplyr) get_nba_player_stats <- function(season = "2023-24", per_mode = "PerGame") { base_url <- "https://stats.nba.com/stats/leaguedashplayerstats" headers <- c( `User-Agent` = "Mozilla/5.0", `Referer` = "https://stats.nba.com/", `Accept` = "application/json" ) params <- list( Season = season, SeasonType = "Regular Season", PerMode = per_mode, MeasureType = "Base" ) response <- GET(base_url, query = params, add_headers(.headers = headers)) data <- content(response, as = "parsed") # Extract and convert to data frame headers <- unlist(data$resultSets[[1]]$headers) rows <- data$resultSets[[1]]$rowSet df <- do.call(rbind, lapply(rows, function(x) as.data.frame(t(unlist(x))))) colnames(df) <- headers return(df) } # Usage player_stats <- get_nba_player_stats(season = "2023-24") head(player_stats) ``` ## Key Endpoints - `/leaguedashplayerstats` - Player statistics - `/leaguedashteamstats` - Team statistics - `/playergamelog` - Game-by-game logs - `/shotchartdetail` - Shot location data - `/boxscoretraditionalv2` - Box scores ## Best Practices 1. Always include proper headers (User-Agent, Referer) 2. Implement rate limiting (0.6s between requests) 3. Handle API errors gracefully 4. Cache responses when possible 5. Respect NBA.com terms of service

Discussion

Have questions or feedback? Join our community discussion on Discord or GitHub Discussions.