ScoreLab API

The ScoreLab API enables developers to securely access league data for use in third-party applications and websites. For example, you can build a custom leaderboard or basketball fantasy game, such as Scorelab fantasy, for your league.

Get started

All requests are GET, scoped to the league on your API key, and return only publicly accessible data.

1. Create a key

To create an API key, go to Portal → Overview → API keys and click Create. Be sure to copy the secret key (for example, slk_live_…) when it is shown, because it can only be viewed once. For security, always keep this key on a server and never expose it in a public client. You may have up to 50 active keys per league.

2. Authenticate

Send your secret key in the Authorization header on every request.

Authorization: Bearer slk_live_YOUR_KEY

3. First request

Start by listing recent matches for the league on your key.

curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/matches?limit=20"

Every response uses the envelope { "data": …, "meta": { "version": "v1", … } }. List endpoints return data as an array. A request that includes id returns a single object.

Limits and errors

Each key allows 60 requests per minute and 2000 requests per day. Going over the limit returns 429 with a Retry-After header in seconds. The list limit parameter defaults to 20 and has a maximum of 100.

StatusWhen
400The query is invalid. Common causes include an unknown include value or a malformed id.
401The API key is missing or invalid.
404The resource is not in this league.
405The method is not GET.
429The rate limit was exceeded.

Error bodies look like { "error": "…" } and include a short message that describes the problem.

GET/api/v1/matches

Matches

Omit id to list matches, or pass id to fetch one match. playByPlay is only available on a single-match request.

Query parameters

QueryDetailsExample
idThe match id. When this parameter is set, the response is a single match.id=64f1a2b3c4d5e6f7a8b9c0d1
seasonIdOn list requests, this parameter filters matches to a season that belongs to your league.seasonId=64f1…
teamIdOn list requests, this parameter filters to matches where the team is home or away.teamId=64f1…
dateStartOn list requests, this parameter sets the start of a UTC day range (YYYY-MM-DD). It requires dateEnd.dateStart=2026-01-01
dateEndOn list requests, this parameter sets the end of a UTC day range (YYYY-MM-DD). It requires dateStart.dateEnd=2026-01-31
isMatchEndOn list requests, this parameter filters to finished or unfinished matches.isMatchEnd=true
limitOn list requests, this parameter sets the page size. The default is 20 and the maximum is 100.limit=20
offsetOn list requests, this parameter skips the first N results.offset=0
playLimitThis parameter is used only with include=playByPlay. It sets the page size for plays. The default is 100 and the maximum is 200.playLimit=100
playOffsetThis parameter is used only with include=playByPlay. It skips the first N plays, ordered by quarter and then by clock.playOffset=0

include values

Core match fields are always returned. List responses always include score and teams. A single-match request always includes score, teams, season, teamStats, and boxScore. The only optional include is playByPlay, and it requires id.

includeDetailsExample
playByPlayAdds one page of public plays. This include requires id.include=playByPlay

Play-by-play paging

Play-by-play is returned one page at a time. Each request returns up to playLimit plays. The default is 100 and the maximum is 200. Plays are ordered by quarter and then by clock, the same as the match page. Use playOffset to skip earlier plays and fetch the next page. When include=playByPlay is set, the meta object also includes the following fields:

Meta fieldDetails
playLimitThe page size used for this response. The default is 100 and the maximum is 200.
playOffsetThe number of plays skipped before this page.
playTotalThe total number of public plays in the match. Compare this value with playOffset plus the number of returned plays to decide whether to request the next page.

For example, if playTotal is 142 and the first page used playLimit=100 with playOffset=0, request the remaining plays with playOffset=100.

Examples

curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/matches?limit=20"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/matches?id=MATCH_ID"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/matches?id=MATCH_ID&include=playByPlay&playLimit=100&playOffset=0"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/matches?id=MATCH_ID&include=playByPlay&playLimit=100&playOffset=100"

Example response (single match with playByPlay)

