MLB Stats API Docs

Type to search endpoints by name, path, or keyword.

TypeScript types

A single, dependency-free file. Copy it below, or download mlb-stats-api.d.ts.

/**
 * MLB Stats API — TypeScript response types.
 * Source: https://statsapi.mlb.com
 * Generated: 2026-06-30 by scripts/bundle-types.ts
 *
 * Single-file, dependency-free. Copy-paste into your project as-is.
 */

// ─── common ────────────────────────────────────────

/**
 * Shared primitives used across many MLB Stats API responses.
 * Extracted here so endpoint-specific types stay small and consistent.
 */

/** Almost every response includes this MLBAM copyright string. */
export interface WithCopyright {
	copyright: string
}

/** The ubiquitous `{ id, name, link }` reference shape (sport, league, venue, ...). */
export interface IdNameLink {
	id: number
	name: string
	link: string
}

/** A reference that may omit `name` (e.g. springVenue). */
export interface IdLink {
	id: number
	link: string
}

export interface LeagueRecord {
	wins: number
	losses: number
	ties: number
	pct: string
}

/** A fielding position. */
export interface Position {
	code: string
	name: string
	type: string
	abbreviation: string
}

/** A player's roster status, e.g. `{ code: 'A', description: 'Active' }`. */
export interface CodeDescription {
	code: string
	description: string
}

/**
 * A person (player, coach, or umpire). Only `id`, `fullName`, and `link` are
 * always present; the rest depend on the endpoint and hydrations. Partial —
 * refine as you document specific people use cases.
 */
export interface Person {
	id: number
	fullName: string
	link: string
	firstName?: string
	lastName?: string
	primaryNumber?: string
	birthDate?: string
	currentAge?: number
	birthCity?: string
	birthCountry?: string
	height?: string
	weight?: number
	active?: boolean
	primaryPosition?: Position
	useName?: string
	boxscoreName?: string
	nickName?: string
	gender?: string
	isPlayer?: boolean
	mlbDebutDate?: string
	batSide?: CodeDescription
	pitchHand?: CodeDescription
	nameSlug?: string
	[key: string]: unknown
}

/** A roster entry (players, coaches, or umpires share this wrapper item). */
export interface RosterEntry {
	person: Person
	jerseyNumber?: string
	position?: Position
	status?: CodeDescription
	job?: string
	jobId?: string
	title?: string
}

/** Shared roster wrapper for `/roster`, `/coaches`, and `/jobs/{jobType}`. */
export interface RosterResponse extends WithCopyright {
	roster: RosterEntry[]
	link: string
	teamId?: number
	rosterType?: string
}

// ─── sport ────────────────────────────────────────

export interface Sport {
	id: number
	code: string
	link: string
	name: string
	abbreviation: string
	sortOrder: number
	activeStatus: boolean
}

/** `GET /api/v1/sports` */
export interface SportsResponse extends WithCopyright {
	sports: Sport[]
}

export interface Division {
	id: number
	name: string
	season?: string
	nameShort: string
	link: string
	abbreviation: string
	league: IdNameLink
	sport: IdNameLink
	hasWildcard: boolean
	sortOrder: number
	active: boolean
}

/** `GET /api/v1/divisions` */
export interface DivisionsResponse extends WithCopyright {
	divisions: Division[]
}

/** Partial — leagues carry a large `seasonDateInfo` block; refine as needed. */
export interface League {
	id: number
	name: string
	link: string
	abbreviation: string
	nameShort: string
	seasonState?: string
	hasWildCard?: boolean
	numTeams?: number
	sport?: IdNameLink
	season?: string
	sortOrder?: number
	active?: boolean
	[key: string]: unknown
}

/** `GET /api/v1/leagues` */
export interface LeaguesResponse extends WithCopyright {
	leagues: League[]
}

// ─── team ────────────────────────────────────────

export interface SpringLeague extends IdNameLink {
	abbreviation: string
}

