Basketball API#
The Basketball API covers leagues, teams, players, games with full box scores and team statistics, pregame reports, standings and model-based predictions.
Base URL: https://sports.bzzoiro.com/basketball/api/v2/
Access#
Requires the Sports Addon ($5/month) — it unlocks the tennis, CS2, darts, hockey, basketball and horse racing APIs plus their MCP servers. Get it at /addons/. You also need a free account token from /register/.
Authorization: Token YOUR_API_KEY
Without a token you get 401:
{"error": "authentication required", "code": "authentication_required",
"detail": "Send Authorization: Token <YOUR_TOKEN> on every request.",
"register": "https://sports.bzzoiro.com/register/"}
With a token but no addon you get 402:
{"error": "Sports Addon required", "code": "addon_required",
"detail": "Tennis, CS:GO, darts, hockey, basketball and horse racing APIs require the Sports Addon ($5/mo).",
"pricing_url": "https://sports.bzzoiro.com/pricing/"}
List endpoints paginate with limit (default 50, max 200) and offset, and
return {count, next, previous, results}.
Endpoints#
| Endpoint | Description |
|---|---|
GET /basketball/api/v2/leagues/ |
List leagues |
GET /basketball/api/v2/leagues/{id}/ |
League detail |
GET /basketball/api/v2/teams/ |
List/search teams |
GET /basketball/api/v2/teams/{id}/ |
Team detail |
GET /basketball/api/v2/events/ |
List games |
GET /basketball/api/v2/events/live/ |
Games in play right now |
GET /basketball/api/v2/events/{id}/ |
Game detail |
GET /basketball/api/v2/events/{id}/odds/ |
Per-bookmaker odds, every market |
GET /basketball/api/v2/events/{id}/box-score/ |
Per-player box score |
GET /basketball/api/v2/events/{id}/team-stats/ |
Team statistics for the game |
GET /basketball/api/v2/events/{id}/pregame/ |
Pregame report |
GET /basketball/api/v2/players/ |
List/search players |
GET /basketball/api/v2/players/{id}/ |
Player detail |
GET /basketball/api/v2/players/{id}/games/ |
Player game log |
GET /basketball/api/v2/managers/ |
List/search coaches |
GET /basketball/api/v2/managers/{id}/ |
Coach detail |
GET /basketball/api/v2/venues/ |
List arenas |
GET /basketball/api/v2/venues/{id}/ |
Arena detail |
GET /basketball/api/v2/standings/ |
League standings |
GET /basketball/api/v2/predictions/ |
Model predictions |
GET /basketball/api/v2/predictions/{id}/ |
One prediction |
Leagues and teams#
Leagues query parameters: country, include_inactive, limit, offset.
Teams query parameters: search, country_code, limit, offset.
curl -H "Authorization: Token YOUR_API_KEY" \
"https://sports.bzzoiro.com/basketball/api/v2/teams/?search=lakers"
{"count": 1, "results": [
{"id": 402, "name": "Los Angeles Lakers", "short_name": "LAL",
"country_code": "US"}
]}
Games#
Query parameters
| Param | Type | Description |
|---|---|---|
league |
int | Filter by league id |
team |
int | Games involving this team id |
status |
string | scheduled, live, finished, postponed, cancelled |
date_from / date_to |
date | YYYY-MM-DD. Without either, the list returns the next 7 days, oldest first. Any of the filters above lifts that window and returns the full archive, newest first. |
limit / offset |
int | Pagination |
{"count": 82, "results": [
{"id": 71204, "league": {"id": 12, "name": "NBA"},
"home_team": {"id": 402, "name": "Los Angeles Lakers"},
"away_team": {"id": 407, "name": "Denver Nuggets"},
"event_date": "2026-04-09T02:30:00+00:00", "status": "finished",
"home_score": 112, "away_score": 108}
]}
GET /events/live/ returns in-play games only (cached 30 seconds).
GET /events/{id}/ adds officials — a raw list of match officials as
reported upstream (typically [{"name": "..."}], shape not normalized).
Usually an empty array — most competitions don't report it.
Box score#
GET /events/{id}/box-score/ returns per-player lines for both teams:
{"event_id": 71204, "home": [
{"player_id": 9931, "name": "LeBron James", "minutes": 36,
"points": 28, "rebounds": 9, "assists": 11, "steals": 1,
"blocks": 1, "turnovers": 3, "fg": "10-19", "three_pt": "3-7", "ft": "5-6"}
]}
Team stats#
GET /events/{id}/team-stats/ returns aggregate shooting, rebounding and
turnover numbers per quarter and for the full game.
Pregame report#
GET /events/{id}/pregame/ bundles what you need before tip-off: coaches,
venue, current standings of both teams, form streaks and players to watch.
Players#
Query parameters: search, team, position, country_code, limit,
offset.
GET /players/{id}/games/ returns the recent game log (limit supported):
{"player_id": 9931, "games": [
{"event_id": 71204, "date": "2026-04-09", "opponent": "Denver Nuggets",
"points": 28, "rebounds": 9, "assists": 11}
]}
Coaches, venues and standings#
GET /managers/—search,team,limit,offset;GET /managers/{id}/.GET /venues/—search,country_code,limit;GET /venues/{id}/.GET /standings/—league(required),season:
{"league_id": 12, "standings": [
{"position": 1, "team": {"id": 407, "name": "Denver Nuggets"},
"played": 82, "wins": 57, "losses": 25, "win_pct": 0.695}
]}
Odds#
GET /basketball/api/v2/events/{id}/odds/ returns every price we hold for one event: the
match-winner market flattened per bookmaker, and below it every other market the
books offered, grouped by kind, line and period.
curl -H "Authorization: Token YOUR_API_KEY" \
"https://sports.bzzoiro.com/basketball/api/v2/events/7108/odds/"
{"event_id": 7108, "event_date": "2026-12-25T20:00:00+00:00",
"home_team_name": "Boston Celtics", "away_team_name": "Miami Heat",
"bookmakers_count": 14, "source": "multi",
"bookmakers": [
{"bookmaker": "Bet365", "bookmaker_slug": "bet365",
"odds_home": 1.77, "movement_home": "STABLE",
"odds_away": 2.19, "movement_away": "STABLE",
"updated_at": "2026-12-25T18:30:26Z"}
],
"markets": [
{"market_kind": "AH", "market_family": "AH", "market_line": -3.5,
"market_period": "FT", "selections": ["HOME", "AWAY"],
"bookmakers": [
{"bookmaker": "Bet365", "bookmaker_slug": "bet365",
"prices": {"HOME": {"price": 1.91, "movement": "STABLE"},
"AWAY": {"price": 1.91, "movement": "STABLE"}},
"updated_at": "2026-12-25T18:30:26Z"}
]}
]}
| Field | Meaning |
|---|---|
source |
multi per-bookmaker prices, consensus the single stored price when the match is not yet linked to a priced feed event, none when nobody has priced it |
bookmakers_count |
Bookmakers with at least one match-winner price |
movement_* |
SHORTENING, DRIFTING or STABLE against the previous price we saw; null when there is no previous price |
market_kind |
Market type: WINNER, AH (spread), OU (total points) |
market_family |
Distinguishes markets sharing a kind (total goals vs corners vs a single side's total) |
market_line |
The handicap or total the market is quoted on; null for a plain winner market |
market_period |
FT for the full match; period codes otherwise |
Prices come from several sources and are pooled per match. A bookmaker appears once per market with its most recent price.
Predictions#
Query parameters
| Param | Type | Description |
|---|---|---|
league |
int | Filter by league id |
days |
int | Look-ahead window in days |
confidence |
float | Minimum model confidence (0–1) |
limit / offset |
int | Pagination |
{"count": 6, "results": [
{"id": 8817, "event_id": 71250,
"home_win_prob": 0.61, "away_win_prob": 0.39,
"predicted_winner_id": 402, "confidence": 0.61}
]}
Coverage and off-season#
The domestic seasons run roughly September to June, so for a stretch of the summer there are no fixtures to return. An empty list on its own cannot tell you whether the season is over or the sync is broken.
GET /api/v2/coverage/?sport=basketball says so directly, without a token:
{"sport": "basketball", "status": "between_events", "events_next_7d": 0,
"events_next_30d": 0, "priced_next_7d": 0, "live_now": 0,
"next_event_at": "2026-09-18T18:00:00+00:00", "last_event_at": "2026-06-24T18:00:00+00:00"}
status is in_season (fixtures within seven days), between_events (nothing
this week, something later), off_season (nothing ahead and the last event is
more than a fortnight old) or no_fixtures. Drop the ?sport= to get every
sport in one call — worth doing before a polling loop decides what to ask for.