Basketball Scraper: Box Scores, Play-by-Play & Odds avatar

Basketball Scraper: Box Scores, Play-by-Play & Odds

Pricing

from $12.60 / 1,000 match records

Go to Apify Store
Basketball Scraper: Box Scores, Play-by-Play & Odds

Basketball Scraper: Box Scores, Play-by-Play & Odds

Basketball scraper for NBA, EuroLeague and other leagues: game results with score by quarter, team stats, player box scores, play-by-play, odds, lineups, rosters and standings from Sofascore. Export CSV, Excel, JSON, XML. No login or API key. 10 record types.

Pricing

from $12.60 / 1,000 match records

Rating

0.0

(0)

Developer

RecordsData

RecordsData

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

0

Monthly active users

19 hours ago

Last modified

Share

PunkRecordsData

Basketball Scraper collects Sofascore basketball games for any NBA, EuroLeague or other team: score by quarter, box scores, play-by-play, odds, lineups, rosters and standings. Enter a team name or match ID, export CSV, Excel or JSON. No login or API key. $0.015 per game, $0.01 per extra record; team statistics are off by default.

Basketball Scraper turns a team name such as "Los Angeles Lakers" into structured game data: the final score, points per quarter, per-quarter team statistics, a full box score line for every player who played, a minute-by-minute point-margin curve and every scoring play. In our reference run on one NBA game (Orlando Magic vs Los Angeles Lakers, 104-105) the Actor returned 71 team stat lines (optional, off by default), 19 player box scores, 115 scoring plays, a 48-point margin graph, 58 roster players (two teams) and 15 standings rows. A second verified cloud run on 2026-10-04 returned 10 Los Angeles Lakers games with 225 player box scores, 1,226 scoring plays and 480 margin graph points. It is built for fantasy and DFS tools, betting-model backtests, sports media and analysts.

πŸ€ What does Basketball Scraper do?

  • Finds a team by name and collects its recent and upcoming games, or fetches specific matches by Sofascore match ID.
  • Lists every currently live basketball game with the "Live games only" switch.
  • Returns the result, tournament, status, start time and score by quarter for each game.
  • Adds optional extras per game: team statistics, player box scores, lineups, head-to-head record, betting odds, score margin graph and play-by-play.
  • Adds team-level records once per run: the full season roster and the league standings table.
  • Leaves out any field you did not request or the source does not have, so rows never carry empty or placeholder columns.

πŸ“Š What data can you extract from Sofascore basketball?

Record typeFields
match-recordmatchId, slug, tournament, round (when Sofascore provides it), homeTeam, awayTeam, homeTeamId, awayTeamId, homeScore, awayScore, scoreByQuarter, status, statusType, startTime, imageUrl, scrapedAt
statistics (nested in the game row)period, group, stat, home, away
boxScore (nested)playerName, minutesPlayed, points, rebounds, assists, steals, blocks, turnovers, field goals, three pointers, free throws, plusMinus, rating
lineups (nested)side, playerName, position, jerseyNumber, starter
h2hRecord, odds, scoreGraph, playByPlay (nested)head-to-head wins, bookmaker odds, minute/margin points, scoring plays with running score
roster-recordteamName, playerName, position, jerseyNumber, heightCm, weightKg, dateOfBirth, country
standings-recordtournamentName, teamName, position, matches, wins, losses, scoresFor, scoresAgainst, percentage, gamesBehind

🧾 Basketball Scraper sample output

Abridged real record from a verified run (one game, with Team statistics and the other extras switched on; long arrays shortened to their first item):

