A comprehensive Go SDK for the unauthenticated portions of the MLB Stats API. Provides idiomatic, type-safe access to baseball data — teams, players, schedules, live game feeds, stats, standings, and more.
Disclaimer: This library is not affiliated with, endorsed by, or sponsored by Major League Baseball (MLB) or MLB Advanced Media. All MLB data accessed through this SDK is subject to MLB's copyright notice and terms of service. A rate limiter is included by default (10 req/s), but users are ultimately responsible for using this SDK respectfully and in compliance with MLB's terms.
client := mlb.NewClient()
// Get today's schedule
schedule, _ := client.Schedule.Games(ctx, mlb.WithSportID(models.SportMLB))
// Look up a player
ohtani, _ := client.People.Get(ctx, 660271) // (player ID for Shohei Ohtani)
// Fetch live game data
linescore, _ := client.Game.Linescore(ctx, 746436) // (game ID)go get github.com/pmurley/go-mlb
Requires Go 1.25.2+.
Runnable examples in examples/ — each is a standalone main.go:
| Example | What it demonstrates |
|---|---|
quickstart |
Create a client, list all MLB teams |
player_stats |
Look up a player and fetch season hitting stats |
todays_schedule |
Today's games with live scores and status |
live_game |
Inning-by-inning linescore from a completed game |
standings |
Division standings with W/L/PCT/GB |
team_roster |
Active roster with positions and jersey numbers |
league_leaders |
Top 10 HR and batting average leaderboards |
statcast |
Sabermetrics (WAR, wOBA) and batted ball exit velo/launch angle |
reviews |
2026 ABS (Automated Ball-Strike) challenge summary |
transactions |
Recent trades and free agent signings |
go run ./examples/quickstart/
The default client comes with sensible defaults: rate limiting (10 req/s), in-memory LRU caching (1000 entries, 5-minute TTL), and automatic retries with exponential backoff.
client := mlb.NewClient()Configure with functional options:
client := mlb.NewClient(
mlb.WithRateLimit(5),
mlb.WithMaxRetries(2),
mlb.WithLogger(slog.Default()),
)All methods take a context.Context and optional request parameters:
ctx := context.Background()
// List all MLB teams
teams, err := client.Teams.List(ctx, mlb.WithSportID(models.SportMLB))
// Get a specific team with roster data
team, err := client.Teams.Get(ctx, models.TeamYankees, mlb.WithHydrate("roster"))
// Today's games
schedule, err := client.Schedule.Games(ctx,
mlb.WithSportID(models.SportMLB),
mlb.WithDate("2024-07-04"),
)
// League leaders
leaders, err := client.Stats.Leaders(ctx,
[]models.LeaderCategory{"homeRuns"},
mlb.WithSeason(2024),
mlb.WithSportID(models.SportMLB),
mlb.WithLimit(10),
)
// AL standings
standings, err := client.Standings.List(ctx,
mlb.WithLeagueID(models.LeagueAmerican),
mlb.WithSeason(2024),
)// Full live feed (play-by-play, boxscore, linescore in one call)
feed, err := client.Game.LiveFeed(ctx, 746436)
// Individual components
boxscore, err := client.Game.Boxscore(ctx, 746436)
plays, err := client.Game.PlayByPlay(ctx, 746436)
// Historical game state at a specific point in time
linescore, err := client.Game.Linescore(ctx, 746436,
mlb.WithTimecode("20240704_230000"),
)// Player career stats via hydration
player, err := client.People.Get(ctx, 545361,
mlb.WithHydrate("stats(group=[hitting],type=[career])"),
)
// Per-team stats
stats, err := client.Teams.Stats(ctx, models.TeamYankees,
[]models.StatType{models.StatTypeSeason},
[]models.StatGroup{models.StatGroupHitting},
mlb.WithSeason(2024),
)Every API call accepts functional options for filtering and configuration:
| Option | Description |
|---|---|
WithSeason(2024) |
Filter by season year |
WithSportID(models.SportMLB) |
Sport level |
WithTeamID(models.TeamYankees) |
Filter by team(s) |
WithDate("2024-07-04") |
Specific date |
WithStartDate / WithEndDate |
Date range |
WithGameType(models.GameTypeRegularSeason) |
Game type filter |
WithHydrate("roster", "stats") |
Embed related data |
WithFields(...) |
Limit response fields |
WithLimit(25) / WithOffset(0) |
Pagination |
WithNoCache() |
Bypass cache for this request |
WithCacheTTL(time.Minute) |
Override cache TTL |
WithQueryParam(key, val) |
Escape hatch for any parameter |
See options.go for the full list (40+ options).
| Service | Description | Key methods |
|---|---|---|
Teams |
Team data, rosters, personnel, stats | List, Get, Roster, Stats, Leaders |
People |
Player biographical data and search | Get, List, Search |
Schedule |
Game schedules and events | Games, Postseason, TiedGames |
Game |
Live and completed game data | LiveFeed, Boxscore, Linescore, PlayByPlay |
Stats |
League-wide stats and leaderboards | Stats, Leaders |
Standings |
League standings | List |
Draft |
Draft picks and prospects | List, Prospects |
Attendance |
Attendance records | List |
Awards |
Award winners | List, Get |
Broadcast |
Broadcast schedules | List |
Conferences |
Conference data | List |
Divisions |
Division data | List |
HighLow |
Statistical highs and lows | List |
HomeRunDerby |
Home Run Derby data | List, Get |
Jobs |
MLB job listings | List |
League |
League info, All-Star ballot | List, Get, AllStarBallot |
Meta |
Lookup/meta endpoints | Lookup |
Milestones |
Player milestones | List |
Reviews |
Replay review data | List |
Seasons |
Season date info | List |
Sports |
Sport definitions | List, Get |
Transactions |
Player transactions | List |
Uniforms |
Team uniform data | List |
Venues |
Stadiums and venues | List |
| Option | Default | Description |
|---|---|---|
WithHTTPClient(c) |
30s timeout | Custom *http.Client |
WithBaseURL(url) |
https://statsapi.mlb.com |
Override API base URL |
WithUserAgent(ua) |
go-mlb/1.0 |
Custom User-Agent header |
WithRateLimit(rps) |
10 req/s | Requests per second (0 to disable) |
WithCache(c) |
In-memory LRU | Custom Cache implementation (nil to disable) |
WithMaxRetries(n) |
3 | Retry attempts (0 to disable) |
WithLogger(l) |
none | *slog.Logger for debug output |
API errors are returned as *mlb.APIError and can be inspected with errors.As:
team, err := client.Teams.Get(ctx, 99999)
if err != nil {
var apiErr *mlb.APIError
if errors.As(err, &apiErr) {
fmt.Println(apiErr.StatusCode) // 404
fmt.Println(apiErr.Message) // "Not Found"
}
}Convenience methods: apiErr.IsNotFound(), apiErr.IsInvalidRequest(), apiErr.IsServerError().
Transient errors (429, 502, 503, 504) are automatically retried with exponential backoff.
GET responses are cached automatically. Bring your own implementation by satisfying the Cache interface:
type Cache interface {
Get(key string) ([]byte, bool)
Set(key string, value []byte, ttl time.Duration)
}Or disable caching entirely:
client := mlb.NewClient(mlb.WithCache(nil))