{
  "data": {
    "id": "64f1a2b3c4d5e6f7a8b9c0d1",
    "url": "https://scorelab.tech/match/64f1a2b3c4d5e6f7a8b9c0d1",
    "seasonId": "64f1a2b3c4d5e6f7a8b9c0d2",
    "homeTeamId": "64f1a2b3c4d5e6f7a8b9c0d3",
    "awayTeamId": "64f1a2b3c4d5e6f7a8b9c0d4",
    "isMatchEnd": true,
    "isForfeit": false,
    "details": {
      "matchDate": "2026-03-01T18:00:00.000Z",
      "matchTimezone": "America/Toronto",
      "matchLocation": "Main Gym",
      "matchStartTime": "2026-03-01T18:05:00.000Z",
      "matchEndTime": "2026-03-01T19:40:00.000Z"
    },
    "youtube": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
    "score": {
      "home": {
        "breakdown": [18, 20, 22, 18],
        "overtime": [8, 5],
        "total": 86
      },
      "away": {
        "breakdown": [15, 19, 17, 20],
        "overtime": [6, 0],
        "total": 77
      }
    },
    "homeTeam": {
      "id": "64f1a2b3c4d5e6f7a8b9c0d3",
      "name": "Northside",
      "image": "https://cdn.scorelab.tech/teams/northside.png",
      "abbreviation": "NOR",
      "url": "https://scorelab.tech/team/northside"
    },
    "awayTeam": {
      "id": "64f1a2b3c4d5e6f7a8b9c0d4",
      "name": "Eastbay",
      "image": "https://cdn.scorelab.tech/teams/eastbay.png",
      "abbreviation": "EAS",
      "url": "https://scorelab.tech/team/eastbay"
    },
    "season": {
      "id": "64f1a2b3c4d5e6f7a8b9c0d2",
      "name": "Spring 2026",
      "image": "https://cdn.scorelab.tech/seasons/spring-2026-banner.jpg",
      "isSeasonEnd": false,
      "url": "https://scorelab.tech/season/64f1a2b3c4d5e6f7a8b9c0d2"
    },
    "teamStats": {
      "home": {
        "PTS": 86,
        "REB": 32,
        "OREB": 10,
        "DREB": 22,
        "AST": 18,
        "STL": 7,
        "BLK": 3,
        "TO": 11,
        "FTM": 12,
        "FTA": 16,
        "PF": 14,
        "TF": 1,
        "1PA": 2,
        "1PM": 1,
        "2PA": 41,
        "2PM": 22,
        "3PA": 21,
        "3PM": 8
      },
      "away": {
        "PTS": 77,
        "REB": 28,
        "OREB": 8,
        "DREB": 20,
        "AST": 14,
        "STL": 5,
        "BLK": 2,
        "TO": 13,
        "FTM": 9,
        "FTA": 13,
        "PF": 16,
        "TF": 0,
        "1PA": 1,
        "1PM": 0,
        "2PA": 38,
        "2PM": 19,
        "3PA": 24,
        "3PM": 9
      }
    },
    "boxScore": {
      "home": [
        {
          "playerId": "64f1a2b3c4d5e6f7a8b9c0d6",
          "name": "Alex Kim",
          "jersey": 7,
          "image": "https://cdn.scorelab.tech/players/alex-kim.png",
          "MINS": 34,
          "PTS": 22,
          "1PM": 1,
          "1PA": 2,
          "2PM": 6,
          "2PA": 11,
          "3PM": 2,
          "3PA": 5,
          "FTM": 3,
          "FTA": 4,
          "REB": 4,
          "OREB": 1,
          "DREB": 3,
          "AST": 5,
          "STL": 2,
          "BLK": 1,
          "TO": 1,
          "PF": 2,
          "TF": 0,
          "EFF": 24,
          "PLUS_MINUS": 9
        },
        {
          "playerId": "64f1a2b3c4d5e6f7a8b9c0d9",
          "name": "Jordan Wu",
          "jersey": 11,
          "image": "https://cdn.scorelab.tech/players/jordan-wu.png",
          "MINS": 28,
          "PTS": 14,
          "1PM": 0,
          "1PA": 0,
          "2PM": 4,
          "2PA": 8,
          "3PM": 2,
          "3PA": 4,
          "FTM": 0,
          "FTA": 0,
          "REB": 6,
          "OREB": 2,
          "DREB": 4,
          "AST": 3,
          "STL": 1,
          "BLK": 0,
          "TO": 2,
          "PF": 3,
          "TF": 0,
          "EFF": 16,
          "PLUS_MINUS": 5
        }
      ],
      "away": [
        {
          "playerId": "64f1a2b3c4d5e6f7a8b9c0d8",
          "name": "Sam Lee",
          "jersey": 3,
          "image": "https://cdn.scorelab.tech/players/sam-lee.png",
          "MINS": 32,
          "PTS": 19,
          "1PM": 0,
          "1PA": 1,
          "2PM": 5,
          "2PA": 10,
          "3PM": 2,
          "3PA": 6,
          "FTM": 3,
          "FTA": 4,
          "REB": 5,
          "OREB": 1,
          "DREB": 4,
          "AST": 4,
          "STL": 1,
          "BLK": 1,
          "TO": 2,
          "PF": 2,
          "TF": 0,
          "EFF": 18,
          "PLUS_MINUS": -4
        },
        {
          "playerId": "64f1a2b3c4d5e6f7a8b9c0da",
          "name": "Chris Park",
          "jersey": 22,
          "image": "https://cdn.scorelab.tech/players/chris-park.png",
          "MINS": 26,
          "PTS": 12,
          "1PM": 0,
          "1PA": 0,
          "2PM": 3,
          "2PA": 7,
          "3PM": 2,
          "3PA": 5,
          "FTM": 0,
          "FTA": 0,
          "REB": 3,
          "OREB": 0,
          "DREB": 3,
          "AST": 2,
          "STL": 2,
          "BLK": 0,
          "TO": 1,
          "PF": 1,
          "TF": 0,
          "EFF": 11,
          "PLUS_MINUS": -3
        }
      ]
    },
    "playByPlay": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0d7",
        "playerId": "64f1a2b3c4d5e6f7a8b9c0d6",
        "side": "home",
        "action": "2PM",
        "matchQuarter": 1,
        "matchTime": "09:15",
        "points": 2
      },
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0db",
        "playerId": "64f1a2b3c4d5e6f7a8b9c0d8",
        "side": "away",
        "action": "3PM",
        "matchQuarter": 1,
        "matchTime": "08:42",
        "points": 3
      },
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0dc",
        "playerId": "64f1a2b3c4d5e6f7a8b9c0d6",
        "side": "home",
        "action": "AST",
        "matchQuarter": 2,
        "matchTime": "05:10",
        "points": 0
      },
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0dd",
        "playerId": "64f1a2b3c4d5e6f7a8b9c0d9",
        "side": "home",
        "action": "FTM",
        "matchQuarter": "ot1",
        "matchTime": "01:20",
        "points": 1
      }
    ]
  },
  "meta": {
    "version": "v1",
    "include": ["playByPlay"],
    "playLimit": 100,
    "playOffset": 0,
    "playTotal": 142
  }
}
GET/api/v1/seasons