{
"recordType": "match-record",
"matchId": 14441947,
"tournament": "NBA",
"homeTeam": "Orlando Magic",
"awayTeam": "Los Angeles Lakers",
"homeScore": 104,
"awayScore": 105,
"scoreByQuarter": [{ "quarter": 1, "homePoints": 30, "awayPoints": 37 }],
"status": "Ended",
"statusType": "finished",
"startTime": "2026-03-21T23:00:00.000Z",
"statistics": [{ "period": "ALL", "group": "Scoring", "stat": "Free throws", "home": "21/23 (91%)", "away": "19/29 (65%)" }],
"boxScore": [{ "side": "home", "playerName": "Paolo Banchero", "minutesPlayed": 36, "points": 16, "rebounds": 5, "assists": 6, "plusMinus": -18, "rating": 7.1 }],
"h2hRecord": { "homeWins": 4, "awayWins": 6 },
"odds": [{ "outcome": "1", "odds": "7/5" }],
"scoreGraph": [{ "minute": 1, "margin": -6 }],
"playByPlay": [{ "time": 48, "playerName": "Luke Kennard", "side": "away", "points": 3, "homeScore": 104, "awayScore": 105 }]
}

Roster and standings rows (delivered after the match rows when "Team roster" and "Conference/division standings" are on and maxItems leaves room):

{ "recordType": "roster-record", "teamName": "Orlando Magic", "playerName": "Desmond Bane", "position": "G", "heightCm": 196, "weightKg": 98, "country": "USA" }
{ "recordType": "standings-record", "tournamentName": "NBA", "teamName": "Detroit Pistons", "position": 1, "wins": 60, "losses": 22, "percentage": 0.732 }

πŸ’° How much does it cost to scrape basketball data?

Pay per event. You are charged only for records that were saved. Error rows, "not found" games, empty searches and failed runs are never charged. Prices at the Free plan tier (higher Apify plans pay slightly less for match-record):

EventPriceWhat one event is
match-record$0.015One game
match-statistics-record$0.01One team stat line (full game or one quarter)
box-score-player-record$0.01One player box score line
lineup-record$0.01One player lineup entry
h2h-record$0.01One head-to-head tally
odds-record$0.01One odds outcome
score-graph-record$0.01One margin graph point
play-by-play-record$0.01One scoring play
roster-record$0.01One roster player, once per team per run
standings-record$0.01One standings row, once per league per run

Team statistics are off by default because they are billed per statistic line, not per game: one finished NBA game returned 71 stat lines in our reference run, about $0.71 extra per game on top of the $0.015 base (verified again in a 2026-10-04 cloud run: 71 lines, 71 charged events). With the default settings a run costs $0.015 per game, or $0.15 for 10 games. Turn Team statistics on only when you need those lines. Set a maximum charge per run in the run options and the Actor stops cleanly when it is reached.

πŸš€ How to scrape basketball data in 3 steps

  1. Open the Actor and type a team name (for example "Los Angeles Lakers") or paste Sofascore match IDs.
  2. Switch on only the extras you need and keep Max Items low for a first run (default 10).
  3. Click Start, then download CSV, Excel, JSON or XML from the Output tab, or read the dataset through the API.

βš™οΈ Basketball Scraper input

FieldTypeDefaultMeaning
teamNameslistLos Angeles Lakers if both lists are emptyTeam names to resolve and scrape
eventIdslistemptySofascore match IDs to fetch directly
liveOnlybooleanfalseFetch all live basketball games and ignore the lists
maxItemsinteger10Cap on output rows (games, roster players, standings rows)
includeStatisticsbooleanfalseTeam stats per quarter, billed per statistic line (about 71 lines per NBA game). Off unless you turn it on
includeBoxScore, includeLineups, includeH2h, includeOdds, includeScoreGraph, includePlayByPlaybooleanfalsePer-game extras
includeRoster, includeStandingsbooleanfalseTeam and league records, once per run
{ "teamNames": ["Los Angeles Lakers"], "maxItems": 10, "includeStatistics": false, "includeBoxScore": true }

πŸ“¦ Basketball Scraper output and empty results