export interface Team {
	id: number
	name: string
	link: string
	season: number
	venue: IdNameLink
	springVenue: IdLink
	springLeague: SpringLeague
	allStarStatus: string
	teamCode: string
	fileCode: string
	abbreviation: string
	teamName: string
	locationName: string
	firstYearOfPlay: string
	league: IdNameLink
	division: IdNameLink
	sport: IdNameLink
	shortName: string
	franchiseName: string
	clubName: string
	active: boolean
}

/** `GET /api/v1/teams` */
export interface TeamsResponse extends WithCopyright {
	teams: Team[]
}

// ─── schedule ────────────────────────────────────────

export interface GameStatus {
	abstractGameState: string
	codedGameState: string
	detailedState: string
	statusCode: string
	startTimeTBD: boolean
	abstractGameCode: string
}

export interface ScheduleTeamSide {
	team: IdNameLink
	leagueRecord: LeagueRecord
	/** Absent before a game starts. */
	score?: number
	isWinner?: boolean
	splitSquad: boolean
	seriesNumber?: number
}

export interface ScheduleGame {
	gamePk: number
	gameGuid: string
	link: string
	gameType: string
	season: string
	gameDate: string
	officialDate: string
	status: GameStatus
	teams: {
		away: ScheduleTeamSide
		home: ScheduleTeamSide
	}
	venue: IdNameLink
	content: { link: string }
	isTie?: boolean
	gameNumber: number
	doubleHeader: string
	dayNight: string
	scheduledInnings: number
	seriesDescription: string
	seriesGameNumber?: number
	gamesInSeries?: number
}

export interface ScheduleDate {
	date: string
	totalItems: number
	totalEvents: number
	totalGames: number
	totalGamesInProgress: number
	games: ScheduleGame[]
	events: unknown[]
}

/** `GET /api/v1/schedule` */
export interface ScheduleResponse extends WithCopyright {
	totalItems: number
	totalEvents: number
	totalGames: number
	totalGamesInProgress: number
	dates: ScheduleDate[]
}

// ─── game ────────────────────────────────────────

/**
 * Game endpoints are deeply nested. These types describe the top-level structure
 * accurately and leave the heavy nested blocks as `Record<string, unknown>` /
 * partial — refine the specific shapes as you document each use case.
 */

// ── Live feed (GUMBO) ───────────────────────────────────────────────────────────

export interface GameFeedMetaData {
	wait: number
	timeStamp: string
	gameEvents: string[]
	logicalEvents: string[]
}

/** Partial — top-level keys of `gameData`. */
export interface GameFeedGameData {
	game: Record<string, unknown>
	datetime: Record<string, unknown>
	status: Record<string, unknown>
	teams: Record<string, unknown>
	players: Record<string, unknown>
	venue: Record<string, unknown>
	weather: Record<string, unknown>
	probablePitchers: Record<string, unknown>
	[key: string]: unknown
}

/** Partial — top-level keys of `liveData`. */
export interface GameFeedLiveData {
	plays: Record<string, unknown>
	linescore: Record<string, unknown>
	boxscore: Record<string, unknown>
	decisions: Record<string, unknown>
	leaders: Record<string, unknown>
	[key: string]: unknown
}

/** `GET /api/v1.1/game/{gamePk}/feed/live` */
export interface GameFeedResponse extends WithCopyright {
	gamePk: number
	link: string
	metaData: GameFeedMetaData
	gameData: GameFeedGameData
	liveData: GameFeedLiveData
}

// ── Sub-resources ───────────────────────────────────────────────────────────────

/** `GET /api/v1/game/{gamePk}/boxscore` — partial. */
export interface BoxscoreResponse extends WithCopyright {
	teams: Record<string, unknown>
	officials: unknown[]
	info: unknown[]
	pitchingNotes: unknown[]
	topPerformers?: unknown[]
}

/** `GET /api/v1/game/{gamePk}/linescore` — partial. */
export interface LinescoreResponse extends WithCopyright {
	currentInning?: number
	currentInningOrdinal?: string
	inningState?: string
	scheduledInnings: number
	innings: unknown[]
	teams: Record<string, unknown>
	defense?: Record<string, unknown>
	offense?: Record<string, unknown>
	[key: string]: unknown
}

