The Unofficial Python Wrapper for the MLB Stats API
This package and its authors are not affiliated with MLB or any MLB team. This API wrapper interfaces with MLB's Stats API. Use of MLB data is subject to the notice posted at http://gdx.mlb.com/components/copyright.txt.
Python-mlb-statsapi is a Python library that provides access to the MLB Stats API, allowing developers to retrieve information related to MLB teams, players, stats, and more. Written in Python 3.10+.
All models are built with Pydantic for robust data validation and serialization. Field names follow Python's snake_case convention for a more Pythonic experience.
For detailed documentation, check out the Wiki which contains information on return objects, endpoint structure, usage examples, and more.
python3 -m pip install python-mlb-statsapi>>> import mlbstatsapi
>>> mlb = mlbstatsapi.Mlb()
>>> mlb.get_people_id("Ty France")
[664034]
>>> player = mlb.get_person(664034)
>>> print(player.full_name)
Ty France
>>> stats = ['season', 'seasonAdvanced']
>>> groups = ['hitting']
>>> params = {'season': 2022}
>>> mlb.get_player_stats(664034, stats, groups, **params)
{'hitting': {'season': Stat, 'seasonadvanced': Stat }}
>>> mlb.get_team_id("Seattle Mariners")
[136]
>>> team = mlb.get_team(136)
>>> print(team.name, team.franchise_name)
Seattle Mariners SeattleAll returned objects are Pydantic models, giving you access to powerful serialization and validation features.
>>> player = mlb.get_person(664034)
>>> player.model_dump()
{'id': 664034, 'full_name': 'Ty France', 'link': '/api/v1/people/664034', ...}
# Exclude None values
>>> player.model_dump(exclude_none=True)
{'id': 664034, 'full_name': 'Ty France', 'link': '/api/v1/people/664034', ...}
# Include only specific fields
>>> player.model_dump(include={'id', 'full_name', 'primary_position'})
{'id': 664034, 'full_name': 'Ty France', 'primary_position': Position(...)}>>> player = mlb.get_person(664034)
>>> player.model_dump_json()
'{"id": 664034, "full_name": "Ty France", "link": "/api/v1/people/664034", ...}'
# Pretty print with indentation
>>> print(player.model_dump_json(indent=2))
{
"id": 664034,
"full_name": "Ty France",
"link": "/api/v1/people/664034",
...
}>>> player = mlb.get_person(664034)
>>> player.full_name # Not fullName
'Ty France'
>>> player.primary_position # Not primaryPosition
Position(code='3', name='First Base', ...)
>>> player.bat_side # Not batSide
CodeDesc(code='R', description='Right')Mlb.get_people_id(self, fullname: str, sport_id: int = 1, search_key: str = 'fullname', **params)- Return Person Id(s) from fullnameMlb.get_person(self, player_id: int, **params)- Return Person Object from IdMlb.get_people(self, sport_id: int = 1, **params)- Return all Players from Sport
Mlb.get_draft(self, year_id: int, **params)- Return a draft for a given year
Mlb.get_awards(self, award_id: int, **params)- Return award recipients for a given award
Mlb.get_team_id(self, team_name: str, search_key: str = 'name', **params)- Return Team Id(s) from nameMlb.get_team(self, team_id: int, **params)- Return Team Object from Team IdMlb.get_teams(self, sport_id: int = 1, **params)- Return all Teams for SportMlb.get_team_coaches(self, team_id: int, **params)- Return coaching roster for team for current or specified seasonMlb.get_team_roster(self, team_id: int, **params)- Return player roster for team for current or specified season
Mlb.get_player_stats(self, person_id: int, stats: list, groups: list, **params)- Return stats by player id, stat type and groupsMlb.get_team_stats(self, team_id: int, stats: list, groups: list, **params)- Return stats by team id, stat types and groupsMlb.get_stats(self, stats: list, groups: list, **params: dict)- Return stats by stat type and group argsMlb.get_players_stats_for_game(self, person_id: int, game_id: int, **params)- Return player stats for a game
Mlb.get_gamepace(self, season: str, sport_id=1, **params)- Return pace of game metrics for specific sport, league or team.
Mlb.get_venue_id(self, venue_name: str, search_key: str = 'name', **params)- Return Venue Id(s)Mlb.get_venue(self, venue_id: int, **params)- Return Venue Object from venue IdMlb.get_venues(self, **params)- Return all Venues
Mlb.get_sport(self, sport_id: int, **params)- Return a Sport object from IdMlb.get_sports(self, **params)- Return all SportsMlb.get_sport_id(self, sport_name: str, search_key: str = 'name', **params)- Return Sport Id from name
Mlb.get_schedule(self, date: str, start_date: str, end_date: str, sport_id: int, team_id: int, **params)- Return a Schedule
Mlb.get_division(self, division_id: int, **params)- Return a DivisionMlb.get_divisions(self, **params)- Return all DivisionsMlb.get_division_id(self, division_name: str, search_key: str = 'name', **params)- Return Division Id(s) from name
Mlb.get_league(self, league_id: int, **params)- Return a League from IdMlb.get_leagues(self, **params)- Return all LeaguesMlb.get_league_id(self, league_name: str, search_key: str = 'name', **params)- Return League Id(s)
Mlb.get_season(self, season_id: str, sport_id: int = None, **params)- Return a seasonMlb.get_seasons(self, sportid: int = None, **params)- Return all seasons
Mlb.get_standings(self, league_id: int, season: str, **params)- Return standings
Mlb.get_schedule(self, date: str = None, start_date: str = None, end_date: str = None, sport_id: int = 1, team_id: int = None, **params)- Return a Schedule from datesMlb.get_scheduled_games_by_date(self, date: str = None,start_date: str = None, end_date: str = None, sport_id: int = 1, **params)- Return game ids from dates
Mlb.get_game(self, game_id: int, **params)- Return the Game for a specific Game IdMlb.get_game_play_by_play(self, game_id: int, **params)- Return Play by play data for a gameMlb.get_game_line_score(self, game_id: int, **params)- Return a Linescore for a gameMlb.get_game_box_score(self, game_id: int, **params)- Return a Boxscore for a game
Contributions are welcome! Whether it's bug fixes, new features, or documentation improvements, we appreciate your help.
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/python-mlb-statsapi.git - Install dependencies:
poetry install - Create a branch:
git checkout -b feat/your-feature
# Run tests
poetry run pytest
# Run mock tests only (no external API calls)
poetry run pytest tests/mock_tests/
# Run external tests (requires internet)
poetry run pytest tests/external_tests/- All tests must pass before submitting a PR
- Use the PR template when creating your pull request
- Follow the branch naming convention:
feat/- New featuresfix/- Bug fixesdocs/- Documentation updatesrefactor/- Code improvements
Found a bug or have a feature request? Please open an issue with:
- A clear description of the problem or feature
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Python version and package version
Some tests make real API calls to the MLB Stats API. These may occasionally fail due to:
- API changes (new fields, removed endpoints)
- Season/data availability
If you notice external test failures, please check if the MLB API has changed and update the models accordingly.
Let's show some examples of getting stat objects from the API. What is baseball without stats, right?
Get the Id(s) of the players you want stats for and set stat types and groups.
>>> mlb = mlbstatsapi.Mlb()
>>> player_id = mlb.get_people_id("Ty France")[0]
>>> stats = ['season', 'career']
>>> groups = ['hitting', 'pitching']
>>> params = {'season': 2022}Use player id with stat types and groups to return a stats dictionary
>>> stat_dict = mlb.get_player_stats(player_id, stats=stats, groups=groups, **params)
>>> season_hitting_stat = stat_dict['hitting']['season']
>>> career_pitching_stat = stat_dict['pitching']['career']Print season hitting stats using Pydantic's model_dump()
>>> for split in season_hitting_stat.splits:
... print(split.stat.model_dump(exclude_none=True))
{'games_played': 140, 'groundouts': 163, 'airouts': 148, 'runs': 65, 'doubles': 27, ...}Or access individual fields directly
>>> for split in season_hitting_stat.splits:
... print(f"Games: {split.stat.games_played}")
... print(f"Home Runs: {split.stat.home_runs}")
... print(f"Batting Avg: {split.stat.avg}")
Games: 140
Home Runs: 20
Batting Avg: .274Get the Team Id(s)
>>> mlb = mlbstatsapi.Mlb()
>>> team_id = mlb.get_team_id('Seattle Mariners')[0]Set the stat types and groups
>>> stats = ['season', 'seasonAdvanced']
>>> groups = ['hitting']
>>> params = {'season': 2022}Use team id and the stat types and groups to return season hitting stats
>>> stats = mlb.get_team_stats(team_id, stats=stats, groups=groups, **params)
>>> season_hitting = stats['hitting']['season']
>>> advanced_hitting = stats['hitting']['seasonadvanced']Print stats as JSON
>>> for split in season_hitting.splits:
... print(split.stat.model_dump_json(indent=2, exclude_none=True))
{
"games_played": 162,
"groundouts": 1273,
"runs": 690,
"doubles": 229,
...
}>>> player_id = mlb.get_people_id('Ty France')[0]
>>> stats = ['expectedStatistics']
>>> group = ['hitting']
>>> params = {'season': 2022}
>>> stats = mlb.get_player_stats(player_id, stats=stats, groups=group, **params)
>>> expected = stats['hitting']['expectedstatistics']
>>> for split in expected.splits:
... print(f"Expected AVG: {split.stat.avg}")
... print(f"Expected SLG: {split.stat.slg}")
Expected AVG: .259
Expected SLG: .394Get pitcher and batter player Ids
>>> ty_france_id = mlb.get_people_id('Ty France')[0]
>>> shohei_ohtani_id = mlb.get_people_id('Shohei Ohtani')[0]Set stat type, stat groups, and params
>>> stats = ['vsPlayer']
>>> group = ['hitting']
>>> params = {'opposingPlayerId': shohei_ohtani_id, 'season': 2022}Get stats
>>> stats = mlb.get_player_stats(ty_france_id, stats=stats, groups=group, **params)
>>> vs_player = stats['hitting']['vsplayer']
>>> for split in vs_player.splits:
... print(f"Games: {split.stat.games_played}, Hits: {split.stat.hits}")
Games: 2, Hits: 2>>> ty_france_id = mlb.get_people_id('Ty France')[0]
>>> stats = ['hotColdZones']
>>> hitting_group = ['hitting']
>>> params = {'season': 2022}
>>> hotcoldzones = mlb.get_player_stats(ty_france_id, stats=stats, groups=hitting_group, **params)
>>> zones = hotcoldzones['stats']['hotcoldzones']
>>> for split in zones.splits:
... print(f"Stat: {split.stat.name}")
... for zone in split.stat.zones:
... print(f" Zone {zone.zone}: {zone.value}")
Stat: battingAverage
Zone 01: .226
Zone 02: .400
...Get a schedule for a given date
>>> mlb = mlbstatsapi.Mlb()
>>> schedule = mlb.get_schedule(date='2022-10-13')
>>> dates = schedule.dates
>>> for date in dates:
... for game in date.games:
... print(f"Game: {game.game_pk}")
... print(f"Status: {game.status.detailed_state}")
... print(f"Home: {game.teams.home.team.name}")
... print(f"Away: {game.teams.away.team.name}")Get a Game for a given game id
>>> mlb = mlbstatsapi.Mlb()
>>> game = mlb.get_game(662242)Get the weather for a game
>>> weather = game.game_data.weather
>>> print(f"Condition: {weather.condition}")
>>> print(f"Temperature: {weather.temp}")
>>> print(f"Wind: {weather.wind}")Get the current status of a game
>>> linescore = game.live_data.linescore
>>> home_info = game.game_data.teams.home
>>> away_info = game.game_data.teams.away
>>> home_status = linescore.teams.home
>>> away_status = linescore.teams.away
>>> print(f"Home: {home_info.franchise_name} {home_info.club_name}")
>>> print(f" Runs: {home_status.runs}, Hits: {home_status.hits}, Errors: {home_status.errors}")
>>> print(f"Away: {away_info.franchise_name} {away_info.club_name}")
>>> print(f" Runs: {away_status.runs}, Hits: {away_status.hits}, Errors: {away_status.errors}")
>>> print(f"Inning: {linescore.inning_half} {linescore.current_inning_ordinal}")Get play by play, line score, and box score objects
>>> play_by_play = game.live_data.plays
>>> line_score = game.live_data.linescore
>>> box_score = game.live_data.boxscoreGet only the play by play for a given game id
>>> playbyplay = mlb.get_game_play_by_play(662242)Get only the line score for a given game id
>>> linescore = mlb.get_game_line_score(662242)Get only the box score for a given game id
>>> boxscore = mlb.get_game_box_score(662242)Get pace of game metrics for a specific season
>>> mlb = mlbstatsapi.Mlb()
>>> gamepace = mlb.get_gamepace(season=2021)
>>> print(f"Hits per game: {gamepace.sports[0].sport_game_pace.hits_per_game}")Get all Players for a given sport id
>>> mlb = mlbstatsapi.Mlb()
>>> players = mlb.get_people(sport_id=1)
>>> for player in players:
... print(f"{player.id}: {player.full_name}")Get a player id
>>> player_id = mlb.get_people_id("Ty France")
>>> print(player_id[0])
664034Get a Team
>>> mlb = mlbstatsapi.Mlb()
>>> team_id = mlb.get_team_id("Seattle Mariners")[0]
>>> team = mlb.get_team(team_id)
>>> print(f"{team.id}: {team.name}")
>>> print(f"Venue: {team.venue.name}")Get a Player Roster
>>> mlb = mlbstatsapi.Mlb()
>>> players = mlb.get_team_roster(136)
>>> for player in players:
... print(f"#{player.jersey_number} {player.person.full_name}")Get a Coach Roster
>>> mlb = mlbstatsapi.Mlb()
>>> coaches = mlb.get_team_coaches(136)
>>> for coach in coaches:
... print(f"{coach.person.full_name}: {coach.title}")Get a draft for a year
>>> mlb = mlbstatsapi.Mlb()
>>> draft = mlb.get_draft('2019')Get Players from Draft
>>> draftpicks = draft[0].picks
>>> for pick in draftpicks:
... print(f"Round {pick.pick_round}, Pick {pick.pick_number}: {pick.person.full_name}")Get awards for a given award id
>>> mlb = mlbstatsapi.Mlb()
>>> retired_numbers = mlb.get_awards(award_id='RETIREDUNI_108')
>>> for recipient in retired_numbers.awards:
... print(f"{recipient.player.full_name}: {recipient.name} ({recipient.date})")Get a Venue
>>> mlb = mlbstatsapi.Mlb()
>>> venue_id = mlb.get_venue_id('PNC Park')[0]
>>> venue = mlb.get_venue(venue_id)
>>> print(f"{venue.name} - {venue.location.city}, {venue.location.state}")Get a division
>>> mlb = mlbstatsapi.Mlb()
>>> division = mlb.get_division(200)
>>> print(division.name)
American League WestGet a league
>>> mlb = mlbstatsapi.Mlb()
>>> league = mlb.get_league(103)
>>> print(league.name)
American LeagueGet a Season
>>> mlb = mlbstatsapi.Mlb()
>>> season = mlb.get_season(2018)
>>> print(f"Season: {season.season_id}")
>>> print(f"Regular Season: {season.regular_season_start_date} to {season.regular_season_end_date}")Get Standings
>>> mlb = mlbstatsapi.Mlb()
>>> standings = mlb.get_standings(103, 2018)
>>> for record in standings:
... print(f"Division: {record.division.name}")
... for team in record.team_records:
... print(f" {team.team.name}: {team.wins}-{team.losses}")