# MLB Stats API - schedule, scores, standings, player stats (`retrainmap/mlb-stats`) Actor

Read MLB's public Stats API (statsapi.mlb.com) and get flat rows: games with status, teams, scores and venue; division standings with W-L, pct, GB and streak; team rosters; season hitting or pitching stats per player. Default: schedule for today +/-3 days (standings if no games).

- **URL**: https://apify.com/retrainmap/mlb-stats.md
- **Developed by:** [RetrainMap Team](https://apify.com/retrainmap) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## MLB Stats API — schedule, scores, standings, player stats

Flat rows from MLB's public Stats API (statsapi.mlb.com, no key): every game in a date
range with status, teams, scores, records and venue; regular-season standings with W-L,
pct, games back, streak, run differential and home/away/last-ten splits; team rosters
with position and jersey number; per-player season hitting or pitching stats. Normalised,
one row per game / team / player, ready for CSV or JSON.

**The default input (schedule, today ±3 days) succeeds within 5 minutes and returns
rows** — Apify auto-tests it daily. In the off-season, when that window has no games and
no dates were given, the Actor writes the last completed season's standings instead and
says so in the log, the status message and `RUN_SUMMARY.details.fallback_mode`.

### Data source and status

| | |
|---|---|
| Publisher | MLB Advanced Media, L.P. (Major League Baseball) |
| API | https://statsapi.mlb.com/api/v1 — public, no key. MLB publishes no formal documentation; the endpoints used are the ones behind mlb.com and are documented by the community (e.g. https://github.com/toddrob99/MLB-StatsAPI/wiki) |
| What this Actor reads | `GET /schedule?sportId=1&startDate=&endDate=`, `GET /standings?leagueId=103,104&season=&standingsTypes=regularSeason&hydrate=division,league,team`, `GET /teams?sportId=1&season=` + `GET /teams/{id}/roster?season=&rosterType=`, `GET /people/{id}/stats?stats=season&group=hitting|pitching&season=` — plain GETs, at most one per 500 ms by default |
| Refresh cadence | Live: scores and game status update during games (`status` = In Progress / Final …); standings carry `last_updated`; rosters change with transactions; season stats update after each game. The Actor reads live on every run; `fetched_at` on each row is the fetch time |
| Terms / attribution | Every API response carries MLB's notice: use of the content acknowledges agreement to the terms at http://gdx.mlb.com/components/copyright.txt (MLBAM copyright; personal, non-commercial use unless licensed). The notice is stored verbatim in `RUN_SUMMARY.copyright`. You are responsible for using the data within those terms |
| Known caveats | `schedule` returns all game types in the range (spring training, regular season, postseason, All-Star, exhibitions — see `game_type_name`); scores are absent until a game starts; a range may span at most 62 days. `standings` are regular-season only; `games_back`, `magic_number`, `elimination_number` are the API's strings (`-` when not applicable). `team_roster` needs numeric team ids (30 listed at https://statsapi.mlb.com/api/v1/teams?sportId=1); an unknown id fails the run with the valid list. `player_stats`: an unknown person id or a player without appearances answers an empty list — the Actor warns and writes no row; a traded player yields one row per team plus a season total row; rate stats (`avg`, `era` …) are the API's strings. Dates are UTC |

Honesty note: sports data only, as published by MLB's API — nothing is inferred; for
information, not for wagering; not affiliated with Major League Baseball.

Identification: the requests carry a product-token User-Agent and the operator's
contact address in the standard `From:` header (RFC 9110 §10.1.2).

### Input

| Field | Type | Meaning |
|---|---|---|
| `mode` | select | `schedule` (default), `standings`, `team_roster`, `player_stats` |
| `date_from` / `date_to` | `YYYY-MM-DD` | `schedule` only; both empty = today ±3 days (UTC); at most 62 days |
| `season` | integer | Year for standings / roster / stats; empty = current year |
| `team_ids` | array | `team_roster` only: e.g. `147` (Yankees), `119` (Dodgers) |
| `roster_type` | select | `active` (default), `40Man`, `fullSeason`, `fullRoster` |
| `player_ids` | array | `player_stats` only: e.g. `660271` (Ohtani), `592450` (Judge) |
| `group` | select | `hitting` (default) or `pitching` |
| `max_records` | integer | Default 500 |
| `request_interval_ms` | integer | Default 500 (floor 250) |
| `contact_email` | string | Sent in the `From:` header |

Example — 2026 hitting lines for Ohtani, Judge and Soto (3 requests):

```json
{ "mode": "player_stats", "player_ids": ["660271", "592450", "665742"], "group": "hitting", "season": 2026 }
```

### Output (dataset row)

Every row carries `mode`, `mlb_url` and `fetched_at`.

- `schedule`: `game_pk`, `date`, `game_datetime_utc`, `season`, `game_type`, `game_type_name`,
  `status`, `status_code`, `abstract_state`, `away_team_id`, `away_team`, `away_score`,
  `away_record`, `away_is_winner`, `home_team_id`, `home_team`, `home_score`, `home_record`,
  `home_is_winner`, `venue_id`, `venue`, `day_night`, `double_header`, `game_number`,
  `series_description`, `series_game_number`, `games_in_series`, `scheduled_innings`, `is_tie`.
- `standings`: `season`, `league`, `division`, `division_short`, `team_id`, `team`,
  `team_abbrev`, `wins`, `losses`, `pct`, `games_played`, `games_back`, `wild_card_games_back`,
  `division_rank`, `league_rank`, `wild_card_rank`, `sport_rank`, `streak`, `runs_scored`,
  `runs_allowed`, `run_differential`, `home_record`, `away_record`, `last_ten`,
  `division_leader`, `clinched`, `magic_number`, `elimination_number`, `last_updated`.
- `team_roster`: `season`, `roster_type`, `team_id`, `team`, `team_abbrev`, `player_id`,
  `player_name`, `jersey_number`, `position`, `position_code`, `position_abbrev`,
  `position_type`, `status`, `parent_team_id`.
- `player_stats`: `player_id`, `player_name`, `season`, `group`, `game_type`, `team_id`, `team`,
  `league`, then hitting (`games_played`, `plate_appearances`, `at_bats`, `runs`, `hits`,
  `doubles`, `triples`, `home_runs`, `rbi`, `stolen_bases`, `walks`, `strikeouts`, `avg`, `obp`,
  `slg`, `ops`) or pitching (`games_played`, `games_started`, `wins`, `losses`, `saves`,
  `innings_pitched`, `era`, `whip`, `strikeouts`, `walks`, `hits_allowed`, `home_runs_allowed`,
  `earned_runs`) columns, plus `stats` = the API's complete stat object.

A run summary (mode, filters, MLB's copyright notice, requests, off-season fallback, whether
the pay-per-event budget stopped the run) is stored as `RUN_SUMMARY` in the run's key-value
store.

### Pricing (pay per event)

| Event | Price |
|---|---|
| `run-start` — once per run | $0.10 |
| `record` — per row written | $0.005 |

A full week of regular-season games (~100 rows) costs about $0.60; standings (30 rows)
$0.25. Rows stop when your run's maximum charge is reached; the run summary says so.

### Operator

Steelyard Ventures LLC (RetrainMap) — info@steelyardclinical.com. Not affiliated with
Major League Baseball or MLB Advanced Media. The Actor writes only to its own dataset and
key-value store; it stores no credentials and sends nothing else.

# Actor input Schema

## `mode` (type: `string`):

schedule = one row per game in the date range (status, teams, scores, venue). standings = one row per team from the regular-season standings of `season`. team\_roster = one row per player on each team in team\_ids. player\_stats = one row per player and team from the season stats of player\_ids (hitting or pitching).

## `date_from` (type: `string`):

schedule only. When both dates are empty the Actor uses today (UTC) minus 3 days through today plus 3 days. A range may span at most 62 days.

## `date_to` (type: `string`):

schedule only. Inclusive upper bound; defaults to date\_from when only date\_from is given.

## `season` (type: `integer`):

standings, team\_roster and player\_stats: the season year. Empty = the current year (UTC).

## `team_ids` (type: `array`):

team\_roster only: MLB team ids, e.g. 147 = New York Yankees, 119 = Los Angeles Dodgers, 111 = Boston Red Sox. The 30 ids are listed at https://statsapi.mlb.com/api/v1/teams?sportId=1. An unknown id fails the run with the valid list.

## `roster_type` (type: `string`):

team\_roster only: the API's rosterType.

## `player_ids` (type: `array`):

player\_stats only: MLB person ids, e.g. 660271 = Shohei Ohtani, 592450 = Aaron Judge, 543037 = Gerrit Cole (the number in a mlb.com/player URL). A player with no stats for the season/group yields no row and a warning.

## `group` (type: `string`):

player\_stats only: hitting or pitching season stats.

## `max_records` (type: `integer`):

Stop after this many rows.

## `request_interval_ms` (type: `integer`):

Politeness delay towards statsapi.mlb.com. The schedule is one request per run; standings one; rosters one per team (+1 for the team list); player stats one per player. Floor 250 ms.

## `contact_email` (type: `string`):

Sent in the standard From: request header so the data owner can reach the operator (RFC 9110 s10.1.2).

## Actor input object example

```json
{
  "mode": "schedule",
  "roster_type": "active",
  "group": "hitting",
  "max_records": 500,
  "request_interval_ms": 500,
  "contact_email": "info@steelyardclinical.com"
}
```

# Actor output Schema

## `results` (type: `string`):

One row per game (schedule), per team (standings), per rostered player (team\_roster) or per player-team season line (player\_stats), flat and normalised.

## `results_csv` (type: `string`):

The same rows as a CSV file.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "schedule",
    "max_records": 500
};

// Run the Actor and wait for it to finish
const run = await client.actor("retrainmap/mlb-stats").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "schedule",
    "max_records": 500,
}

# Run the Actor and wait for it to finish
run = client.actor("retrainmap/mlb-stats").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "schedule",
  "max_records": 500
}' |
apify call retrainmap/mlb-stats --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,retrainmap/mlb-stats"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/sQ6H1tXPQqpUHFqwZ/builds/Kf98j1yFfgtmUE060/openapi.json
