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.
Table of Contents
Related Topics
Quick Actions