Skip to content

gek0z/nba-api-ts

Repository files navigation

nba-api-ts

npm version CI License: MIT TypeScript Zero Dependencies Docs

TypeScript NBA API client. Zero dependencies. Wraps 138 stats endpoints and 4 live data endpoints from NBA.com.

Features

  • 138 stats endpoints — player, team, game, draft, and league data from stats.nba.com
  • 4 live endpoints — real-time scoreboard, box scores, play-by-play, and odds from cdn.nba.com
  • Fully typed — every endpoint has typed params, responses, and row interfaces
  • Built-in retry, rate limiting, and timeout — exponential backoff, token-bucket rate limiter, configurable timeouts
  • Custom fetch injection — plug in TLS impersonation libraries to bypass Akamai bot protection
  • Zero dependencies — nothing to audit, nothing to break

Requirements

  • Node.js >= 18, Bun, or any runtime with fetch support
  • Stats endpoints require a residential IP + TLS impersonation (see Akamai / TLS Fingerprinting)
  • Live endpoints work from anywhere

Install

bun add nba-api-ts
# or
npm install nba-api-ts

Quick Start

import { NBAClient } from 'nba-api-ts';

const nba = new NBAClient();

// Stats — player career totals
const career = await nba.stats.playerCareerStats({ playerID: 203999 });
console.log(career.careerTotalsRegularSeason[0].pts);

// Stats — league-wide player dashboard
const dashboard = await nba.stats.leagueDashPlayerStats({
  season: '2024-25',
  perMode: 'PerGame',
});
console.log(dashboard.leagueDashPlayerStats[0].playerName);

// Live — today's scoreboard (no Akamai, works anywhere)
const scoreboard = await nba.live.scoreboard();
console.log(scoreboard.scoreboard.games.length, 'games today');

API Reference

NBAClient

const nba = new NBAClient({
  stats: { timeout: 30000, maxRetries: 3, rateLimit: 600, fetch: customFetch },
  live: { timeout: 10000, rateLimit: 0 },
});
  • nba.statsStatsClient with 138 endpoint methods
  • nba.liveLiveClient with 4 methods (scoreboard, boxscore, playByPlay, odds)

Stats Endpoints

138 endpoints are available (full list). Some commonly used ones:

Method Description
playerCareerStats({ playerID }) Career and season stats
commonPlayerInfo({ playerID }) Player biographical info
commonAllPlayers({ season, leagueID }) All players for a season
leagueDashPlayerStats({ season }) League-wide player stats
leagueDashTeamStats({ season }) League-wide team stats
playerGameLog({ playerID, season }) Game-by-game stats
teamGameLog({ teamID, season }) Team game-by-game stats
shotChartDetail({ playerID, season }) Shot chart data
leagueGameFinder({ ... }) Search for games
boxScoreTraditionalV3({ gameID }) Box score for a game
playByPlayV2({ gameID }) Play-by-play data
scoreboardV2({ gameDate }) Scoreboard for a date
leagueStandings({ season }) League standings
leagueLeaders({ season, statCategory }) League leaders
commonTeamRoster({ teamID }) Team roster
playerIndex({ season }) Player index

Response Format

Stats API responses use the NBA's headers[] + rowSet[][] format, automatically parsed into typed objects with camelCase keys:

// Raw NBA response:
// { "headers": ["PLAYER_ID", "PTS"], "rowSet": [[203999, 25.0]] }

// Parsed:
// { playerId: 203999, pts: 25.0 }

Parameters

Common parameter types are available as string unions:

import type { PerModeDetailed, SeasonTypePlayoffs, LeagueID } from 'nba-api-ts';
import { currentSeason, formatSeason, defaults } from 'nba-api-ts';

const season = currentSeason(); // "2025-26"
const prev = formatSeason(2023); // "2023-24"

Error Handling

import { NBAApiError, NBATimeoutError, NBANetworkError } from 'nba-api-ts';

try {
  await nba.stats.playerCareerStats({ playerID: -1 });
} catch (e) {
  if (e instanceof NBAApiError) {
    console.log(e.statusCode, e.url);
  }
}

Documentation

Development

bun install
bun test            # unit tests (offline, fast)
bun run build

# Integration tests — hits real NBA API, requires residential IP
NBA_INTEGRATION_TESTS=1 bun test tests/integration

# Integration tests with TLS fingerprint impersonation
NBA_INTEGRATION_TESTS=1 NBA_USE_TLS=1 bun test tests/integration

Contributing

PRs welcome. Run bun run lint and bun test before submitting.

Akamai / TLS Fingerprinting

All stats.nba.com endpoints are behind Akamai bot protection that blocks requests based on TLS fingerprinting. This means Node.js and Bun's built-in fetch will be blocked. Live endpoints (cdn.nba.com) work fine from any environment.

To use stats endpoints from a server, provide a custom fetch backed by a library that can impersonate a browser's TLS fingerprint:

import { NBAClient } from 'nba-api-ts';
import { ModuleClient, SessionClient } from 'tlsclientwrapper';

const moduleClient = new ModuleClient();
await moduleClient.open();

const session = new SessionClient(moduleClient, {
  tlsClientIdentifier: 'chrome_131',
  timeoutSeconds: 30,
  defaultHeaders: {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36',
    'Accept': 'application/json, text/plain, */*',
    'Referer': 'https://www.nba.com/',
    'Origin': 'https://www.nba.com',
  },
});

const nba = new NBAClient({
  stats: {
    fetch: async (url) => {
      const res = await session.get(url);
      if (res.status === 0) throw new Error(res.body);
      const headers: Record<string, string> = {};
      for (const [k, v] of Object.entries(res.headers))
        headers[k] = Array.isArray(v) ? v.join(', ') : String(v);
      return new Response(res.body, { status: res.status, headers });
    },
  },
});

const career = await nba.stats.playerCareerStats({ playerID: 203999 });

Any fetch-compatible function works — tlsclientwrapper, curl-impersonate, Puppeteer, or a proxy that adds the right TLS fingerprint.

IP Blocking

Beyond TLS fingerprinting, stats.nba.com drops connections from known cloud/datacenter IP ranges. If your requests hang without any response, this is likely the cause — it affects all major providers (AWS, GCP, Azure, etc.) and CI environments like GitHub Actions.

You'll need to make requests from a residential IP, either directly (local machine, home server) or via a residential proxy.

License

MIT

About

TypeScript NBA API client — wraps stats.nba.com and cdn.nba.com live data

Topics

Resources

License

Stars

Watchers

Forks

Contributors