Seasons

This endpoint lists seasons in your league, or returns one season when you pass id. A single-season request includes the match schedule and results by default through matches.

Query parameters

QueryDetailsExample
idThe season id. When this parameter is set, the response is a single season.id=64f1…
isSeasonEndOn list requests, this parameter filters to finished or unfinished seasons.isSeasonEnd=false
activeOn list requests, this parameter filters by the active flag in the database.active=true
limitOn list requests, this parameter sets the page size. The default is 20 and the maximum is 100.limit=20
offsetOn list requests, this parameter skips the first N results.offset=0
matchLimitThis parameter is used with include=matches. The default is 20 and the maximum is 100.matchLimit=20
matchOffsetThis parameter is used with include=matches. It skips the first N matches, ordered by date ascending.matchOffset=0
statThis parameter is required with include=topPlayers. Request one stat category per request.stat=PTS
topLimitThis parameter is used with include=topPlayers. The default is 20 and the maximum is 100.topLimit=20
topOffsetThis parameter is used with include=topPlayers. It skips the first N leaders for that stat.topOffset=0

include values

Core season fields are always returned. A single-season request includes matches by default. standings and topPlayers require id.

includeDetailsExample
matchesReturns a paged match schedule and results, including score and teams. This is the default on a single-season request.include=matches
standingsReturns standings by stage, including overall tables, group tables, or playoff brackets.include=standings
topPlayersReturns leaders for one stat. This include requires stat.include=topPlayers&stat=PTS