Rows are written to the default dataset, one per game, roster player or standings row, identified by recordType. The Overview view shows teams, tournament, score, date and record type. A genuinely empty search (unknown team, nothing live) ends as succeeded with a status message and no charge. If Sofascore blocks or errors on every request, the run ends as failed with a clear message and no charge.

βš–οΈ Basketball Scraper vs alternatives

Prices read from the public Apify Store API:

ActorModelNotes
This Actor$0.015 per game plus $0.01 per extra record10 record types from Sofascore, includes score margin graph, one run
sian.agency basketball-api-scraper$0.015 per result, $0.03 for profile and detail results, plus $0.05 start fee14 events, different data source
hgservices ESPN scraper$0.001 per itemGeneric multi-sport, flat score list
extractify-labs Flashscore basketball$0.001 per itemLive match list only

The flat $0.001 scrapers are cheaper per row, but they return one summary row per game. Per-player box scores, play-by-play and quarter statistics are what the extra events pay for.

πŸ’Ό Use cases

  • Fantasy and DFS: feed box scores and rosters into projection models.
  • Betting models: backtest against bookmaker odds, margin curves and quarter splits. Odds are informational, not advice.
  • Sports media: generate recaps, tables and widgets from results and standings.
  • Scouting and analytics: study player minutes, plus-minus and scoring runs.

πŸ”Œ Basketball Scraper API, schedule and integrations

curl -X POST "https://api.apify.com/v2/acts/RecordsData~basketball-match-stats-scraper/runs?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"teamNames":["Los Angeles Lakers"],"maxItems":10,"includeStatistics":false}'

Schedule runs after game nights, and connect the dataset to Zapier, Make, n8n, Google Sheets or Airbyte. The Actor works with the Apify MCP server, so AI agents can call it with the same input.

The Actor reads publicly available game data and does not log in, bypass accounts or collect private data. You are responsible for using the data in line with Sofascore's terms and local law. Player names and statistics are public sports records. This is an independent tool, not affiliated with Sofascore, the NBA or any league or team.

❓ Frequently asked questions

Which leagues does Basketball Scraper cover? Any basketball league Sofascore covers, including the NBA and EuroLeague. Depth of statistics and box scores depends on what Sofascore publishes for that league.

Why did I get 0 results? Either the team name did not resolve (use the full name, "Los Angeles Lakers" not "Lakers") or the team has no recent or upcoming games. The run succeeds with a status message and costs nothing.

Why did my run fail? Sofascore actively challenges automated requests (in October 2026 its old api.sofascore.com host started returning HTTP 403 challenge responses, so the Actor now uses a different request path with a Firefox-like fingerprint). The Actor retries on fresh residential IPs, and if every request is blocked it fails with a message and charges nothing. Try again later.

Why is my run expensive? Almost always because an extra that is billed per line is on. Team statistics are off by default (about 71 lines per NBA game at $0.01 each), and player box scores, play-by-play and score graph also add one charge per record. Check the extras you switched on, lower Max Items, or set a maximum charge per run.

Am I charged for failed games or error rows? No. Error rows have no charge event, and records are charged only after they are saved.

How are roster and standings billed? Once per unique team and once per unique league season in the run, not once per game.

Can I use match IDs instead of a team name? Yes. Put Sofascore match IDs in eventIds. The ID is the number after id: in a Sofascore match URL.

What does the score margin graph contain? One point per minute of game time with the home-minus-away margin, so positive means the home team led.

Why is play-by-play period sometimes missing? Sofascore does not label every scoring play with its quarter. Where it is absent, the Actor omits the field instead of guessing.

How can I cap my spend? Lower Max Items, keep Team statistics and other extras off unless you need them (they are billed per record), and set a maximum charge per run. The Actor stops when the limit is reached.

πŸ”— Want more sports data? Other PunkRecordsData scrapers

πŸ†˜ Support

Open an issue from the Actor's Issues tab or write to contact.punkrecordsdata@gmail.com.

Last updated: 2026-10-04