# ESPN Transactions Scraper - NFL, NBA, MLB, NHL & WNBA (`hgservices/espn-transactions-scraper`) Actor

Scrape NFL, NBA, MLB, NHL and WNBA roster transactions from ESPN: signings, releases, trades, waivers, injured list and IR moves, call-ups and practice squad elevations. Filter by team or player. Get past years back to 2001. Export JSON, CSV or Excel.

- **URL**: https://apify.com/hgservices/espn-transactions-scraper.md
- **Developed by:** [Harish Garg](https://apify.com/hgservices) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 saved transactions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Transactions Scraper — NFL, NBA, MLB, NHL & WNBA Signings, Trades and Roster Moves

Get **roster transactions** for the **NFL, NBA, MLB, NHL and WNBA** from ESPN. Every signing, release, trade, waiver claim, injured reserve and injured list move, call-up, option and practice squad elevation, with the team and the date.

Get the moves of the last few days for a live feed, or a whole past year for research. Filter by team or by player. Download the data as JSON, CSV, Excel or HTML, or read it from the API.

No API key. No login. No coding needed.

### What does ESPN Transactions Scraper do?

- **Signings and releases** — free-agent signings, contract extensions, rookie contracts, two-way and hardship contracts, releases and waivers.
- **Trades** — the players, draft picks and considerations that each team sent and received.
- **Injury moves** — NFL injured reserve, MLB 10-day, 15-day and 60-day injured list, NHL long-term injured reserve, and every return from them.
- **Call-ups and send-downs** — MLB recalls, options and selected contracts, NHL recalls from and assignments to the AHL.
- **Practice squad** — NFL practice squad signings and game-day elevations.
- **Coaching and front office** — hires and firings that ESPN reports as team transactions.
- **History** — any past calendar year.

### Supported leagues

| League | Code | Transactions per year | What you get |
|--------|------|-----------------------|--------------|
| NFL | `nfl` | about 2,800 | Signings, releases, trades, injured reserve, practice squad, elevations |
| MLB | `mlb` | about 3,500 | Injured list, recalls, options, designated for assignment, trades, signings |
| NHL | `nhl` | about 1,800 | Recalls, AHL assignments, waivers, injured reserve, signings, trades |
| NBA | `nba` | about 500 | Signings, two-way and 10-day contracts, waivers, trades, extensions |
| WNBA | `wnba` | about 150 | Signings, hardship contracts, waivers, trades |

ESPN publishes no transactions for college sports or soccer.

### Why use this sports transactions scraper?

- **Fantasy sports** — Catch a waiver, a release or an injured reserve move as soon as ESPN reports it, and post it to your league's Slack or Discord.
- **Team and player trackers** — Follow one club's roster moves, or every move that names one player.
- **Sports betting and prediction models** — Add roster changes and injured list moves to your model as features.
- **Sports media and newsletters** — Build a daily "transactions wire" for every league in one run.
- **Research and analytics** — Download whole years to study roster churn, call-up patterns or trade activity in Excel, Google Sheets, Python or R.

### How to scrape sports transactions from ESPN

1. Click **Try for free** and sign in to Apify. A free account is enough.
2. In **Leagues**, pick one or more leagues.
3. Set **Lookback (days)** for recent moves, or set **Year** for a whole calendar year.
4. Optional: add team abbreviations or team names in **Teams**, or player names in **Players**.
5. Click **Start**. Most runs finish in a few seconds.
6. Open the **Output** tab. Download the data as JSON, CSV, Excel or HTML, or view it as a table.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `leagues` | string\[] | `["nfl"]` | `nfl`, `nba`, `mlb`, `nhl`, `wnba` |
| `days` | integer | `7` | Transactions of today and the N days before it, from 1 to 365. `1` is today and yesterday. Not used when `year` is set |
| `year` | integer | — | Every transaction of one calendar year, 1 January to 31 December, for example `2024` |
| `teams` | string\[] | `[]` | Team abbreviations, such as `KC`, `LAL`, `NYY`, `TOR`, or team names, such as `Kansas City Chiefs`, `Lakers` or `Red Sox`. Case does not matter. An abbreviation that more than one league uses, such as `DAL`, matches in every league you selected |
| `players` | string\[] | `[]` | Player names. Part of a name is enough, and case does not matter |

#### Input examples

**This week's NFL transactions**

```json
{
  "leagues": ["nfl"]
}
```

**Today's and yesterday's moves in all five leagues**

```json
{
  "leagues": ["nfl", "nba", "mlb", "nhl", "wnba"],
  "days": 1
}
```

**The Kansas City Chiefs, last 30 days**

```json
{
  "leagues": ["nfl"],
  "teams": ["KC"],
  "days": 30
}
```

**Every New York Yankees move of 2024**

```json
{
  "leagues": ["mlb"],
  "year": 2024,
  "teams": ["Yankees"]
}
```

**Every move that names one player in the last year**

```json
{
  "leagues": ["nfl", "nba", "mlb", "nhl", "wnba"],
  "days": 365,
  "players": ["rodgers"]
}
```

### Output

You get one row per transaction, newest first. The **Output** tab shows them as a table with the date, league, team and transaction.

```json
{
  "recordType": "transaction",
  "league": "mlb",
  "leagueName": "MLB",
  "sport": "baseball",
  "team": {
    "id": "10",
    "name": "New York Yankees",
    "abbreviation": "NYY"
  },
  "description": "Agreed to terms with RHP Jonathan Loáisiga on a one-year contract.",
  "date": "2024-12-21T08:00Z",
  "dateLocal": "2024-12-21T03:00:00.000-05:00",
  "retrievedAt": "2026-09-29T15:36:42.610Z"
}
```

#### Output fields

| Field | Description |
|-------|-------------|
| `league`, `leagueName`, `sport` | The league, such as `nfl` and `NFL`, and the sport |
| `team.id`, `team.name`, `team.abbreviation` | The team that made the move. `team.id` is the ESPN team ID |
| `description` | The transaction, with the players, their positions and the other team, such as "Traded WR A.J. Brown to New England for a 2028 first-round pick" |
| `date` | The day of the transaction, as a UTC timestamp |
| `dateLocal` | The same day in US Eastern time, the time zone that the leagues report in |
| `retrievedAt` | When the data was collected. The same value for every row of one run |

### Use the scraper with the Apify API

You can run the scraper and read the results from any programming language with the [Apify API](https://docs.apify.com/api/v2). Get your API token in Apify Console under **Settings → API & Integrations**, and replace `<YOUR_API_TOKEN>` below.

**JavaScript / Node.js**

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

const run = await client.actor('hgservices/espn-transactions-scraper').call({
    leagues: ['nfl', 'nba'],
    days: 3,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const move of items) {
    console.log(move.dateLocal.slice(0, 10), move.team.abbreviation, move.description);
}
```

**Python** (`apify-client` 3.0 or later)

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run = client.actor("hgservices/espn-transactions-scraper").call(run_input={
    "leagues": ["mlb"],
    "year": 2024,
    "teams": ["NYY", "BOS"],
})
if run is None:
    raise RuntimeError("The run was not found.")

for move in client.dataset(run.default_dataset_id).iterate_items():
    print(move["date"][:10], move["team"]["abbreviation"], move["description"])
```

**cURL** — run the scraper and get the results in one call:

```bash
curl -X POST "https://api.apify.com/v2/acts/hgservices~espn-transactions-scraper/run-sync-get-dataset-items?format=json" \
  -H "Authorization: Bearer <YOUR_API_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ "leagues": ["nhl"], "days": 7, "teams": ["TOR"] }'
```

Change `format=json` to `format=csv` or `format=xlsx` to get a spreadsheet.

### Use sports transactions in Claude, ChatGPT and other AI assistants

This scraper works as a tool for AI assistants through the [Apify MCP server](https://mcp.apify.com/). Your assistant can find the scraper, read its input options, run it, and use the transactions in its answer.

**Claude (claude.ai or Claude Desktop)** — Go to **Settings → Connectors**, add a custom connector, and enter `https://mcp.apify.com`. Sign in to Apify when Claude asks.

**Claude Code**

```bash
claude mcp add --transport http apify https://mcp.apify.com
```

**ChatGPT** — Turn on **Developer mode** in **Settings → Apps & Connectors → Advanced settings**. Then create a connector with the MCP server URL `https://mcp.apify.com`.

**Cursor, VS Code and other MCP clients** — Add `https://mcp.apify.com` as a remote MCP server. To give the assistant only this scraper, use `https://mcp.apify.com?tools=hgservices/espn-transactions-scraper`.

Then ask in plain language:

> Use the ESPN Transactions Scraper to list every NFL player placed on injured reserve this week.

> Which NBA players signed two-way contracts in the last 30 days?

> Summarize the Toronto Maple Leafs' roster moves this month, and tell me who was recalled from the AHL.

For the best results, tell the assistant the league, the number of days and the team. This keeps the run fast and the cost low.

### Integrations and scheduling

Connect the scraper to the tools you already use with [Apify integrations](https://apify.com/integrations): **Google Sheets, Slack, Discord, Zapier, Make, n8n, Airbyte, Keboola, GitHub** and more. You can also use **webhooks** to call your own endpoint when a run finishes.

Use **Schedules** in Apify Console to run the scraper automatically:

| Use case | Cron | Input |
|----------|------|-------|
| Transaction wire, every 6 hours | `0 */6 * * *` | `days: 1` |
| Daily digest, every morning | `0 9 * * *` | `days: 1` |
| Weekly team report, every Monday | `0 8 * * 1` | `days: 7`, `teams: ["KC"]` |
| Year archive, every 2 January | `0 6 2 1 *` | `year` set to the year that ended |

### Run summary

Every run saves a `SUMMARY` record in the key-value store. It gives the number of transactions for each league, the period and the filters. If a league could not be read, it is named in `failedLeagues`, and the other leagues are still saved.

```json
{
  "totalTransactions": 8636,
  "transactionsByLeague": { "nfl": 2649, "nba": 453, "mlb": 3578, "nhl": 1833, "wnba": 123 },
  "transactionsBeforeFilters": 8636,
  "leagues": ["nfl", "nba", "mlb", "nhl", "wnba"],
  "failedLeagues": [],
  "period": { "days": 365 },
  "filters": { "teams": [], "players": [] },
  "retrievedAt": "2026-09-29T15:35:49.604Z"
}
```

### How much does it cost to scrape sports transactions?

See the **Pricing** tab for the current price. Every Apify account gets free monthly platform credit, which is more than enough to try the scraper.

A week of transactions for one league finishes in a few seconds. A full year of all five leagues is about 9,000 rows and finishes in about 10 seconds. The default memory of 256 MB is enough for every run, so you do not need to change it.

### Data notes

- **The player is named only in the text.** ESPN writes the players into `description`, often several in one transaction. Use the **Players** filter to find a player's moves.
- **Dates have no time of day.** ESPN gives the day of each transaction only.
- **A year is a calendar year.** `year: 2025` returns 1 January to 31 December 2025. For a season that crosses New Year, such as the NBA or the NHL, run two years, or use **Lookback (days)**.

### FAQ

**Do I need an ESPN account or an API key?**
No. You need only an Apify account.

**How quickly does a new transaction appear?**
As soon as ESPN publishes it, usually on the same day. Schedule the scraper every few hours for a near-live feed.

**Why did my run return no rows?**
Usually there were no moves in your period, or the team did not match. The run log names the teams that had transactions, so you can check the abbreviation or the name.

**Can I get the transactions of one player?**
Yes. Put part of the name in **Players**, for example `mahomes`. Use a surname that is not too common, or add a team filter.

**Can I combine this data with scores and schedules?**
Yes. The [ESPN Sports Scores & Schedules](https://apify.com/hgservices/apify-actor-espn) scraper uses the same `league` codes and the same `team` fields, so the datasets join directly.

**Is it legal to scrape sports transactions?**
This scraper collects only public information and never signs in. You are responsible for how you use the data, and for the terms of use of the data source.

### Related scrapers

- [ESPN Sports Scores & Schedules](https://apify.com/hgservices/apify-actor-espn) — scores, schedules, venues and broadcasts for the NFL, NBA, MLB, NHL, college sports and more.

### Support

Did you find a bug, or do you need a field or a league that is not here? Open an issue on the **Issues** tab. Custom solutions are available on request.

*This scraper uses public data from ESPN. It is not affiliated with, endorsed by, or sponsored by ESPN.*

# Actor input Schema

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

The leagues to get transactions for.

## `days` (type: `integer`):

Get the transactions of today and the N days before it, in US Eastern time. 1 is today and yesterday. Not used when Year is set.

## `year` (type: `integer`):

Get every transaction of one calendar year (1 January to 31 December), for example 2024. Leave empty to use Lookback (days).

## `teams` (type: `array`):

Only return these teams. Use the abbreviation (KC, LAL, NYY) or the team name (Kansas City Chiefs, Lakers, Red Sox). Not case-sensitive. Leave empty for every team. An abbreviation that several leagues use (DAL, NY) matches every league you selected.

## `players` (type: `array`):

Only return transactions that name one of these players. Part of a name is enough, for example 'mahomes'. Not case-sensitive.

## Actor input object example

```json
{
  "leagues": [
    "nfl"
  ],
  "days": 7
}
```

# Actor output Schema

## `transactions` (type: `string`):

No description

## `summary` (type: `string`):

No description

# 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 = {
    "leagues": [
        "nfl"
    ],
    "days": 7
};

// Run the Actor and wait for it to finish
const run = await client.actor("hgservices/espn-transactions-scraper").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 = {
    "leagues": ["nfl"],
    "days": 7,
}

# Run the Actor and wait for it to finish
run = client.actor("hgservices/espn-transactions-scraper").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 '{
  "leagues": [
    "nfl"
  ],
  "days": 7
}' |
apify call hgservices/espn-transactions-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hgservices/espn-transactions-scraper"
        }
    }
}
```

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/5CkTfmoRrBYwPYioC/builds/jWiLftKi0mjXY19tQ/openapi.json