Matches paging

With include=matches, results are ordered by match date ascending. Use matchLimit (default 20, maximum 100) and matchOffset to page through the schedule. The meta object includes matchTotal.

Standings by stage

standings is an array of stages. Each item has a type of overall, group, or playoff, and a name.

Group stages expose groups with ranked team rows. Playoff stages expose brackets that include rounds, matchups, series, and winnerId. A bronze matchup is included when bronze is enabled.

Top players

Request one category at a time with stat. The allowed values are PTS, REB, AST, STL, BLK, efficiency, 3PM, 2PM, 1PM, and FTM. Page the results with topLimit and topOffset. The meta object includes topTotal.

Examples

curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/seasons?limit=20"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/seasons?id=SEASON_ID&include=matches&matchLimit=20&matchOffset=0"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/seasons?id=SEASON_ID&include=standings"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/seasons?id=SEASON_ID&include=topPlayers&stat=PTS&topLimit=20&topOffset=0"

Example response (single season with matches, standings, and topPlayers)

{
  "data": {
    "id": "64f1a2b3c4d5e6f7a8b9c0d2",
    "name": "Spring 2026",
    "image": "https://cdn.scorelab.tech/seasons/spring-2026-banner.jpg",
    "isSeasonEnd": false,
    "url": "https://scorelab.tech/season/64f1a2b3c4d5e6f7a8b9c0d2",
    "matches": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0d1",
        "url": "https://scorelab.tech/match/64f1a2b3c4d5e6f7a8b9c0d1",
        "seasonId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "homeTeamId": "64f1a2b3c4d5e6f7a8b9c0d3",
        "awayTeamId": "64f1a2b3c4d5e6f7a8b9c0d4",
        "isMatchEnd": true,
        "isForfeit": false,
        "details": {
          "matchDate": "2026-03-01T18:00:00.000Z",
          "matchTimezone": "America/Toronto",
          "matchLocation": "Main Gym",
          "matchStartTime": "2026-03-01T18:05:00.000Z",
          "matchEndTime": "2026-03-01T19:40:00.000Z"
        },
        "youtube": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "score": {
          "home": {
            "breakdown": [18, 20, 22, 18],
            "overtime": [8, 5],
            "total": 86
          },
          "away": {
            "breakdown": [15, 19, 17, 20],
            "overtime": [6, 0],
            "total": 77
          }
        },
        "homeTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d3",
          "name": "Northside",
          "image": "https://cdn.scorelab.tech/teams/northside.png",
          "abbreviation": "NOR",
          "url": "https://scorelab.tech/team/northside"
        },
        "awayTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d4",
          "name": "Eastbay",
          "image": "https://cdn.scorelab.tech/teams/eastbay.png",
          "abbreviation": "EAS",
          "url": "https://scorelab.tech/team/eastbay"
        }
      }
    ],
    "standings": [
      {
        "type": "group",
        "name": "Group Stage",
        "groups": [
          {
            "name": "Group A",
            "teams": [
              {
                "id": "64f1a2b3c4d5e6f7a8b9c0d3",
                "name": "Northside",
                "image": "https://cdn.scorelab.tech/teams/northside.png",
                "abbreviation": "NOR",
                "url": "https://scorelab.tech/team/northside",
                "record": { "wins": 8, "losses": 2, "draws": 0 },
                "points": 16,
                "pointsFor": 720,
                "pointsAgainst": 640,
                "pointsDifferential": 80,
                "matchesPlayed": 10,
                "ranking": 1
              }
            ]
          }
        ]
      },
      {
        "type": "playoff",
        "name": "Playoffs",
        "brackets": [
          {
            "name": "Main Bracket",
            "format": ["bo1", "bo3"],
            "bronze": true,
            "rounds": [
              {
                "roundIndex": 0,
                "name": "Round 1",
                "matchups": [
                  {
                    "teamA": {
                      "id": "64f1a2b3c4d5e6f7a8b9c0d3",
                      "name": "Northside",
                      "image": "https://cdn.scorelab.tech/teams/northside.png",
                      "abbreviation": "NOR",
                      "url": "https://scorelab.tech/team/northside",
                      "bye": false
                    },
                    "teamB": {
                      "id": "64f1a2b3c4d5e6f7a8b9c0d4",
                      "name": "Eastbay",
                      "image": "https://cdn.scorelab.tech/teams/eastbay.png",
                      "abbreviation": "EAS",
                      "url": "https://scorelab.tech/team/eastbay",
                      "bye": false
                    },
                    "winnerId": "64f1a2b3c4d5e6f7a8b9c0d3",
                    "series": { "teamA": 1, "teamB": 0 },
                    "isGoldMatch": false,
                    "isBronzeMatch": false
                  }
                ]
              }
            ]
          }
        ]
      }
    ],
    "topPlayers": {
      "stat": "PTS",
      "players": [
        {
          "playerId": "64f1a2b3c4d5e6f7a8b9c0d6",
          "name": "Alex Kim",
          "number": "7",
          "teamId": "64f1a2b3c4d5e6f7a8b9c0d3",
          "teamName": "Northside",
          "teamUrl": "https://scorelab.tech/team/northside",
          "gamesPlayed": 10,
          "PTS": 182,
          "REB": 44,
          "AST": 51,
          "STL": 18,
          "BLK": 4,
          "TO": 22,
          "PF": 18,
          "1PM": 0,
          "1PA": 0,
          "2PM": 48,
          "2PA": 90,
          "3PM": 22,
          "3PA": 55,
          "FTM": 20,
          "FTA": 28,
          "efficiency": 210
        }
      ]
    }
  },
  "meta": {
    "version": "v1",
    "include": ["matches", "standings", "topPlayers"],
    "matchLimit": 20,
    "matchOffset": 0,
    "matchTotal": 42,
    "stat": "PTS",
    "topLimit": 20,
    "topOffset": 0,
    "topTotal": 48
  }
}
GET/api/v1/teams

