Quickstart
Make your first call to the StatsRadar API in under five minutes. Every account — including the free tier — can call all endpoints against sandbox demo games, so you can explore the full data shape before paying anything.
1. Get your API key
Sign up and create a key from the dashboard. Keys are scoped to an environment — start with a test key, which only reaches sandbox data. Every request sends the key as a bearer token — see Authentication.
2. Make your first call
List this week's matches. Copy, paste, run:
curl "https://api.statsradar.io/v1/matches?from=2026-07-01T00:00:00Z&until=2026-07-08T00:00:00Z" \ -H "Authorization: Bearer $STATSRADAR_KEY"
Every response shares the same envelope — data plus an errorCode that is null on success:
{
"data": [{
"league": { "leagueId": "2074414626342305792", "name": "PBA" },
"season": { "name": "Season 50", "type": "Philippine Cup" },
"match": {
"matchId": "2074795629401489408",
"status": "live",
"scheduledStartTime": "2026-07-01T10:00:00Z",
"venueName": "Philippine Arena",
"teams": [
{ "teamId": "2074418534968066048", "name": "Taguig Falcons",
"abbreviation": "TGF", "isHomeTeam": true, "score": "71" },
{ "teamId": "2074418534968066050", "name": "Cebu Mariners",
"abbreviation": "CEB", "isHomeTeam": false, "score": "68" }
]
}
}],
"errorCode": null
}
3. Understand the data model
One consistent schema across every league. Resources form a hierarchy, and every ID is stable and globally unique:
Match lifecycle
Every match carries a status following this lifecycle — scheduled → delayed → live → completed → closed:
Authentication
Every StatsRadar API endpoint requires authentication. Send your API key as a bearer token in the Authorization header of each request.
The Authorization header
Pass the key using the standard HTTP bearer scheme:
curl "https://api.statsradar.io/v1/leagues" \ -H "Authorization: Bearer $STATSRADAR_KEY"
Keys are scoped to an environment — a test key reaches sandbox data only, a live key reaches production data. Create and rotate keys from your dashboard.
Unauthorized requests
A request with a missing or invalid key returns 401 with the standard envelope:
{
"data": null,
"errorCode": "UNAUTHORIZED"
}
Your key also determines which leagues you can read — GET /v1/leagues returns exactly the leagues your key is authorized for.
Keep keys secret
Never embed API keys in client-side code, mobile apps or public repositories. Call the API from your backend and proxy what your frontend needs. If a key may have been exposed, rotate it immediately from the dashboard.
Data model
One consistent schema across every league. Resources form a hierarchy, and every ID is a stable, globally unique string.
Entities
IDs
All identifiers — leagueId, matchId, teamId, playerId — are strings, stable across requests and globally unique across leagues. Treat them as opaque: don't parse or derive meaning from them.
Nullable fields
Fields whose value doesn't exist yet are null, not omitted — e.g. a match's actualStartTime before tip-off, a team's isWon and score before a result exists, or a player's boxScore before they've recorded statistics.
Response envelope
Every endpoint returns the same JSON envelope: a data payload plus an errorCode that is null on success.
Success
data holds the result — an array for list endpoints, an object for detail endpoints:
{
"data": [
{ "leagueId": "2074414626342305792", "name": "PBA" }
],
"errorCode": null
}
Errors
On failure, data is null and errorCode identifies the problem. The HTTP status code always matches the error code:
{
"data": null,
"errorCode": "BAD_REQUEST"
}
Branch on errorCode (or the HTTP status) rather than parsing messages — the set of codes is stable and message text may change.
Match lifecycle
Every match carries a status field. The main flow is scheduled → delayed → live → completed → closed, with two branches for postponements and cancellations.
Statuses
Transitions
A match in scheduled or delayed can branch to postponed, and returns to scheduled once rescheduled — with an updated scheduledStartTime.
Any state before closed — that is scheduled, postponed, delayed, live or completed — can transition to cancelled. Once closed, scores are verified and final.
Timestamps per status
A match's time fields fill in as it progresses through the lifecycle; each is null until its milestone is reached:
Live updates
While a match is live, its score and status update in real time on the match endpoints. Scores visible in completed may still receive corrections; treat closed as the finalized record.
Time & timezones
All timestamps in the API — request parameters and response fields alike — use ISO 8601 in UTC, e.g. 2026-07-01T10:00:00Z. Convert to local time in your application.
Time-range queries
Match listing endpoints filter on the scheduled start time with a from / until pair:
The maximum range is 7 days; a longer range returns 400 BAD_REQUEST. To cover a season, page through consecutive 7-day windows — the exclusive until means windows chain without overlap:
curl "https://api.statsradar.io/v1/matches?from=2026-07-01T00:00:00Z&until=2026-07-08T00:00:00Z" \ -H "Authorization: Bearer $STATSRADAR_KEY"
Match time fields
Matches carry scheduledStartTime, actualStartTime, actualEndTime, closedTime and cancelledTime — all ISO 8601 UTC, and null until the corresponding lifecycle milestone is reached. See Match lifecycle.
Get leagues
Returns the leagues your API key is authorized to read. Use the returned leagueId to scope every other league-level request.
Parameters
No parameters.
Errors
curl "https://api.statsradar.io/v1/leagues" \ -H "Authorization: Bearer $STATSRADAR_KEY"
{
"data": [
{
"leagueId": "2074414626342305792",
"name": "PBA"
},
{
"leagueId": "2074414626342305793",
"name": "MPBL"
}
],
"errorCode": null
}
Get matches by scheduled start time range
Returns matches whose scheduled start time falls in the given range, grouped by league and season. During live matches, score and status update in real time. Also available scoped to one league via /v1/leagues/{leagueId}/matches.
Query parameters
Errors
curl "https://api.statsradar.io/v1/matches?from=2026-07-01T00:00:00Z&until=2026-07-08T00:00:00Z" \ -H "Authorization: Bearer $STATSRADAR_KEY"
{
"data": [{
"league": {
"leagueId": "2074414626342305792",
"name": "PBA"
},
"season": {
"name": "Season 50",
"type": "Philippine Cup"
},
"match": {
"matchId": "2074795629401489408",
"status": "completed",
"scheduledStartTime": "2026-07-01T10:00:00Z",
"actualStartTime": "2026-07-01T10:05:00Z",
"actualEndTime": "2026-07-01T12:15:00Z",
"cancelledTime": null,
"closedTime": null,
"venueName": "Philippine Arena",
"teams": [{
"teamId": "2074418534968066048",
"name": "Taguig Falcons",
"abbreviation": "TGF",
"logo": "https://cdn.statsradar.io/tgf.png",
"isHomeTeam": true,
"isWon": true,
"score": "105"
}, {
"teamId": "2074418534968066050",
"name": "Cebu Mariners",
"abbreviation": "CEB",
"logo": "https://cdn.statsradar.io/ceb.png",
"isHomeTeam": false,
"isWon": false,
"score": "98"
}]
}
}],
"errorCode": null
}
Get matches of a league by scheduled start time range
Returns matches of a single league whose scheduled start time falls in the given range, grouped by season. Same match shape as /v1/matches, without the league wrapper.
Path parameters
Query parameters
Errors
curl "https://api.statsradar.io/v1/leagues/2074414626342305792/matches?from=2026-07-01T00:00:00Z&until=2026-07-08T00:00:00Z" \ -H "Authorization: Bearer $STATSRADAR_KEY"
{
"data": [{
"season": {
"name": "Season 50",
"type": "Philippine Cup"
},
"match": {
"matchId": "2074795629401489408",
"status": "live",
"scheduledStartTime": "2026-07-01T10:00:00Z",
"actualStartTime": "2026-07-01T10:05:00Z",
"actualEndTime": null,
"cancelledTime": null,
"closedTime": null,
"venueName": "Philippine Arena",
"teams": [{
"teamId": "2074418534968066048",
"name": "Taguig Falcons",
"abbreviation": "TGF",
"logo": "https://cdn.statsradar.io/tgf.png",
"isHomeTeam": true,
"isWon": null,
"score": "71"
}, {
"teamId": "2074418534968066050",
"name": "Cebu Mariners",
"abbreviation": "CEB",
"logo": "https://cdn.statsradar.io/ceb.png",
"isHomeTeam": false,
"isWon": null,
"score": "68"
}]
}
}],
"errorCode": null
}
Get match detail by match ID
Returns detailed information for one match, including every participating player with lineup status, availability and a per-player box score. boxScore is null until the player has recorded statistics in the match.
Path parameters
Notes
Errors
curl "https://api.statsradar.io/v1/matches/2074795629401489408" \ -H "Authorization: Bearer $STATSRADAR_KEY"
{
"data": {
"league": {
"leagueId": "2074414626342305792",
"name": "PBA"
},
"season": {
"name": "Season 50",
"type": "Philippine Cup"
},
"match": {
"matchId": "2074795629401489408",
"status": "completed",
"scheduledStartTime": "2026-07-01T10:00:00Z",
"actualStartTime": "2026-07-01T10:05:00Z",
"actualEndTime": "2026-07-01T12:15:00Z",
"cancelledTime": null,
"closedTime": null,
"venueName": "Philippine Arena",
"teams": [{
"teamId": "2074418534968066048",
"name": "Taguig Falcons",
"abbreviation": "TGF",
"logo": "https://cdn.statsradar.io/tgf.png",
"isHomeTeam": true,
"isWon": true,
"score": "105"
}, {
"teamId": "2074418534968066050",
"name": "Cebu Mariners",
"abbreviation": "CEB",
"logo": "https://cdn.statsradar.io/ceb.png",
"isHomeTeam": false,
"isWon": false,
"score": "98"
}],
"players": [{
"playerId": "2074428573690757122",
"name": "John Michael Doe",
"firstName": "John",
"middleName": "Michael",
"lastName": "Doe",
"avatar": "https://cdn.statsradar.io/avatars/doe.png",
"jerseyNumber": "10",
"position": "PG",
"lineupStatus": "starter",
"status": "active",
"teamId": "2074418534968066048",
"boxScore": {
"secondsPlayed": 1440,
"points": 20,
"fieldGoalsAttempted": 15,
"fieldGoalsMade": 8,
"fieldGoalsRateInPercent": "53.33",
"twoPointersAttempted": 12,
"twoPointersMade": 8,
"twoPointersRateInPercent": "66.67",
"threePointersAttempted": 3,
"threePointersMade": 0,
"threePointersRateInPercent": "0.0",
"freeThrowsAttempted": 4,
"freeThrowsMade": 4,
"freeThrowsRateInPercent": "100.0",
"assists": 1,
"rebounds": 3,
"defensiveRebounds": 2,
"offensiveRebounds": 1,
"steals": 1,
"blocks": 0,
"personalFouls": 0,
"turnovers": 0
}
}]
}
},
"errorCode": null
}
Get teams of a league
Returns the teams of a league, with full name, abbreviation and logo URL.
Path parameters
Errors
curl "https://api.statsradar.io/v1/leagues/2074414626342305792/teams" \ -H "Authorization: Bearer $STATSRADAR_KEY"
{
"data": [
{
"teamId": "2074418534968066048",
"name": "Barangay Ginebra San Miguel",
"abbreviation": "GIN",
"logo": "https://cdn.statsradar.io/logos/ginebra.png"
},
{
"teamId": "2074418534968066050",
"name": "Cebu Mariners",
"abbreviation": "CEB",
"logo": "https://cdn.statsradar.io/logos/ceb.png"
}
],
"errorCode": null
}
Get players currently on a team
Returns players currently on a team, including name parts, avatar, jersey number and position.
Path parameters
Notes
Errors
curl "https://api.statsradar.io/v1/leagues/2074414626342305792/teams/2074418534968066048/players" \ -H "Authorization: Bearer $STATSRADAR_KEY"
{
"data": [
{
"playerId": "2074428573690757122",
"name": "John Michael Doe",
"firstName": "John",
"middleName": "Michael",
"lastName": "Doe",
"avatar": "https://cdn.statsradar.io/avatars/doe.png",
"jerseyNumber": "10",
"position": "PG"
}
],
"errorCode": null
}
Get currently injured players of a league
Returns currently injured players of a league. Only injuries the player has not recovered from yet are included; each player’s injuries are ordered newest first and the list is never empty.
Path parameters
Notes
Errors
curl "https://api.statsradar.io/v1/leagues/2074414626342305792/players/injuries" \ -H "Authorization: Bearer $STATSRADAR_KEY"
{
"data": [
{
"playerId": "2074428573690757122",
"injuries": [
{
"bodyPart": "ankle",
"injuryTime": "2026-06-04T00:00:00Z"
}
]
}
],
"errorCode": null
}