/** `GET /api/v1/game/{gamePk}/content` — partial. */
export interface GameContentResponse extends WithCopyright {
	link: string
	editorial?: Record<string, unknown>
	media?: Record<string, unknown>
	highlights?: Record<string, unknown>
	summary?: Record<string, unknown>
	[key: string]: unknown
}

/** `GET /api/v1/game/{gamePk}/contextMetrics` — partial. */
export interface ContextMetricsResponse {
	game: Record<string, unknown>
	awayWinProbability?: number
	homeWinProbability?: number
	[key: string]: unknown
}

/** `GET /api/v1/game/{gamePk}/winProbability` — array of play states (partial). */
export type WinProbabilityResponse = Array<Record<string, unknown>>

/** `GET /api/v1/game/{gamePk}/playByPlay` — partial. */
export interface PlayByPlayResponse extends WithCopyright {
	allPlays: unknown[]
	currentPlay?: Record<string, unknown>
	scoringPlays: number[]
	playsByInning: unknown[]
}

/** `GET /api/v1/gamePace` — partial. */
export interface GamePaceResponse extends WithCopyright {
	teams?: unknown[]
	leagues?: unknown[]
	sports?: unknown[]
	[key: string]: unknown
}

// ─── person ────────────────────────────────────────

/**
 * `GET /api/v1/people/{personId}`, `/people/search`, and `/people/changes` all
 * return a `people` array.
 */
export interface PeopleResponse extends WithCopyright {
	people: Person[]
}

export interface FreeAgent {
	player: IdNameLink
	originalTeam?: IdNameLink
	newTeam?: IdNameLink
	notes?: string | null
	dateSigned?: string
	dateDeclared?: string
	position?: { code: string; name: string; type: string; abbreviation: string }
	[key: string]: unknown
}

/** `GET /api/v1/people/freeAgents` */
export interface FreeAgentsResponse extends WithCopyright {
	freeAgents: FreeAgent[]
	season: string
}

// ─── stats ────────────────────────────────────────

/**
 * The stats endpoints share a `stats` array of "stat groups", each holding
 * `splits` of actual numbers. The per-stat `stat` object varies by group
 * (hitting / pitching / fielding), so it's left open. Partial — refine per group.
 */
export interface StatSplit {
	season?: string
	stat: Record<string, unknown>
	team?: IdNameLink
	player?: Person
	gameType?: string
	numTeams?: number
	[key: string]: unknown
}

export interface StatGroup {
	type: { displayName: string }
	group: { displayName: string }
	exemptions?: unknown[]
	splits: StatSplit[]
	totalSplits?: number
}

/**
 * `GET /api/v1/stats`, `/people/{personId}/stats`, and
 * `/people/{personId}/stats/game/{gamePk}`.
 */
export interface StatsResponse extends WithCopyright {
	stats: StatGroup[]
}

export interface LeaderEntry {
	rank: number
	value: string
	team?: IdNameLink
	league?: IdNameLink
	person: Person
	sport?: IdNameLink
	season?: string
	numTeams?: number
}

export interface LeaderCategory {
	leaderCategory: string
	season?: string
	gameType?: string
	leaders: LeaderEntry[]
	statGroup?: string
	totalSplits?: number
}

/** `GET /api/v1/stats/leaders` */
export interface LeadersResponse extends WithCopyright {
	leagueLeaders: LeaderCategory[]
}

// ─── standings ────────────────────────────────────────

export interface TeamRecord {
	team: IdNameLink
	season?: string
	streak?: { streakType: string; streakNumber: number; streakCode: string }
	clinchIndicator?: string
	divisionRank?: string
	leagueRank?: string
	sportRank?: string
	gamesPlayed: number
	gamesBack: string
	wildCardGamesBack?: string
	leagueRecord: LeagueRecord
	lastUpdated?: string
	runsAllowed?: number
	runsScored?: number
	divisionChamp?: boolean
	divisionLeader?: boolean
	clinched?: boolean
	magicNumber?: string
	wins: number
	losses: number
	runDifferential?: number
	winningPercentage?: string
	records?: Record<string, unknown>
	[key: string]: unknown
}