Teams

This endpoint lists teams in your league, or returns one team when you pass id. A single-team request always returns the active roster in players and the match history in matchHistory. Pass seasonId as a comma-separated list to scope aggregates. The default is all active seasons that have not ended.

Query parameters

QueryDetailsExample
idThe team id. When this parameter is set, the response is a single team.id=64f1…
seasonIdOn a single-team request, this parameter filters aggregates to one or more seasons. On a list request, it returns teams linked to one season.seasonId=64f1…,64f2…
activeOn list requests, this parameter defaults to true when it is omitted.active=true
qOn list requests, this parameter performs a case-insensitive search on the team name.q=north
limitOn list requests, this parameter sets the page size. The default is 20 and the maximum is 100.limit=20
offsetOn list requests, this parameter skips the first N results.offset=0
matchLimitThis parameter applies to single-team requests. It pages matchHistory and boxScore. The default is 20 and the maximum is 100.matchLimit=20
matchOffsetThis parameter applies to single-team requests. It skips the first N matches, ordered by date ascending.matchOffset=0
statThis parameter is required with include=leaders. The allowed values are PTS, REB, and AST.stat=PTS
topLimitThis parameter is used with include=leaders. The default is 20 and the maximum is 100.topLimit=20
topOffsetThis parameter is used with include=leaders. It skips the first N leaders for that stat.topOffset=0

include values

Core team fields, players, and matchHistory are always returned on a single-team request. The optional includes below require id.

