This guide walks you through API-NBA from scratch: getting your key, making your first request, understanding the response format, and using every endpoint in a real application.
API-NBA is a dedicated NBA data product. It covers teams, players, seasons, league variants, schedules, live scores, standings, game box scores, team season totals and player statistics through a focused REST API. All you need to follow along is a free account. The complete reference documentation is available here.
What we'll cover
- Getting your API key from the dashboard
- Making your first call with cURL, Node.js and Python
- Testing requests without code using the Live Tester and Postman
- Understanding rate limits, errors, coverage flags and timezones
- Exploring each endpoint by use case
- Building real applications without wasting requests
Getting your API key
To find your API key, open Account → My Access from the left sidebar. The string of characters in the top-right corner is your API key. Copy it and store it securely, as you’ll need it for every request. If you ever suspect that it has been exposed, you can regenerate it from the same page.
About the plans
The free tier gives you 100 requests per day and access to every endpoint and competition. The daily quota resets at 00:00 UTC, and unused requests do not roll over. The data access remains the same across the standard paid plans, but the official plans also differ by daily request volume, seats and per-minute limits.
| Plan | Price | Requests/day | Rate limit | Seats |
|---|---|---|---|---|
| FREE | $0 | 100 | 10/min | 1 |
| PRO | $15/month | 7,500 | 300/min | 1 |
| ULTRA | $25/month | 75,000 | 450/min | 2 |
| MEGA | $35/month | 150,000 | 900/min | 3 |
If you need more than 150,000 requests per day, custom plans are available for volumes of up to 1.5 million requests per day.
What's covered
API-NBA focuses on the NBA ecosystem, covering active NBA franchises, historical teams and teams associated with supported league variants. The available data includes schedules, results, live game states, standings, and team and player statistics.
Unlike API-Basketball, API-NBA does not return a season-level coverage object. Use /leagues and /seasons to discover valid scope values, then test the exact league, season and endpoint combination your product needs. Availability can differ between the standard NBA competition, summer leagues and older seasons, and individual fields may be null.
Making your first API call
The base URL is https://v2.nba.api-sports.io. All endpoints use the GET method. Authenticate by setting the x-apisports-key request header to your API key. We’ll start with /leagues. It requires no query parameters and returns the league strings that can be used elsewhere in the API.
cURL
curl --request GET
--url 'https://v2.nba.api-sports.io/leagues'
--header 'x-apisports-key: YOUR_API_KEY_HERE'
Node.js 18+ (server-side)
const response = await fetch('https://v2.nba.api-sports.io/leagues', {
method: 'GET',
headers: {
'x-apisports-key': process.env.API_SPORTS_KEY
}
});
if (!response.ok) {
throw new Error(`API-NBA request failed: ${response.status}`);
}
const data = await response.json();
console.log(data);
Python
import os
import requests
url = 'https://v2.nba.api-sports.io/leagues'
headers = {
'x-apisports-key': os.environ['API_SPORTS_KEY']
}
response = requests.get(url, headers=headers, timeout=20)
response.raise_for_status()
print(response.json())
Replace YOUR_API_KEY_HERE or set the API_SPORTS_KEY environment variable before running the example. A successful response follows this shape:
"response": [
{
"id": 15476,
"league": "standard",
"season": 2025,
"date": {
"start": "2025-10-07T23:00:00.000Z",
"end": null,
"duration": null
},
"stage": 1,
"status": {
"clock": null,
"halftime": false,
"short": 3,
"long": "Finished"
},
"periods": {
"current": 4,
"total": 4,
"endOfPeriod": false
},
"arena": {
"name": "Rocket Arena",
"city": "Cleveland",
"state": "OH",
"country": null
},
...
For the main NBA competition, the value you will normally pass as league is standard. The other strings identify supported summer or regional league contexts.
Understanding the response structure
API-NBA responses use a consistent top-level envelope. The get field echoes the requested endpoint, parameters reports the supplied filters, errors contains API-level errors, results gives the number of returned items, and response holds the data.
Check errors first, then inspect results, and only then parse response. A request can return HTTP 200 with results: 0 because the filters are valid but no matching data exists. Do not treat an empty array as a transport failure.
Checking your account from the API
The /status endpoint returns account information, subscription details and current request consumption:
GET https://v2.nba.api-sports.io/status
"response": {
"account": {
"firstname": "xxxxxxx",
"lastname": "xxxxxx",
"email": "xxxxxxxxx"
},
"subscription": {
"plan": "xxx",
"end": "xxxxxxxxxxxxxxxxxxx",
"active": xxxx
},
"requests": {
"current": xx,
"limit_day": xxxxx
}
}
}
This call does not count against the daily quota. Keep it restricted to internal monitoring because its response includes account-holder and subscription information.
Testing endpoints without code
Before writing any application logic, spend time exploring endpoints interactively. This is one of the highest-leverage things you can do early on.
The Dashboard Live Tester
The fastest option is the Live API Tester built into your dashboard, available for the NBA API at https://dashboard.api-football.com/nba/tester. No setup. No external tools. Select an endpoint from the list, fill in parameters using the form fields, and hit the call button. You get the full JSON response in your browser instantly.
We strongly recommend spending real time here before writing your first integration. You'll see which fields are sometimes null, what a statistics group actually looks like, how parameter combinations interact, and which seasons have coverage. Understanding the response shapes before you start writing parsing logic saves hours of debugging later.
Postman
If you prefer a dedicated API client, Postman works perfectly. Create a new GET request, paste your full endpoint URL, go to the Headers tab and add x-apisports-key with your key as the value, then click Send. Postman lets you save requests into organized collections and quickly adjust parameters.
Remember the API header rule: keep your request clean and only send x-apisports-key. If Postman or your framework auto-adds headers that aren't allowed, you'll get an error from the API rather than data.
In either tool, focus on two things: results to know how many items came back, and errors to know if something went wrong.
Understanding how requests work
Rate limits
Your plan has two types of limits running simultaneously. The daily quota is the total number of requests you can make in a day, 100 on the free plan, up to 150 000 on Mega, resetting at 00:00 UTC. The per-minute cap is a ceiling on how fast you can fire requests, regardless of which plan you're on.
Both limits are reported in the response headers of every API call:
x-ratelimit-requests-limit: requests allocated per dayx-ratelimit-requests-remaining: requests remaining for the dayX-RateLimit-Limit: maximum calls per minuteX-RateLimit-Remaining: calls remaining in the current minute
In a server-side Node.js request, read these values directly from the response before parsing the body:
const dailyRemaining = response.headers.get(
'x-ratelimit-requests-remaining'
);
const minuteRemaining = response.headers.get(
'X-RateLimit-Remaining'
);
console.log({ dailyRemaining, minuteRemaining });
Log these values on the server and slow your queue before either allowance reaches zero. Centralize polling so one API response can be reused for every visitor rather than making one provider request per browser session.
Error codes
A 200 response can still contain zero results. This can happen because a filter is invalid, a parameter does not exist, or the requested data is legitimately unavailable.
The other documented status codes are:
403 Forbidden: the API-KEY is missing, mistyped429 Too Many Requests: slow down and retry with backoff500 Internal Server Error: retry once after a short wait, then report persistent failures
When something does go wrong, the errors object in the response body is more informative than the HTTP status code alone. Always log the full error message in development, it usually tells you exactly what the problem is.
League and season scope
The /leagues endpoint returns the league values available in API-NBA, while /seasons returns the available seasons as four-digit years. Use these values exactly as returned when calling other endpoints.
Before implementing a feature, test the relevant endpoint with the league and season your application will use. Some response fields may be null, so your application should handle missing values appropriately.
Dates and timezones
API-NBA does not provide a /timezone endpoint or a timezone query parameter on /games. Game objects include an ISO 8601 value in date.start. Preserve its offset, store the timestamp in a canonical form, and convert it to the user’s local timezone in your backend or frontend.
The date filter uses YYYY-MM-DD. Because an NBA game can begin late in the evening in North America and fall on the next UTC calendar date, test your date-boundary logic with the exact timezone your product uses for its daily slate.
Logos and images
API-NBA provides team logo URLs in the responses from endpoints such as /teams and /games. Requests to these media files do not count towards your daily API quota. However, media delivery is subject to per-second and per-minute limits, so it is recommended to store or cache the files on your side to avoid affecting your application’s performance.
Download each logo once and serve it from your own storage or a CDN such as Bunny. Our dedicated tutorial, “Optimizing Sports Websites: BunnyCDN & API-SPORTS Image Storage Guide,” explains how to configure BunnyCDN with the API-SPORTS media infrastructure.
Complete endpoint walkthrough
API-NBA has a compact endpoint catalogue. Start with reference values, resolve team and player IDs, then use game IDs and seasons to retrieve the detailed statistics your application needs.
A practical architecture caches /seasons, /leagues and /teams, refreshes player directories on a slower schedule, and reserves frequent calls for /games and live box scores.
/seasons:
Returns all seasons available in API-NBA. This endpoint does not require any parameters. Every season is represented by a four-digit YYYY value. The values returned by this endpoint can be used as season filters in other endpoints.
Use /seasons to populate a season selector or validate a season value before making another request.
/leagues:
Returns the list of leagues available in API-NBA. This endpoint does not require any parameters.
The values returned by /leagues can be used as league filters in other endpoints. Pass them exactly as returned by the API rather than hardcoding them, as the list may change over time.
/games:
Returns games matching the supplied filters. This endpoint requires at least one parameter. Available filters include:
id: for a specific gameleague: for a value returned by/leaguesseason: as a four-digitYYYYvalueteam: for games involving a specific teamdate: inYYYY-MM-DDformath2h: for games between two teams, formatted asTEAM_ID-TEAM_IDlive: for games currently in progresslive=all
The status.short field uses the following values:
1: Not Started2: Live3: Finished4: Postponed5: Delayed6: Canceled
GET https://v2.nba.api-sports.io/games?id=15464
"response": [
{
"id": 15464,
"league": "standard",
"season": 2025,
"date": {
"start": "2025-10-02T16:00:00.000Z",
"end": null,
"duration": null
},
"stage": 1,
"status": {
"clock": null,
"halftime": false,
"short": 3,
"long": "Finished"
},
"periods": {
"current": 0,
"total": 4,
"endOfPeriod": false
},
"arena": {
"name": "Etihad Arena",
"city": "Abu Dhabi",
"state": null,
"country": null
},
...
Each game object includes its id, league, season and stage. The date object contains the start time, end time and duration, while status provides the game clock, halftime indicator and short and long status values. The response also includes the current and total periods, the arena and information about the home and visiting teams. The scores object contains each team’s win and loss values, series record, period-by-period linescore and total points. A game can also include the officials, number of times tied, lead changes and an additional value in nugget. Some fields may be null, so your application should handle missing values.
/games/statistics:
Returns the statistics of the teams that participated in a specific game. The id parameter is required and must contain a valid game ID. Each response entry identifies the team and provides its scoring, shooting, rebounding, assists, fouls, steals, turnovers, blocks, plus/minus and minutes. It also includes contextual statistics such as fast-break points, points in the paint, biggest lead, second-chance points, points off turnovers and longest scoring run.
Some fields may be null. Shooting percentages, plusMinus and min can also be returned as strings, so your application should not assume that every statistical value is numeric.
/teams:
Returns team profile data. Team IDs are unique within API-NBA and remain the same across seasons, making them reliable references for other endpoints.
You can filter teams by id, exact name, three-character code, league, conference or division. The search parameter performs a name search and requires at least three characters. Each team object includes its id, name, nickname, code, city and logo. The allStar and nbaFranchise fields identify the type of team, while the leagues object lists the competitions in which it appears, with the associated conference and division when available. Some league, conference or division values may be absent or null.
/teams/statistics:
Returns the overall statistics of a team for a given season. The id and season parameters are required, with the season provided as a four-digit YYYY value. You can also use the optional stage parameter to restrict the statistics to a particular stage.
The response includes the number of games and cumulative scoring, shooting, rebounding, assists, fouls, steals, turnovers, blocks and plus/minus statistics. It also contains contextual values such as fast-break points, points in the paint, biggest lead, second-chance points, points off turnovers and longest scoring run run. Most values are season totals rather than per-game averages. Shooting percentages are returned as strings, so your application should parse them accordingly.
/players:
Returns player profile data. Player IDs are unique within API-NBA and remain the same across seasons, making them reliable references for other endpoints. At least one parameter is required.
You can filter players by id, name, team, four-digit season or country. The search parameter can also be used with at least three characters.
GET https://v2.nba.api-sports.io/players?id=417&season=2025&team=27
"response": [
{
"id": 417,
"firstname": "Cameron",
"lastname": "Payne",
"birth": {
"date": "1994-08-08",
"country": "USA"
},
"nba": {
"start": 2015,
"pro": 6
},
"height": {
"feets": "6",
"inches": "1",
"meters": "1.85"
},
"weight": {
"pounds": "183",
"kilograms": "83.0"
},
"college": "Murray State",
"affiliation": "Murray State/USA",
"leagues": {
"standard": {
"jersey": 15,
"active": true,
"pos": "G"
},
"vegas": {
"jersey": 20,
"active": true,
"pos": "G"
}
}
}
]
}
Each player object includes the player’s first and last name, birth information, NBA information, height, weight, college and affiliation. The leagues object provides league-specific details such as jersey number, active status and position. Some profile fields may be null, so your application should handle missing values.
/players/statistics:
Returns statistics for one or more players. This endpoint requires at least one parameter and can be filtered by player id, game, team or four-digit season.
Each response entry represents a player’s statistics for a game and identifies the corresponding player, team and game. It includes points, position, minutes, shooting statistics, rebounds, assists, personal fouls, steals, turnovers, blocks and plus/minus. Statistical fields may be null when a player did not participate. In that case, the comment field may provide additional information, such as a reason for the player’s absence. Shooting percentages, minutes and plus/minus can be returned as strings.
/standings:
Returns the standings for a league and season. Both league and season are required. The season must use a four-digit YYYY value. You can optionally filter the response by team, conference or division.
GET https://v2.nba.api-sports.io/standings?league=standard&season=2025&team=27
"response": [
{
"league": "standard",
"season": 2025,
"team": {
"id": 27,
"name": "Philadelphia 76ers",
"nickname": "76ers",
"code": "PHI",
"logo": "https://upload.wikimedia.org/wikipedia/en/0/0e/Philadelphia_76ers_logo.svg"
},
"conference": {
"name": "east",
"rank": 13,
"win": 0,
"loss": 0
},
"division": {
"name": "atlantic",
"rank": 4,
"win": 0,
"loss": 0,
"gamesBehind": "11"
},
"win": {
"home": 23,
"away": 22,
"total": 0,
"percentage": "0.000",
"lastTen": 6
},
"loss": {
"home": 18,
"away": 19,
"total": 0,
"percentage": "0.000",
"lastTen": 4
},
"gamesBehind": "11",
"streak": 2,
"winStreak": true,
"tieBreakerPoints": null
}
]
}
Each standings entry identifies the league, season and team. It provides the team’s conference and division rankings, together with the corresponding win and loss values. The main win and loss objects include home, away and total records, percentages and results from the last ten games. The response also includes games behind, the current streak, whether it is a winning streak and tie-breaker points when available. Some fields may be null, and percentage values are returned as strings.
Endpoint quick reference
| Endpoint | Main purpose | Suggested refresh |
|---|---|---|
/status |
Account, subscription and request usage | When needed |
/seasons |
Available four-digit season values | When a season is added |
/leagues |
Available league values | Rarely |
/games |
Schedules, live games, results and head-to-head records | During live games or when schedules change |
/games/statistics |
Team statistics for a specific game | During live games or once after completion |
/teams |
Team profiles, IDs and league information | Daily or weekly |
/teams/statistics |
Overall team statistics for a season | Daily or after completed games |
/players |
Player profiles and team-season player lists | Daily |
/players/statistics |
Player statistics filtered by player, game, team or season | During live games or once after completion |
/standings |
Conference, division and team standings | After completed games or daily |
Putting it all together: three workflows
These workflows show how the endpoints connect in production. Replace the placeholders with values retrieved from the API and centralize requests on your server.
Workflow 1: Building a livescore app
- Call
/seasonsand/leaguesduring setup, then store the values returned by the API. Select the season required by your application and use the appropriate league value. - Load the daily schedule with
/games?date=DATE. You can use/games?league=standard&season=SEASON&date=DATEto limit the request to a particular league and season. - While games are active, poll
/games?live=allat a frequency supported by your plan. A 30-second interval can work for a livescore application, but it should be adjusted to your quota and traffic. Treatstatus.short=2as live and reuse each response for all visitors. - Retrieve a team box score with
/games/statistics?id=GAME_ID. Poll it separately from/gamesbecause scores and detailed statistics come from different endpoints. - After
status.shortbecomes3, call/players/statistics?game=GAME_IDto retrieve the final player statistics.
Workflow 2: Building a game preview page
- Find the upcoming matchup with
/games?date=DATE, then store the game and team IDs returned by the API. - Retrieve previous meetings with
/games?h2h=HOME_ID-AWAY_ID. - Load the standings with
/standings?league=standard&season=SEASON. Addconference,divisionorteamwhen you need a narrower result. - Call
/teams/statistics?id=TEAM_ID&season=SEASONfor each team to compare their season statistics. - Use
/players?team=TEAM_ID&season=SEASONto retrieve the players associated with each team and season. Request/players/statistics?id=PLAYER_ID&season=SEASONonly for the players displayed in the preview.
Workflow 3: Building a player profile page
- Find the player with
/players?search=PLAYER_NAME. The search value must contain at least three characters. - Retrieve the player’s profile with
/players?id=PLAYER_ID. - Request the player’s game-by-game statistics with
/players/statistics?id=PLAYER_ID&season=SEASON. - Aggregate the returned records on your side to calculate games played, totals, averages and recent form.
- After a completed game, update the profile with
/players/statistics?game=GAME_IDor refresh the player-season request in a background process.
Practical tips for building with API-NBA
- Test realistic responses first: Use the Live Tester with the seasons, leagues and game states your application will support. Inspect nullable fields and nested objects before defining strict data types.
- Keep the API key on the server: Browser and mobile clients should call your backend. Never include
x-apisports-keyin public JavaScript or an application bundle. - Use four-digit season values: Seasons use the
YYYYformat. Pass the value exactly as/seasonsreturns it and do not reuse API-Basketball’sYYYY-YYYYformat. - Treat status as a state machine: Use
status.shortvalues1for not started,2for live,3for finished,4for postponed,5for delayed and6for canceled. Retainstatus.longwhen you need a human-readable label. - Monitor request limits: Read the daily and per-minute rate-limit headers, queue requests and slow down before either allowance reaches zero. After a
429response, retry with progressively longer delays. - Test during a real game: Live clocks, halftime, period changes and score updates are difficult to validate using completed games alone.
Conclusion
You now have the complete path from account setup to every API-NBA endpoint. Start by retrieving the available seasons and leagues, resolve the required team and player IDs, load games, then use the relevant game, team or player identifier to request statistics.
Choose one concrete use case, such as a live scoreboard, standings table, team comparison or player page, and validate it on the free plan. Use the Live Tester to confirm response structures, cache slow-moving data and upgrade only when your measured request volume requires it.
If you need guidance, contact the API-SPORTS support team through the chat in your dashboard.
The API-SPORTS Team
