A Ruby interface to the MLB Stats API
Follow
For updates and announcements, follow @sferik.
Installation
Install the gem and add to the application's Gemfile:
bundle add mlb
Or, if Bundler is not being used to manage dependencies:
gem install mlb
Usage
require "mlb"
Teams
# Get all MLB teams for a season
teams = MLB::Teams.all(season: 2025)
teams.size # => 30
mets = teams.find { |t| t.id == MLB::Team::NYM }
mets.name # => "New York Mets"
mets.short_name # => "NY Mets"
mets.league.name # => "National League"
mets.division.name # => "National League East"
mets.first_year_of_play # => 1962
mets.venue.name # => "Citi Field"
Roster
# Get a team's roster
roster = MLB::Roster.find(team: MLB::Team::NYM, season: 2025)
roster.size # => 39
# Find a specific player on the roster
entry = roster.find { |e| e.player.full_name == "Francisco Lindor" }
entry.player.full_name # => "Francisco Lindor"
entry.jersey_number # => 12
entry.position.name # => "Shortstop"
entry.status.description # => "Active"
Players
# Find a player by ID
senga = MLB::Players.find(807882)
senga.full_name # => "Kodai Senga"
senga.primary_number # => 34
senga.primary_position.name # => "Pitcher"
senga.pitch_hand.description # => "Right"
senga.bat_side.description # => "Right"
senga.current_age # => 32
senga.birth_date.to_s # => "1993-01-30"
senga.birth_city # => "Nagaoka"
senga.birth_state_province # => "Niigata"
senga.birth_country # => "Japan"
senga.mlb_debut_date.to_s # => "2023-04-01"
senga.height # => "6' 1\""
senga.weight # => 200
senga.active? # => true
Schedule
# Get games for a specific date
games = MLB::Schedule.games(date: Date.new(2025, 6, 14))
games.size # => 15
# Get games for a specific team (Mets home opener)
mets_games = MLB::Schedule.games(date: Date.new(2025, 4, 4), team: MLB::Team::NYM)
game = mets_games.first
game.game_pk # => 778465
game.official_date.to_s # => "2025-04-04"
game.status.final? # => true
game.venue.name # => "Citi Field"
game.day? # => true
game.description # => "Mets home opener"
game.teams.away.team.name # => "Toronto Blue Jays"
game.teams.home.team.name # => "New York Mets"
game.teams.away.score # => 0
game.teams.home.score # => 5
game.teams.home.winner? # => true
Standings
# Get all division standings
standings = MLB::Standings.all(season: 2025)
standings.size # => 6
# Access a specific division
nl_east = standings.find { |s| s.division.name == "National League East" }
nl_east.division.name # => "National League East"
nl_east.team_records.size # => 5
# Get team standings info (Mets finished 2nd in NL East in 2025)
mets = nl_east.team_records.find { |r| r.team.name == "New York Mets" }
mets.team.name # => "New York Mets"
mets.wins # => 83
mets.losses # => 79
mets.winning_percentage # => ".512"
mets.games_back # => "13.0"
mets.runs_scored # => 766
mets.runs_allowed # => 715
mets.run_differential # => 51
mets.division_rank # => "2"
mets.streak.streak_code # => "L1"
Team Leaders
# Get home run leaders for a specific team
hr_leaders = MLB::TeamLeaders.find(team: MLB::Team::NYM, category: "homeRuns", season: 2025)
hr_leaders.size # => 10
hr_leader = hr_leaders.first
hr_leader.rank # => 1
hr_leader.value # => "43"
hr_leader.person.full_name # => "Juan Soto"
League Leaders
# Get home run leaders
hr_leaders = MLB::Leaders.find(category: "homeRuns", season: 2025, limit: 5)
hr_leader = hr_leaders.first
hr_leader.rank # => 1
hr_leader.value # => "60"
hr_leader.person.full_name # => "Cal Raleigh"
hr_leader.team.name # => "Seattle Mariners"
# Get batting average leaders
avg_leaders = MLB::Leaders.find(category: "battingAverage", season: 2025, limit: 3)
avg_leaders.first.person.full_name # => "Aaron Judge"
avg_leaders.first.value # => ".331"
# Get wins leaders for pitchers
wins_leaders = MLB::Leaders.find(category: "wins", season: 2025, limit: 3)
wins_leaders.first.person.full_name # => "Max Fried"
wins_leaders.first.value # => "19"
Awards
# Find an award and get its recipients
mvp = MLB::Awards.find("NLMVP")
recipients = mvp.recipients(season: 2025)
winner = recipients.first
winner.player.full_name # => "Shohei Ohtani"
Draft
# Get draft picks for a year
picks = MLB::Draft.picks(year: 2025)
picks.size # => 615
# First overall pick
first_pick = picks.first
first_pick.pick_number # => 1
first_pick.pick_round # => "1"
first_pick.person.full_name # => "Eli Willits"
first_pick.team.name # => "Washington Nationals"
first_pick.school.name # => "Fort Cobb-Broxton HS"
first_pick.school.school_class # => "HS SR"
first_pick.pick_value # => "11075900"
first_pick.signing_bonus # => "8200000"
Transactions
# Get transactions for a date range
transactions = MLB::Transactions.between(
start_date: Date.new(2025, 12, 22),
end_date: Date.new(2025, 12, 22)
)
# Find a specific transaction
trade = transactions.find { |t| t.trade? && t.player&.full_name == "Jeff McNeil" }
trade.trade? # => true
trade.player.full_name # => "Jeff McNeil"
trade.from_team.name # => "New York Mets"
trade.to_team.name # => "Athletics"
trade.description # => "New York Mets traded 2B Jeff McNeil and cash to Athletics for RHP Yordan Rodriguez."
Boxscore
# Get boxscore for Mets home opener (5-0 shutout win)
boxscore = MLB::Boxscore.find(game: 778465)
# Team batting stats
home_batting = boxscore.teams.home.team_stats.batting
home_batting.runs # => 5
home_batting.hits # => 4
home_batting.home_runs # => 1
home_batting.rbi # => 5
# Team pitching stats
home_pitching = boxscore.teams.home.team_stats.pitching
home_pitching.innings_pitched # => "9.0"
home_pitching.hits # => 4
home_pitching.strike_outs # => 10
home_pitching.earned_runs # => 0
Linescore
# Get linescore for 2025 World Series Game 7 (11 innings)
linescore = MLB::Linescore.find(game: 813024)
linescore.scheduled_innings # => 9
linescore.innings.count # => 11
# Team totals (runs, hits, errors)
linescore.teams.home.runs # => 4
linescore.teams.home.hits # => 14
linescore.teams.away.runs # => 5
linescore.teams.away.hits # => 11
# Inning-by-inning breakdown
eleventh = linescore.innings[10]
eleventh.ordinal_num # => "11th"
eleventh.away.runs # => 1
eleventh.away.hits # => 1
Play-by-Play
# Get play-by-play for Mets home opener
pbp = MLB::PlayByPlay.find(game: 778465)
pbp.all_plays.size # => 65
pbp.scoring_plays.size # => 4
# Find scoring plays
scoring = pbp.all_plays.select { |p| p.about.scoring_play? }
hr = scoring.first
hr.about.inning # => 1
hr.about.scoring_play? # => true
hr.result.event # => "Home Run"
hr.result.description # => "Pete Alonso homers (3) on a fly ball to right field. Francisco Lindor scores."
hr.result.rbi # => 2
hr.matchup.batter.full_name # => "Pete Alonso"
hr.matchup.pitcher.full_name # => "Kevin Gausman"
Win Probability
# Get win probability data for 2025 World Series Game 7
# Dodgers vs Blue Jays at Rogers Centre (Dodgers won 5-4 in 11 innings)
wp = MLB::WinProbability.find(game: 813024)
wp.size # => 99
# Probability at game start (away team Dodgers slight favorites)
wp.first.at_bat_index # => 0
wp.first.home_team_win_probability # => 0.464
wp.first.away_team_win_probability # => 0.536
# After Bo Bichette's 3-run HR in the 3rd, Blue Jays led 3-0
wp[22].home_team_win_probability # => 0.828
wp[22].away_team_win_probability # => 0.172
# Miguel Rojas's game-tying HR in the 9th
wp[73].home_team_win_probability # => 0.558
wp[73].away_team_win_probability # => 0.442
# Will Smith's go-ahead HR in the 11th
wp[93].home_team_win_probability # => 0.194
wp[93].away_team_win_probability # => 0.806
# Final out - Dodgers clinch the title
wp.last.home_team_win_probability # => 0.0
wp.last.away_team_win_probability # => 1.0
Venues
# Get all MLB venues
venues = MLB::Venues.all(season: 2025)
venues.size # => 30
# Find a specific venue
citi_field = venues.find { |v| v.name == "Citi Field" }
citi_field.id # => 3289
citi_field.name # => "Citi Field"
citi_field.active? # => true
# Find venue by ID
citi_field = MLB::Venues.find(3289, season: 2025)
citi_field.name # => "Citi Field"
Attendance
# Get attendance data for a team
attendance = MLB::Attendance.find(team: MLB::Team::NYM, season: 2025)
record = attendance.first
record.team.name # => "New York Mets"
record.attendance_total # => 5816527
record.attendance_average_home # => 39316
record.attendance_high # => 43945
record.attendance_high_date # => 2025-04-04 (home opener)
record.games_home_total # => 82
Game Pace
# Get league-wide pace of play statistics
pace = MLB::GamePace.find(season: 2025)
pace.total_games # => 2430
pace.time_per_game # => "02:40:51"
pace.runs_per_game # => 8.89
pace.hits_per_game # => 16.52
pace.pitches_per_game # => 292.22
pace.total_extra_inn_games # => 209
Sponsorship
By contributing to the project, you help:
- Maintain the library: Keeping it up-to-date and secure.
- Add new features: Enhancements that make your life easier.
- Provide support: Faster responses to issues and feature requests.
⭐️ Bonus: Sponsors will get priority support and influence over the project roadmap. We will also list your name or your company's logo on our GitHub page.
Building and maintaining an open-source project like this takes a considerable amount of time and effort. Your sponsorship can help sustain this project. Even a small monthly donation makes a huge difference!
Click here to sponsor this project.
Development
Checkout and repo:
git checkout [email protected]:sferik/mlb-ruby.git
Enter the repo’s directory:
cd mlb-ruby
Install dependencies via Bundler:
bin/setup
Run the default Rake task to ensure all tests pass:
bundle exec rake
Create a new branch for your feature or bug fix:
git checkout -b my-new-branch
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/sferik/mlb-ruby.
Pull requests will only be accepted if they meet all the following criteria:
Code must conform to Standard Ruby. This can be verified with:
bundle exec rake standard
Code must conform to the RuboCop rules. This can be verified with:
bundle exec rake rubocop
Code must typecheck. This can be verified with:
bundle exec rake steep
100% branch coverage. This can be verified with:
bundle exec rake test
100% mutation coverage. This can be verified with:
bundle exec rake mutant
100% documentation coverage. This can be verified with:
bundle exec rake yardstick
License
The gem is available as open source under the terms of the MIT License.