includeDetailsExample
boxScoreAdds per-match team box score rows for the selected seasons.include=boxScore
careerStatsAdds totals and per-game averages for the selected seasons.include=careerStats
leadersAdds leaders for one stat. This include requires stat set to PTS, REB, or AST.include=leaders&stat=PTS
recordAdds wins, losses, and draws for the selected seasons.include=record

Match history paging

On a single-team request, matchHistory is paged with matchLimit (default 20, maximum 100) and matchOffset, and the results are ordered by match date ascending. When include=boxScore is set, those rows use the same page. The meta object includes matchTotal. careerStats, leaders, and record still use all matches in the selected seasons.

Leaders

Request one category at a time with stat. The allowed values are PTS, REB, and AST. Page the results with topLimit and topOffset. The meta object includes topTotal.

Examples

curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/teams?limit=20"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/teams?id=TEAM_ID&seasonId=SEASON_ID&matchLimit=20&matchOffset=0"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/teams?id=TEAM_ID&include=leaders&stat=PTS&topLimit=20&topOffset=0"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/teams?id=TEAM_ID&include=boxScore,careerStats,leaders,record&stat=PTS&matchLimit=20"

Example response (single team with all includes)

{
  "data": {
    "id": "64f1a2b3c4d5e6f7a8b9c0d3",
    "name": "Northside",
    "image": "https://cdn.scorelab.tech/teams/northside.png",
    "abbreviation": "NOR",
    "url": "https://scorelab.tech/team/northside",
    "players": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0d6",
        "name": "Alex Kim",
        "number": "7",
        "image": "https://cdn.scorelab.tech/players/alex-kim.png",
        "teamId": "64f1a2b3c4d5e6f7a8b9c0d3",
        "isRetired": false,
        "url": "https://scorelab.tech/player/64f1a2b3c4d5e6f7a8b9c0d6"
      }
    ],
    "matchHistory": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0d1",
        "url": "https://scorelab.tech/match/64f1a2b3c4d5e6f7a8b9c0d1",
        "seasonId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "homeTeamId": "64f1a2b3c4d5e6f7a8b9c0d3",
        "awayTeamId": "64f1a2b3c4d5e6f7a8b9c0d4",
        "isMatchEnd": true,
        "isForfeit": false,
        "details": {
          "matchDate": "2026-03-01T18:00:00.000Z",
          "matchTimezone": "America/Toronto",
          "matchLocation": "Main Gym",
          "matchStartTime": "2026-03-01T18:05:00.000Z",
          "matchEndTime": "2026-03-01T19:40:00.000Z"
        },
        "youtube": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "score": {
          "home": {
            "breakdown": [18, 20, 22, 18],
            "overtime": [8, 5],
            "total": 86
          },
          "away": {
            "breakdown": [15, 19, 17, 20],
            "overtime": [6, 0],
            "total": 77
          }
        },
        "homeTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d3",
          "name": "Northside",
          "image": "https://cdn.scorelab.tech/teams/northside.png",
          "abbreviation": "NOR",
          "url": "https://scorelab.tech/team/northside"
        },
        "awayTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d4",
          "name": "Eastbay",
          "image": "https://cdn.scorelab.tech/teams/eastbay.png",
          "abbreviation": "EAS",
          "url": "https://scorelab.tech/team/eastbay"
        }
      }
    ],
    "boxScore": [
      {
        "matchId": "64f1a2b3c4d5e6f7a8b9c0d1",
        "seasonId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "matchDate": "2026-03-01T18:00:00.000Z",
        "matchTimezone": "America/Toronto",
        "isMatchEnd": true,
        "isForfeit": false,
        "isHome": true,
        "isWin": true,
        "isLoss": false,
        "isDraw": false,
        "teamScore": 86,
        "opponentScore": 77,
        "scoreDisplay": "86-77",
        "homeTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d3",
          "name": "Northside",
          "image": "https://cdn.scorelab.tech/teams/northside.png",
          "abbreviation": "NOR",
          "url": "https://scorelab.tech/team/northside"
        },
        "awayTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d4",
          "name": "Eastbay",
          "image": "https://cdn.scorelab.tech/teams/eastbay.png",
          "abbreviation": "EAS",
          "url": "https://scorelab.tech/team/eastbay"
        },
        "stats": {
          "PTS": 86,
          "1PM": 0,
          "1PA": 0,
          "2PM": 28,
          "2PA": 52,
          "3PM": 8,
          "3PA": 22,
          "FTM": 6,
          "FTA": 10,
          "OREB": 12,
          "DREB": 28,
          "REB": 40,
          "AST": 18,
          "STL": 7,
          "BLK": 3,
          "TO": 11,
          "PF": 14
        }
      }
    ],
    "careerStats": {
      "totalPoints": 1240,
      "totalRebounds": 580,
      "totalAssists": 310,
      "pointsPerGame": "82.7",
      "reboundsPerGame": "38.7",
      "assistsPerGame": "20.7",
      "gamesPlayed": 15
    },
    "leaders": {
      "stat": "PTS",
      "players": [
        {
          "playerId": "64f1a2b3c4d5e6f7a8b9c0d6",
          "name": "Alex Kim",
          "number": "7",
          "image": "https://cdn.scorelab.tech/players/alex-kim.png",
          "PTS": 182,
          "REB": 44,
          "AST": 51
        }
      ]
    },
    "record": {
      "wins": 12,
      "losses": 3,
      "draws": 0
    }
  },
  "meta": {
    "version": "v1",
    "include": ["boxScore", "careerStats", "leaders", "record"],
    "matchLimit": 20,
    "matchOffset": 0,
    "matchTotal": 15,
    "stat": "PTS",
    "topLimit": 20,
    "topOffset": 0,
    "topTotal": 8,
    "seasonIds": ["64f1a2b3c4d5e6f7a8b9c0d2"]
  }
}
GET/api/v1/players