export interface StandingsRecord {
	standingsType: string
	league: IdNameLink
	division: IdNameLink
	sport: IdNameLink
	lastUpdated?: string
	teamRecords: TeamRecord[]
}

/** `GET /api/v1/standings` */
export interface StandingsResponse extends WithCopyright {
	records: StandingsRecord[]
}

// ─── reference ────────────────────────────────────────

/** A season's calendar of key dates. */
export interface Season {
	seasonId: string
	hasWildcard: boolean
	regularSeasonStartDate?: string
	regularSeasonEndDate?: string
	seasonStartDate?: string
	seasonEndDate?: string
	preSeasonStartDate?: string
	postSeasonStartDate?: string
	postSeasonEndDate?: string
	allStarDate?: string
	[key: string]: unknown
}

/** `GET /api/v1/seasons` */
export interface SeasonsResponse extends WithCopyright {
	seasons: Season[]
}

export interface Venue {
	id: number
	name: string
	link: string
	active?: boolean
	season?: string
	location?: Record<string, unknown>
	[key: string]: unknown
}

/** `GET /api/v1/venues` */
export interface VenuesResponse extends WithCopyright {
	venues: Venue[]
}

export interface DraftPick {
	bisPlayerId?: number
	pickRound?: string
	pickNumber?: number
	roundPickNumber?: number
	rank?: number
	pickValue?: string | null
	signingBonus?: string | null
	person?: Person
	team?: IdNameLink
	[key: string]: unknown
}

export interface DraftRound {
	round: string
	picks: DraftPick[]
}

/** `GET /api/v1/draft/{year}` */
export interface DraftResponse extends WithCopyright {
	drafts: {
		draftYear: number
		rounds: DraftRound[]
	}
}

export interface Transaction {
	id: number
	person?: IdNameLink
	fromTeam?: IdNameLink
	toTeam?: IdNameLink
	date?: string
	effectiveDate?: string
	typeCode?: string
	typeDesc?: string
	description: string
}

/** `GET /api/v1/transactions` */
export interface TransactionsResponse extends WithCopyright {
	transactions: Transaction[]
}

export interface GameUniforms {
	gamePk: number
	home: Record<string, unknown>
	away: Record<string, unknown>
}

/** `GET /api/v1/uniforms/game` */
export interface UniformsResponse extends WithCopyright {
	uniforms: GameUniforms[]
}

/** A team's attendance totals for a year. Partial — many aggregate fields. */
export interface AttendanceRecord {
	team?: IdNameLink
	year?: string
	gameType?: string
	attendanceTotal?: number
	attendanceAverageYtd?: number
	attendanceHigh?: number
	attendanceLow?: number
	gamesTotal?: number
	[key: string]: unknown
}

/** `GET /api/v1/attendance` */
export interface AttendanceResponse extends WithCopyright {
	records: AttendanceRecord[]
	aggregateTotals?: Record<string, unknown>
}

// ─── meta ────────────────────────────────────────

/**
 * The `/api/v1/{type}` meta endpoints return flat arrays of enumeration entries.
 * They're the source of truth for the magic strings other endpoints accept
 * (stat names, game statuses, game type codes).
 */

/** One entry from `GET /api/v1/baseballStats`. Partial. */
export interface BaseballStat {
	name: string
	lookupParam: string
	isCounting: boolean
	label: string
	statGroups?: { displayName: string }[]
	orgTypes?: { displayName: string }[]
	[key: string]: unknown
}

/** `GET /api/v1/baseballStats` */
export type BaseballStatsResponse = BaseballStat[]

/** One entry from `GET /api/v1/gameStatus`. Partial. */
export interface GameStatusEntry {
	abstractGameState?: string
	codedGameState?: string
	detailedState?: string
	statusCode?: string
	abstractGameCode?: string
	[key: string]: unknown
}

/** `GET /api/v1/gameStatus` */
export type GameStatusResponse = GameStatusEntry[]

/** `GET /api/v1/gameTypes` */
export type GameTypesResponse = Array<{ id: string; description: string }>