# ESPN Sports Stats Scraper: Scores, Box Scores, Standings (`bisketapis/espn-sports-stats`) Actor

Every major ESPN league in one actor: scoreboards, full box scores with one row per player stat line, schedules, standings, rosters and career player stats for NFL, NBA, MLB, NHL, WNBA, college, soccer, UFC, PGA and F1.

- **URL**: https://apify.com/bisketapis/espn-sports-stats.md
- **Developed by:** [Chris Lucas](https://apify.com/bisketapis) (community)
- **Categories:** Other, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 rows

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## ESPN Sports Stats Scraper: scores, box scores, standings, rosters, player stats

Pulls data from ESPN's public JSON endpoints for NFL, NBA, MLB, NHL, WNBA, college football and basketball, the big soccer leagues, UFC, PGA and F1, all in one actor. No ESPN account or API key. Output is flat JSON rows with a `type` field, ready for a spreadsheet, a database or a model.

### What you get

| `type` | Mode | One row per |
|---|---|---|
| `game` | `scoreboard`, `teamSchedule` | game (UFC: bout, F1: session): teams, scores, records, status, venue, broadcast, odds, leaders |
| `gameDetail` | `gameDetails` | game: line scores, team box-score stats, attendance, officials, odds, win probability |
| `playerStatLine` | `gameDetails`, `playerStats` | player per stat group in a game, or player per season (plus a Career row) |
| `standing` | `standings` | team in a league table, with every ESPN stat column |
| `rosterPlayer` | `roster` | player on a team: jersey, position, age, height, weight, college, status, injuries |

Box scores differ per sport and the actor keeps each sport's own columns: NBA (MIN, PTS, FG, 3PT, REB, AST ...), NFL (passing, rushing, receiving, defensive, kicking ... as separate `statGroup` rows), MLB (batting, pitching), NHL (forwards, defenses, goalies), soccer (appearances, shots, saves ...). Numbers are returned as numbers; ratios like `11-18` stay strings.

### Input

| Field | Meaning | Example |
|---|---|---|
| `mode` | `scoreboard` (default), `gameDetails`, `teamSchedule`, `standings`, `roster`, `playerStats` | `scoreboard` |
| `leagues` | Keys or names: nfl, nba, mlb, nhl, wnba, college-football (ncaaf), mens-college-basketball (ncaab), eng.1 (epl), usa.1 (mls), esp.1 (laliga), ger.1, ita.1, fra.1, uefa.champions (ucl), ufc, pga, f1 | `["nfl","nba","mlb"]` |
| `dateFrom`, `dateTo` | YYYY-MM-DD, default yesterday to today, 31 days at most | `2026-10-27` |
| `eventIds` | gameDetails: ESPN game IDs (`nba:401909881` pins the league). Empty = every finished or live game in the date range | `["401909881"]` |
| `teamIds`, `teamNames` | teamSchedule / roster. Roster with neither returns the whole league | `["Lakers"]` |
| `athleteIds`, `athleteNames` | playerStats | `["LeBron James"]` |
| `season` | ESPN season year = the year the season ends (2026-27 NBA is 2027) | `2027` |
| `maxItems` | Hard cap on rows, default 500 | `500` |

```json
{"mode":"scoreboard","leagues":["nfl","nba","mlb"],"dateFrom":"2026-10-27","dateTo":"2026-10-29","maxItems":100}
```

### Output example (`game`)

```json
{"type":"game","league":"nba","sport":"basketball","season":2027,"seasonType":"regular-season","eventId":"401909877","date":"2026-10-27T23:30Z","name":"Brooklyn Nets at Boston Celtics","status":"Final","statusState":"post","completed":true,"homeName":"Boston Celtics","homeAbbrev":"BOS","homeScore":125,"homeRecord":"3-1","awayName":"Brooklyn Nets","awayAbbrev":"BKN","awayScore":124,"awayRecord":"0-4","winner":"Boston Celtics","venue":"TD Garden","city":"Boston","broadcast":"NBA League Pass, DAZN (YES)","oddsDetails":null,"spread":null,"overUnder":null,"leaders":[{"category":"points","team":"BOS","athlete":"Jayson Tatum","value":"40"}],"url":"https://www.espn.com/nba/game/_/gameId/401909877/nets-celtics","scrapedAt":"2026-10-31T01:44:00Z"}
```

### Output example (`playerStatLine`, from a box score)

```json
{"type":"playerStatLine","league":"nba","eventId":"401909881","date":"2026-10-28T23:00Z","team":"Miami Heat","teamAbbrev":"MIA","athleteId":"3032977","player":"Giannis Antetokounmpo","position":"F","starter":true,"statGroup":"","stats":{"MIN":31,"PTS":24,"FG":"11-18","3PT":"0-2","FT":"2-5","REB":18,"AST":3,"TO":2,"STL":1,"BLK":1},"url":"https://www.espn.com/nba/game/_/gameId/401909881","scrapedAt":"2026-10-31T01:46:00Z"}
```

### Pricing (pay per event)

| Event | Price | Applies to |
|---|---|---|
| `row` | $0.0005 | each `game`, `playerStatLine`, `standing` and `rosterPlayer` row |
| `game-detail` | $0.002 | each `gameDetail` summary row |

Examples: a 3-day NFL + NBA + MLB scoreboard (about 22 games) costs about $0.011. 1,000 scoreboard rows cost $0.50. One NBA box score (1 summary + about 19 player lines) costs about $0.0115. All 30 NBA standings rows cost $0.015. There is no start fee beyond Apify's platform usage. Runs never charge for failures or empty results, and `maxItems` caps spend.

### Use cases

Betting-model and fantasy data feeds, daily results digests, player-vs-player research, box-score datasets for training, standings and schedule widgets, sports newsletters.

### FAQ

**Is it live?** Scoreboards and box scores refresh as ESPN updates them; in-progress games return their current score and `status`.
**Why one request per day?** ESPN's scoreboard currently rejects date ranges, so the actor fetches each day separately. Up to 31 days per run.
**Which `season` do I pass?** The year the season ends. NFL 2026 = 2026, NBA 2026-27 = 2027.
**Do I need a proxy?** The endpoints are open. The default Apify datacenter proxy works; no residential proxy is used or needed.
**Other leagues?** Pass any ESPN `sport/league` path, e.g. `hockey/nhl` or `soccer/ger.1`. Common leagues are verified; others use the same endpoints.

### Limits

- Data comes from ESPN's public site API, which is undocumented and can change without notice.
- Golf and F1 rows keep the top 10 competitors per event; they have no home/away fields. UFC and F1 produce one row per bout or session.
- Odds are present when ESPN publishes them (mostly before and during games); box-score odds are the closing line.
- NFL box scores omit player positions in ESPN's response, so `position` is null there.
- Not affiliated with ESPN or The Walt Disney Company. Use the data in line with ESPN's terms.

# Actor input Schema

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

scoreboard = games for a date range. gameDetails = box score per game (one summary row plus one row per player stat line). teamSchedule = a team's season schedule. standings = league tables. roster = team rosters. playerStats = season-by-season and career stats per player.

## `leagues` (type: `array`):

Leagues by key or common name: nfl, nba, mlb, nhl, wnba, college-football (ncaaf), mens-college-basketball (ncaab), eng.1 (epl), usa.1 (mls), esp.1 (laliga), ger.1, ita.1, fra.1, uefa.champions (ucl), ufc, pga, f1. Any ESPN 'sport/league' path also works.

## `dateFrom` (type: `string`):

First day, YYYY-MM-DD. Default: yesterday. Used by scoreboard and gameDetails.

## `dateTo` (type: `string`):

Last day, YYYY-MM-DD. Default: today. The range can span 31 days at most.

## `eventIds` (type: `array`):

ESPN game IDs, e.g. 401909881, or league:id such as nba:401909881. Leave empty to get box scores for every finished or live game in the date range.

## `teamIds` (type: `array`):

ESPN team IDs for teamSchedule and roster, e.g. 13 for the Lakers.

## `teamNames` (type: `array`):

Team names or abbreviations, e.g. Lakers, GB, Manchester United. For roster, leaving both team fields empty returns every team in the league.

## `athleteIds` (type: `array`):

ESPN athlete IDs, e.g. 1966. Uses the first league in the list, or write league:id such as nba:1966.

## `athleteNames` (type: `array`):

Player names, searched on ESPN, e.g. LeBron James. The best match inside your chosen leagues is used.

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

ESPN season year, which is the year the season ends (2026-27 NBA = 2027). Optional for standings, schedule, roster and playerStats.

## `maxItems` (type: `integer`):

Hard cap on rows pushed (and billed) in this run.

## `maxConcurrency` (type: `integer`):

Parallel requests to ESPN, 1 to 5.

## `proxyConfiguration` (type: `object`):

ESPN's JSON API is open; the default Apify datacenter proxy is fine.

## Actor input object example

```json
{
  "mode": "scoreboard",
  "leagues": [
    "nfl",
    "nba",
    "mlb"
  ],
  "maxItems": 500,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

type = game, gameDetail, standing, rosterPlayer or playerStatLine.

## `runSummary` (type: `string`):

Per-input status, row counts and HTTP stats.

# 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": "scoreboard",
    "leagues": [
        "nfl",
        "nba",
        "mlb"
    ],
    "maxItems": 500,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("bisketapis/espn-sports-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": "scoreboard",
    "leagues": [
        "nfl",
        "nba",
        "mlb",
    ],
    "maxItems": 500,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("bisketapis/espn-sports-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": "scoreboard",
  "leagues": [
    "nfl",
    "nba",
    "mlb"
  ],
  "maxItems": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call bisketapis/espn-sports-stats --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bisketapis/espn-sports-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/Y3pQl5zpHKiUdUKHt/builds/yn7kPSUaASYvziRJf/openapi.json