Players

This endpoint lists players in your league, or returns one player when you pass id. A single-player request always returns per-match rows in boxScore and match history in matchHistory. Pass seasonId as a comma-separated list to scope aggregates. The default is all active seasons that have not ended.

Query parameters

QueryDetailsExample
idThe player id. When this parameter is set, the response is a single player.id=64f1…
seasonIdThis parameter applies to single-player requests. It filters aggregates to one or more seasons.seasonId=64f1…,64f2…
teamIdOn list requests, this parameter filters to players on this team.teamId=64f1…
activeOn list requests, this parameter defaults to true when it is omitted.active=true
qOn list requests, this parameter performs a case-insensitive search on the player name.q=kim
limitOn list requests, this parameter sets the page size. The default is 20 and the maximum is 100.limit=20
offsetOn list requests, this parameter skips the first N results.offset=0
matchLimitThis parameter applies to single-player requests. It pages matchHistory and boxScore. The default is 20 and the maximum is 100.matchLimit=20
matchOffsetThis parameter applies to single-player requests. It skips the first N matches, ordered by date ascending.matchOffset=0

include values

Core player fields, boxScore, and matchHistory are always returned on a single-player request. The optional includes below require id.

includeDetailsExample
careerStatsAdds totals, per-game averages, and gamesPlayed for the selected seasons.include=careerStats

Match history paging

On a single-player request, matchHistory and boxScore are paged with matchLimit (default 20, maximum 100) and matchOffset, and the results are ordered by match date ascending. The meta object includes matchTotal. careerStats still uses all matches in the selected seasons.

Examples

curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/players?teamId=TEAM_ID&limit=50"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/players?id=PLAYER_ID&seasonId=SEASON_ID&matchLimit=20&matchOffset=0"
curl -H "Authorization: Bearer slk_live_YOUR_KEY" \
  "https://www.scorelab.tech/api/v1/players?id=PLAYER_ID&include=careerStats&matchLimit=20"

Example response (single player with careerStats)

