HOW TO GET STARTED WITH API-NBA: THE COMPLETE BEGINNER’S GUIDE

- Posted in Tutorials by

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. Dashboard API-NBA 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. Postman 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 day
  • x-ratelimit-requests-remaining: requests remaining for the day
  • X-RateLimit-Limit: maximum calls per minute
  • X-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, mistyped
  • 429 Too Many Requests: slow down and retry with backoff
  • 500 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 game
  • league: for a value returned by /leagues
  • season: as a four-digit YYYY value
  • team: for games involving a specific team
  • date: in YYYY-MM-DD format
  • h2h: for games between two teams, formatted as TEAM_ID-TEAM_ID
  • live: for games currently in progress live=all

The status.short field uses the following values:

  • 1: Not Started
  • 2: Live
  • 3: Finished
  • 4: Postponed
  • 5: Delayed
  • 6: 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

  1. Call /seasons and /leagues during setup, then store the values returned by the API. Select the season required by your application and use the appropriate league value.
  2. Load the daily schedule with /games?date=DATE. You can use /games?league=standard&season=SEASON&date=DATE to limit the request to a particular league and season.
  3. While games are active, poll /games?live=all at 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. Treat status.short=2 as live and reuse each response for all visitors.
  4. Retrieve a team box score with /games/statistics?id=GAME_ID. Poll it separately from /games because scores and detailed statistics come from different endpoints.
  5. After status.short becomes 3, call /players/statistics?game=GAME_ID to retrieve the final player statistics.

Workflow 2: Building a game preview page

  1. Find the upcoming matchup with /games?date=DATE, then store the game and team IDs returned by the API.
  2. Retrieve previous meetings with /games?h2h=HOME_ID-AWAY_ID.
  3. Load the standings with /standings?league=standard&season=SEASON. Add conference, division or team when you need a narrower result.
  4. Call /teams/statistics?id=TEAM_ID&season=SEASON for each team to compare their season statistics.
  5. Use /players?team=TEAM_ID&season=SEASON to retrieve the players associated with each team and season. Request /players/statistics?id=PLAYER_ID&season=SEASON only 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_ID or 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-key in public JavaScript or an application bundle.
  • Use four-digit season values: Seasons use the YYYY format. Pass the value exactly as /seasons returns it and do not reuse API-Basketball’s YYYY-YYYY format.
  • Treat status as a state machine: Use status.short values 1 for not started, 2 for live, 3 for finished, 4 for postponed, 5 for delayed and 6 for canceled. Retain status.long when 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 429 response, 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