Tutorial · 10 min · endpoints verified 2026-09-22
How to build an NBA scoreboard
Start with the canonical match list, render only fields the response actually carries, and add push updates without turning a quiet socket into a false live state.
API coverage and endpoint overview: Explore the NBA API
Why this is hard
A scoreboard is a state machine, not a score pair
Scheduled, live and final games share one card, but each state has different trustworthy fields. The implementation has to preserve that distinction while scores and clocks change.
- A scheduled game may have no score or clock; zero is not the same value as not started.
- The canonical match UUID and the NBA-native game id are not interchangeable on every route.
- Quarter arrays can be partial while a game is live, so the UI must not assume four values.
- A WebSocket connection can be healthy while no subscribed game is producing an update.
Path 1 · recommended
Have your AI agent build it
The MCP server can discover the current NBA match list and its canonical ids. Use REST for the NBA-native matchup detail and the WebSocket protocol when you need push delivery.
1. Connect the MCP server
Add the server in your MCP client and sign in with your Big Balls account. Your client registers itself and handles the token exchange — there is no key to copy.
{
"mcpServers": {
"bigballs-sports-data": {
"url": "https://mcp.bigballsdata.com/mcp"
}
}
}2. Tools your agent gets
get_matchesLive, upcoming or historical matches for a sport or league.
get_coverageMachine-readable map of what we hold and what we do not.
3. Ask for what you want
Paste this at your agent. It is written to make the model check coverage before it designs anything, which is what stops it inventing a field we do not serve.
Build an NBA scoreboard with Big Balls Sports Data.
First call get_coverage for basketball, then get_matches scoped to league nba.
Render scheduled, live and final states separately. Never turn a missing score,
period or clock into zero. Keep the canonical match id and any league-native
game id as separate fields. Add a REST fallback even if you wire WebSockets.What the agent cannot reach
MCP exposes the match list but not the NBA matchup route or WebSocket subscription. Call those over HTTP with the same account after the agent establishes the canonical match state.
Path 2 · hand-coded
Build it yourself
These calls use the public gateway contract. The examples intentionally render response values rather than hard-coded teams, scores or claims that a game is live.
- 01
Load the NBA schedule and score list
Scope both sport and league. Basketball also contains other competitions, so sport=basketball by itself is not an NBA query.
Fetch the canonical match listtypescriptconst API = 'https://api.bigballsdata.com'; const headers = { Authorization: `Bearer ${process.env.BBS_API_KEY}` }; const response = await fetch( `${API}/v1/matches?sport=basketball&league=nba&limit=20`, { headers }, ); if (!response.ok) throw new Error(`matches failed: ${response.status}`); const { data: games } = await response.json(); - 02
Render status without inventing values
Keep null distinct from zero, preserve the status returned by the API, and render the period arrays at their actual length.
Shape one scoreboard rowtypescriptconst cards = games.map((game) => ({ id: game.id, status: game.status, tipoff: game.scheduled_at, home: game.home_team?.name ?? 'Home team', away: game.away_team?.name ?? 'Away team', homeScore: game.home_score ?? null, awayScore: game.away_score ?? null, periods: game.linescore ?? null, })); - 03
Add push updates with a polling fallback
Subscribe to the game room documented by the WebSocket guide. Reconcile every push by id, keep a bounded REST poll, and treat silence as silence rather than as proof that the score has not changed.
Delivery contracttext1. Subscribe with the canonical match id returned by /v1/matches. 2. Merge each message by match id and event timestamp. 3. Keep a slower REST refresh for reconnects and missed delivery. 4. Stop live polling only when the API reports a terminal game status.
Reference
Every endpoint this tutorial uses
All on the gateway at api.bigballsdata.com. Verified against production on 2026-09-22.
| Method | Path | Returns | Why you need it | Plan |
|---|---|---|---|---|
| GET | /v1/matches?sport=basketball&league=nba | NBA schedule, status, scores and available linescore fields | The canonical list and the source of match ids for every scoreboard card. | Free |
| GET | /v1/nba/games/:game_id/matchup | Match meta, team context, roster blocks and recent form where populated | Optional detail drawer. Read the route identifier note before following an id from another surface. Read the NBA id guide. | Free |
Pricing, honestly
Free builds the board; Pro adds push delivery
The match list and scoreboard state are available on Free. Pro adds WebSocket delivery and full play-by-play; neither removes the need for null handling or a reconnect path.
Free scoreboard state
GET /v1/matches?sport=basketball&league=nbaPro push and play-by-play
WebSocket match-room subscription + GET /v1/nba/games/:game_id/plays- Free is enough for schedules, statuses and score cards.
- Pro WebSockets reduce polling latency; they do not guarantee a message while a game is quiet.
- Full NBA play-by-play has a Pro floor.
- Rate limits still apply to the REST fallback.
More tutorials
Other build guides
- How to build a fantasy hockey app
- How to build a fantasy basketball app
- How to build an NHL scoreboard
- How to build an NBA props tracker
- How to build an NBA shot chart
- How to build an NBA matchup page
- How to build an NHL props tracker
- How to build an NHL xG explorer
- How to build an NHL goalie dashboard
- How to build a soccer xG app
- How to build a cricket app
- NFL fantasy football API tutorial
- How to build an NFL scouting tool
- How to build an NFL conditions analytics tool
- NFL betting model API tutorial
- NFL live game center API tutorial
- How to build an NCAAF scoreboard and live game center
- How to build college football rankings and conference standings
- How to build an NCAAF fantasy football app
- How to build an MLB live scoreboard
- How to build a fantasy baseball app
- How to build an MLB pitching dashboard
- How to build an MLB betting model
- How to build an MLB standings dashboard
- How to build a soccer fantasy app
- How to build a soccer betting model
- How to build a soccer live match center
- How to build a soccer player production board
- How to build a soccer fixture alert app
- How to build a soccer scouting tool
- How to build an NCAAF betting model
- How to build an NCAAF conditions analytics tool
- How to build a WNBA live scoreboard
- How to build a WNBA quarter tracker
- How to build a WNBA odds board
- How to build a WNBA schedule browser
- How to build a WNBA team-form tool
- How to build an NCAAB scoreboard
- How to build a March Madness archive
- How to build an NCAAB game-detail view
- How to build an NCAAB team-form dashboard
- How to build an NCAAB head-to-head tool
Known gaps
What this first scoreboard does not promise
Keep the initial build inside the fields and delivery states the API exposes.
- It does not fabricate a game clock when the current response has no clock.
- It does not infer possession, a live win probability or a player on court from the score feed.
- It does not use an external logo or headshot guessed from a team or player name.
Questions
- Can the scoreboard run on the free plan?
- Yes. The canonical NBA match list, statuses and scores have a Free entry point. Pro is needed for WebSocket push and full play-by-play.
- Should a missing score render as 0?
- No. Null before tip-off means the value is not present. A real 0 after play starts is a score and must remain distinguishable.
- How do I keep the board current after a reconnect?
- Refetch the REST match list, replace cards by canonical match id, then resume the room subscription. Do not replay a guessed local state.
- Can I use the same id for every NBA route?
- No. Some NBA-native routes take a league game id while the shared match surface publishes a canonical UUID. Follow the route contract and preserve both when both are returned.
Related APIs
Other APIs you can build with: