MLB Stats Scraper | Game Logs, Statcast Pitches, Lineups avatar

MLB Stats Scraper | Game Logs, Statcast Pitches, Lineups

Pricing

from $2.79 / 1,000 games

Go to Apify Store
MLB Stats Scraper | Game Logs, Statcast Pitches, Lineups

MLB Stats Scraper | Game Logs, Statcast Pitches, Lineups

Scrape MLB stats in bulk: every player's game log, daily slates with probable pitchers, lineups, weather and umpires, pitch-by-pitch Statcast with all columns, season stats with WAR, wRC+ and splits, rosters with injured list, standings. MLB and minor leagues, back to 1901.

Pricing

from $2.79 / 1,000 games

Rating

0.0

(0)

Developer

Zen Studio

Zen Studio

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

4 days ago

Last modified

Share

Every player's game line, in bulk. 58,380 player game lines in one run.

From Zen Studio, creators of PrizePicks Player Props and DraftKings Odds, with 35,000+ combined runs. Established sports-data tools for odds, player props and research.

Why choose this actor?

58,380 player game lines in one run. Collect batting and pitching game logs across a date range or season. Get player names, teams, opponents and game-level stats as structured rows, ready for analysis and model training.

46 data types, including the detail behind the box score. Choose pitch-by-pitch tracking with velocity, spin and bat speed; season stats with WAR and wRC+; player splits; or daily games with probable pitchers, lineups, weather and umpires. Odds and player props are available too.

Follow players across games and seasons. Filter by player name, team or league level. Consistent player and game identifiers connect the actor’s game logs, pitches and season records. Supported modes also cover minor-league baseball.

Get player game logs

Quick start

Try 50 player game lines from a completed day. Remove maxResults for the full selection, set a date range, or use seasons instead of dates for a season-wide export.

{
"mode": "playerGames",
"startDate": "2026-09-14",
"maxResults": 50
}

Open actor input to select the data type, dates and teams. Export JSON, CSV or Excel.

Available detail varies by season, league and record type. Statcast measurements are added after games, not live. Odds, props and Statcast leaderboards are MLB-only.

Zen Studio · Sports Data
 MLB Stats
You are here
 PrizePicks
Player prop lines
 DraftKings
Odds & props
 Sleeper
Picks & multipliers
 Bet365
Live & pre-match

Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

zen-studio/mlb-stats-scraper on Apify. MLB and minor-league baseball data, 46 record types, one per run.
Call: ApifyClient("TOKEN").actor("zen-studio/mlb-stats-scraper").call(run_input={...}), then
client.dataset(run["defaultDatasetId"]).list_items().items for rows.
mode (string, required in practice, prefilled "games") picks the record type. Date-addressed modes use
startDate/endDate (YYYY-MM-DD; empty = today): games, playerGames, teamGames, inningLines, plateAppearances,
pitchEvents, runnerMovements, gameOdds, playerProps, lineMovement, transactions, highlights. Every other mode
uses seasons (string[] of years, empty = current season): playerSeasons, playerSplits, fieldingSeasons,
rosters, standings, teams, venues, teamHistory, seasonCalendar, leaders, gameHighLows, staff, homeRunDerby,
players, draft, draftProspects, prospectRankings, freeAgents, awards, milestones, injuries, futures,
playoffOdds, teamBettingRecords, statcastBatting, statcastPitching, statcastFielding, statcastCatching,
statcastRunning, statcastTeams, pitchTypes, rollingForm, parkFactors, absChallenges.
Common inputs: level (string, "mlb" default; also aaa, aa, high_a, single_a, rookie, winter, other_minors,
college, independent, international, negro_leagues), teams (string[], names/abbreviations/ids), players
(string[], names or ids), gameTypes (string[], R regular, F wildcard, D division, L league, W world series,
S spring, E exhibition, A all-star), maxResults (integer).
Dependencies that decide what you get:
- Dates outrank seasons on date-addressed modes. Set one or the other, not both.
- players only applies to player-level modes: playerGames, playerSeasons, playerSplits, fieldingSeasons,
rosters, pitchEvents, plateAppearances, runnerMovements, players, transactions, draft, draftProspects,
prospectRankings, freeAgents, awards, milestones, leaders, gameHighLows, staff, highlights, homeRunDerby,
injuries, playerProps, futures and the Statcast player boards. On games, teamGames, standings, venues or
odds-by-game it is refused with a message naming the modes that do accept it, not silently ignored.
- Statcast leaderboards, all odds/props modes and injuries are Major League Baseball only. Another level is
refused, not returned empty.
- pitchEvents has includeStatcast (boolean, prefilled true) to attach Statcast columns to each pitch, and
pitchEventTypes to restrict to pitches, pickoffs, step-offs, automatic calls or in-game actions.
- playerSeasons/playerSplits take statGroups (hitting, pitching) and splitCodes (600+ situation codes).
Fielding season lines are their own mode, fieldingSeasons.
- transactions treats a season as the calendar year, because moves happen all winter.
- Statcast is not published while a game is in progress: live pitches arrive with has_statcast false and null
measurement columns, filling in after the game is final.
Every row carries record_type, the MLB player_id and/or team_id, and game_pk where a game applies, so rows
join to each other and to zen-studio's odds and props actors.
Row types bill at different rates per 1,000 rows; the current figures are on the actor's pricing panel.
Set maxTotalChargeUsd on a run to cap spend: the run stops cleanly at the cap rather than over-delivering.
Full input schema: https://apify.com/zen-studio/mlb-stats-scraper/input-schema

What you can collect

Pick one record type per run with the What to collect setting. All forty-six are below, grouped by what they describe.

Games and players

Record typeOne row isAddressed by
gamesA game, with probable pitchers, lineups, weather, umpire crew, venue geometry, series context and attendanceDates
playerGamesA player's batting or pitching line for one game, with batting order and positionDates
teamGamesA team's totals for one gameDates
playerSeasonsA player's season line, with sabermetrics, expected stats and WARSeasons
playerSplitsA player's season split: versus left, versus right, home, away and 600 more situationsSeasons
fieldingSeasonsA player's fielding season, per positionSeasons
rostersA player on a team roster, with injured-list statusSeasons
standingsA team's standing, with games back, wild card, streak and run differentialSeasons
teams, venues, teamHistory, seasonCalendarReference dataSeasons

Pitch and play level

Record typeOne row isAddressed by
pitchEventsA pitch, pickoff, step-off, automatic call or in-game action, with tracking and Statcast measurementsDates
plateAppearancesA plate appearance, with result, count, score and runnersDates
runnerMovementsOne runner moving on one playDates
inningLinesA team's line for one inningDates

Statcast leaderboards

statcastBatting, statcastPitching, statcastFielding, statcastCatching, statcastRunning, statcastTeams, pitchTypes, rollingForm and parkFactors. Expected stats, barrels, sprint speed, arm strength, framing, pitch arsenals and park factors.

absChallenges sits alongside them: automatic ball-strike challenges, for Major League Baseball and Triple-A.

Odds and props

gameOdds, playerProps, lineMovement, futures, playoffOdds, teamBettingRecords and injuries, each joined back to the MLB game, team and player ids so they line up with the stat records.

People and league

players, transactions, draft, draftProspects, prospectRankings, freeAgents, awards, milestones, leaders, gameHighLows, staff, homeRunDerby and highlights.

How to scrape MLB stats

The opening shows the smallest useful run. From there, a date range for one team:

{
"mode": "playerGames",
"startDate": "2026-08-01",
"endDate": "2026-08-31",
"teams": ["NYY"]
}

A whole season of pitch-by-pitch Statcast:

{
"mode": "pitchEvents",
"seasons": ["2026"]
}

Triple-A instead of the majors:

{
"mode": "games",
"startDate": "2026-08-12",
"level": "aaa"
}

Main settings

SettingTypeMeaning
modestringWhich record type to collect. One per run
startDate, endDatedateFor date-addressed types. Leave both empty for today
seasonsarrayYears, for season-addressed types. Takes second place to dates
levelstringMLB, Triple-A down to Rookie, winter, college, independent, international or the Negro Leagues
teamsarrayTeam names, abbreviations or ids
playersarrayPlayer names or ids. Only for player-level record types
gameTypesarrayRegular season, postseason rounds, spring training, All-Star
maxResultsintegerStop after this many rows

Record types have their own extra settings, such as the stat groups on season lines, the situations on splits, the roster type, the event types on pitch events, and the sportsbooks and prop markets on odds. They appear in the Input tab under the record type that uses them.

What data you get

One playerGames row, captured from a real run. The season_* block is omitted below for length: it repeats the same batting_*, pitching_* and fielding_* keys with the player's season-to-date totals, 111 further fields, so this batting row is 194 fields in all. A pitching row swaps the batting_* block for 54 pitching_* keys and runs to about 215.

{
"record_type": "player_game",
"game_pk": 823244,
"official_date": "2026-03-25",
"game_date": "2026-03-26T00:05:00Z",
"season": 2026,
"game_type": "R",
"double_header": "N",
"game_number": 1,
"day_night": "night",
"venue_id": 2395,
"venue_name": "Oracle Park",
"status_detailed_state": "Final",
"team_id": 147,
"team_name": "New York Yankees",
"team_abbreviation": "NYY",
"opponent_id": 137,
"opponent_name": "San Francisco Giants",
"opponent_abbreviation": "SF",
"is_home": false,
"player_id": 676609,
"player_name": "José Caballero",
"boxscore_name": "Caballero",
"jersey_number": "72",
"position_code": "6",
"position_name": "Shortstop",
"position_type": "Infielder",
"position_abbreviation": "SS",
"all_positions": [
"SS"
],
"roster_status_code": "A",
"roster_status_description": "Active",
"parent_team_id": 147,
"game_status_is_current_batter": false,
"game_status_is_current_pitcher": false,
"game_status_is_on_bench": false,
"game_status_is_substitute": false,
"batting_order_code": "700",
"batting_order_slot": 7,
"is_starting_batter": true,
"pitching_order": null,
"is_starting_pitcher": false,
"batting_summary": "1-4 | RBI, R",
"batting_games_played": 1,
"batting_fly_outs": 0,
"batting_ground_outs": 2,
"batting_air_outs": 1,
"batting_runs": 1,
"batting_doubles": 0,
"batting_triples": 0,
"batting_home_runs": 0,
"batting_strike_outs": 0,
"batting_base_on_balls": 0,
"batting_intentional_walks": 0,
"batting_hits": 1,
"batting_hit_by_pitch": 0,
"batting_at_bats": 4,
"batting_caught_stealing": 0,
"batting_stolen_bases": 0,
"batting_stolen_base_percentage": null,
"batting_ground_into_double_play": 1,
"batting_ground_into_triple_play": 0,
"batting_plate_appearances": 4,
"batting_total_bases": 1,
"batting_rbi": 1,
"batting_left_on_base": 3,
"batting_sac_bunts": 0,
"batting_sac_flies": 0,
"batting_catchers_interference": 0,
"batting_pickoffs": 0,
"batting_at_bats_per_home_run": null,
"batting_pop_outs": 1,
"batting_line_outs": 0,
"fielding_games_started": 1,
"fielding_caught_stealing": 0,
"fielding_stolen_bases": 0,
"fielding_stolen_base_percentage": null,
"fielding_caught_stealing_percentage": null,
"fielding_assists": 4,
"fielding_put_outs": 0,
"fielding_errors": 1,
"fielding_chances": 5,
"fielding_fielding": 0,
"fielding_passed_ball": 0,
"fielding_pickoffs": 0
}

Pitching lines carry pitching_* keys in the same shape, 54 of them, including innings, earned runs, strikeouts, pitch counts, strikes and inherited runners. A row always carries both the game context and the player context, so the file is usable without joining anything else. Use JSON or JSONL to keep nested fields such as all_positions; CSV flattens them.

Coverage and limits

  • History runs deep but unevenly. Plays exist from 1950, full pitch sequences from 1988, pitch tracking from 2008, exit velocity and launch angle from 2015, induced break and extension from 2017, arm angle from 2023, bat speed from 2024. Earlier rows carry the columns as nulls rather than dropping them.
  • Minor leagues are a first-class level, from Triple-A to Rookie, plus winter, college, independent and international leagues, and the Negro Leagues for games, team totals, inning lines, season stats, standings, teams and rosters.
  • Statcast leaderboards, every odds and props record type, and injuries are Major League Baseball only. Ask for another level and the actor says so rather than finishing with an empty run. absChallenges is the exception inside that group: it covers Major League Baseball and Triple-A.
  • Live games work for the slate, plays and pitch events. Statcast is not published while a game is in progress, so pitches from a live game arrive with has_statcast false and their measurement columns null. They fill in once the game is final.
  • Out of season a date range is empty, not an error. The run finishes normally and says why.

FAQ

Which record type should I pick? For prop and fantasy models, playerGames. For the day's card, games. For pitch physics, pitchEvents. For season-level modelling, playerSeasons and playerSplits.

How far back can I go? It depends on the record type; see Coverage above. Season-level records reach much further back than pitch tracking does.

Can I get data for a game happening right now? Yes for the slate, plate appearances and pitch events. Statcast measurements are not published for a game in progress, so those columns are null until the game finishes.

How do I join this to odds or props? Every row carries the MLB player id and game id. The odds record types carry them too, and so do the sibling actors above.

Can I filter by player? On player-level record types, yes. A game row, team line, standing or venue has no player to match, so the actor tells you instead of returning nothing.

What happens if I ask for a date with no games? The run finishes successfully with zero rows and explains why.

Is there a free tier? Yes. The Store pricing panel on this page has the current rates for each row type.

Something looks wrong. Open an issue on the Issues tab with the input you used and what you expected.

Support

Questions, bugs and requests for extra fields go in the Issues tab. We read every one.