{
  "data": {
    "id": "64f1a2b3c4d5e6f7a8b9c0d6",
    "name": "Alex Kim",
    "number": "7",
    "image": "https://cdn.scorelab.tech/players/alex-kim.png",
    "teamId": "64f1a2b3c4d5e6f7a8b9c0d3",
    "isRetired": false,
    "url": "https://scorelab.tech/player/64f1a2b3c4d5e6f7a8b9c0d6",
    "boxScore": [
      {
        "matchId": "64f1a2b3c4d5e6f7a8b9c0d1",
        "seasonId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "matchDate": "2026-03-01T18:00:00.000Z",
        "matchTimezone": "America/Toronto",
        "isMatchEnd": true,
        "isForfeit": false,
        "playerSide": "home",
        "score": {
          "home": {
            "breakdown": [18, 20, 22, 18],
            "overtime": [8, 5],
            "total": 86
          },
          "away": {
            "breakdown": [15, 19, 17, 20],
            "overtime": [6, 0],
            "total": 77
          }
        },
        "homeTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d3",
          "name": "Northside",
          "image": "https://cdn.scorelab.tech/teams/northside.png",
          "abbreviation": "NOR",
          "url": "https://scorelab.tech/team/northside"
        },
        "awayTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d4",
          "name": "Eastbay",
          "image": "https://cdn.scorelab.tech/teams/eastbay.png",
          "abbreviation": "EAS",
          "url": "https://scorelab.tech/team/eastbay"
        },
        "stats": {
          "PTS": 18,
          "1PM": 0,
          "1PA": 0,
          "2PM": 6,
          "2PA": 11,
          "3PM": 2,
          "3PA": 5,
          "FTM": 0,
          "FTA": 0,
          "REB": 4,
          "OREB": 1,
          "DREB": 3,
          "AST": 5,
          "STL": 2,
          "BLK": 0,
          "TO": 1,
          "PF": 2,
          "EFF": 22
        }
      }
    ],
    "matchHistory": [
      {
        "id": "64f1a2b3c4d5e6f7a8b9c0d1",
        "url": "https://scorelab.tech/match/64f1a2b3c4d5e6f7a8b9c0d1",
        "seasonId": "64f1a2b3c4d5e6f7a8b9c0d2",
        "homeTeamId": "64f1a2b3c4d5e6f7a8b9c0d3",
        "awayTeamId": "64f1a2b3c4d5e6f7a8b9c0d4",
        "isMatchEnd": true,
        "isForfeit": false,
        "details": {
          "matchDate": "2026-03-01T18:00:00.000Z",
          "matchTimezone": "America/Toronto",
          "matchLocation": "Main Gym",
          "matchStartTime": "2026-03-01T18:05:00.000Z",
          "matchEndTime": "2026-03-01T19:40:00.000Z"
        },
        "youtube": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
        "score": {
          "home": {
            "breakdown": [18, 20, 22, 18],
            "overtime": [8, 5],
            "total": 86
          },
          "away": {
            "breakdown": [15, 19, 17, 20],
            "overtime": [6, 0],
            "total": 77
          }
        },
        "homeTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d3",
          "name": "Northside",
          "image": "https://cdn.scorelab.tech/teams/northside.png",
          "abbreviation": "NOR",
          "url": "https://scorelab.tech/team/northside"
        },
        "awayTeam": {
          "id": "64f1a2b3c4d5e6f7a8b9c0d4",
          "name": "Eastbay",
          "image": "https://cdn.scorelab.tech/teams/eastbay.png",
          "abbreviation": "EAS",
          "url": "https://scorelab.tech/team/eastbay"
        }
      }
    ],
    "careerStats": {
      "totalPoints": 182,
      "totalRebounds": 44,
      "totalAssists": 51,
      "pointsPerGame": "18.2",
      "reboundsPerGame": "4.4",
      "assistsPerGame": "5.1",
      "gamesPlayed": 10
    }
  },
  "meta": {
    "version": "v1",
    "include": ["careerStats"],
    "matchLimit": 20,
    "matchOffset": 0,
    "matchTotal": 10,
    "seasonIds": ["64f1a2b3c4d5e6f7a8b9c0d2"]
  }
}