# Sherdog Scraper - UFC & MMA Fight Stats, Records & Events API (`parseforge/sherdog-scraper`) Actor

Extract public Sherdog data: UFC and MMA fighter records with method breakdowns, full bout-by-bout fight history, and entire event cards for finished and upcoming shows.

- **URL**: https://apify.com/parseforge/sherdog-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** AI, Automation, News
- **Stats:** 26 total users, 8 monthly users, 69.6% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $18.75 / 1,000 results

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/platform/actors/running/actors-in-store#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

[![ParseForge](https://raw.githubusercontent.com/ParseForge/apify-assets/main/banner.jpg)](https://apify.com/parseforge?fpr=vmoqkp)

### Sherdog Scraper - UFC & MMA Fight Stats, Records & Events API

Scrape complete MMA records from Sherdog by fighter, by name, or by event card. Every bout comes with the opponent, result, method, round, finish time, and the referee where Sherdog lists one; every fighter comes with the full career record and the win/loss breakdown by KO, submission, and decision. No login or API key. Export to CSV, JSON, Excel, or XML.

There is no official Sherdog API. The Fight Finder is the sport's most complete public record — every promotion, not just the UFC — and it exists only as HTML. This reads those pages directly and returns each bout in one fixed schema.

| Who uses it | What they scrape Sherdog for |
| --- | --- |
| MMA analytics and modelling | Finish rates, method distributions, and round-length features across a whole division |
| Betting and odds shops | Both fighters' complete records the moment a card is announced |
| Sports media and stat sites | Fighter pages and card previews that stay current without manual entry |
| Fantasy MMA products | A full event card, upcoming bouts included, in a single run |
| Gyms, managers, matchmakers | Opponent history, activity, and how a prospect's wins actually came |

### What it does

This Actor collects MMA data by fighter URL, fighter name, event URL, or by browsing Sherdog's Fight Finder by division and gym, and returns each result as a flat row. Two shapes, chosen with one setting:

🥊 **Fights** — one row per bout: opponent, result, method and detail, round, time in seconds, event, ISO date, and the referee where one is on record.

👤 **Fighter profiles** — one row per fighter: career record with draws and no contests, plus wins and losses broken out by KO, submission, decision, and other. `draws` and `noContests` appear only for fighters who have them.

Every run also gives you:

- 📅 **Event cards in full**: main event and every undercard bout, with weight class, card position, and title-fight flag.
- 🔮 **Upcoming bouts**: announced fights come back with `result: "upcoming"` and empty method fields, never invented results.
- 🧬 **Parsed methods**: `"TKO (Spinning Back Kick and Punches)"` splits into `method` and `methodDetail`, so you can group by finish type without string surgery.
- 🥋 **Amateur records**: tagged `fightType: "amateur"` and switchable off, so they never contaminate a pro-record analysis.
- 📇 **Bio and gym data**: nationality, birthplace, birth date, height and weight in both unit systems, weight class, and every gym the fighter is listed with.
- 🔎 **Browse by division and gym**: `weightClass` and `association` filter a name search, or on their own turn Fight Finder into a directory — every heavyweight, or the whole American Top Team roster.

Results export to CSV, JSON, Excel, or XML, or stream from the API.

### What you can do with Sherdog data

📊 **Model finishes, not just wins.**

Pull a division's fighters and read how each win actually came — KO, submission, or decision — with the round and the second it ended.

🎯 **Prep a card in one run.**

Feed an event URL and get every bout on the card, with weight classes, card positions, and title-fight flags before the broadcast opens.

📈 **Track a prospect's activity.**

A fighter's full history with ISO dates shows layoffs, step-ups in competition, and who they actually beat.

🧠 **Build MMA datasets.**

Thousands of bouts with consistent method, round, and time fields make a clean corpus for prediction models.

### Why choose this scraper

| What you get | |
| --- | --- |
| Three inputs, one run | Fighter URLs, fighter names, and event URLs together, in one fixed schema. |
| Beyond the UFC | Sherdog records every promotion — ONE, PFL, RIZIN, LFA, Oktagon, Shooto, ACA, and the regional shows the UFC-only databases never touch. |
| Methods already split | `method` and `methodDetail` as separate fields, plus `timeSeconds` alongside `4:29`, plus a `methodCategory` bucket and an `isFinish` flag you can filter and count on. |
| Career breakdowns | Wins and losses by KO, submission, decision, and other — computed by Sherdog, read verbatim. A breakdown field is absent when Sherdog renders no bar for it, which means zero. |
| Rates and streaks, precomputed | `finishRate`, `koRate`, `submissionRate`, `winRate`, `currentStreak`, `debutDate` and `daysSinceLastFight` — the numbers you would otherwise write a script to derive. |
| Career sequence per bout | `fightNumber` and `daysSincePreviousFight` on every row, so a layoff or a debut is a column and not a join. |
| Venue split into columns | `venue`, `city`, `region` and `country` instead of one comma-joined string. |
| Filters that cut the bill | Date range, result, method, promotion, title fights and finishes. Filtered rows are never saved and never charged. |
| Upcoming fights included | Announced bouts on both fighter profiles and event cards. |
| Honest empties | A missing referee or weight class is absent, never a guessed value. |
| Four export formats | CSV, JSON, Excel, and XML, from the dashboard or the API. |

### How it compares

There is no other Sherdog scraper on Apify — the MMA actors in the Store are built on UFC sources. That matters when the fight you need is from Bellator, PFL, KSW or a regional card: those records exist on Sherdog and mostly not on the alternatives.

The competitor columns below reflect what each Actor's own public listing states, not a test run of it.

| Feature | ParseForge | crawlerbros | lemur | jenko\_systems | solidcode |
| --- | --- | --- | --- | --- | --- |
| Promotions covered | Every promotion Sherdog records | UFC, via ESPN's API | UFC | UFC, Bellator, PFL, Invicta, Rizin | UFC |
| Live or historical | Live, including announced future bouts | Live | Live | Historical set, 11,720 fights | Live |
| Target one exact fighter or event by URL | Yes, resolved by numeric id | Search and browse | API endpoints | Fixed dataset | Not stated |
| Whole event card, main plus undercard | Yes, with card order | Not stated | Yes | Historical fights | Yes |
| Amateur records | Yes, tagged separately | Not stated | Not stated | Not stated | Not stated |
| Method split into type, detail and `timeSeconds` | Yes | Not stated | Not stated | Not stated | Not stated |
| Rates and streaks computed for you | `finishRate`, `koRate`, `winRate`, `currentStreak`, `daysSinceLastFight` | Not stated | Not stated | Not stated | Not stated |
| Career position on every bout | `fightNumber` and `daysSincePreviousFight` | Not stated | Not stated | Not stated | Not stated |
| Filter before you pay | Date, result, method, promotion, title fights, finishes | Not stated | Not stated | Fixed dataset | Not stated |
| Price per result | $0.025 | $0.005 | $0.055 | $0.001 | $0.036 |

If you only ever need UFC, the cheaper UFC-specific actors will serve you well — including our own [UFCStats Fighter Profile & Fight History Scraper](https://apify.com/parseforge/ufcstats-scraper?fpr=vmoqkp). Come here when the promotion is not the UFC, or when you need a named card pulled end to end.

### What a fight looks like

Every bout returns as one flat JSON row. Here is a real record, unedited:

```json
{
  "fighter": "Jon Jones",
  "fighterUrl": "https://www.sherdog.com/fighter/Jon-Jones-27944",
  "fighterId": "27944",
  "fighterRecord": "28-1-0",
  "opponent": "Stipe Miocic",
  "opponentUrl": "https://www.sherdog.com/fighter/Stipe-Miocic-39537",
  "opponentId": "39537",
  "opponentRecord": "20-5-0",
  "result": "win",
  "fightType": "pro",
  "eventName": "UFC 309 - Jones vs. Miocic",
  "eventUrl": "https://www.sherdog.com/events/UFC-309-Jones-vs-Miocic-103896",
  "eventId": "103896",
  "eventDate": "2024-11-16T00:00:00.000Z",
  "organization": "Ultimate Fighting Championship (UFC)",
  "location": "Madison Square Garden, New York, New York, United States",
  "weightClass": "Heavyweight",
  "matchNumber": 12,
  "isMainEvent": true,
  "isTitleFight": true,
  "method": "TKO",
  "methodDetail": "Spinning Back Kick and Punches",
  "referee": "Herb Dean",
  "refereeUrl": "https://www.sherdog.com/referee/Herb-Dean-5",
  "round": 3,
  "time": "4:29",
  "timeSeconds": 269,
  "source": "event",
  "scrapedAt": "2026-08-18T18:59:53.321Z"
}
```

And a fighter profile:

```json
{
  "fighterId": "27944",
  "name": "Jon Jones",
  "nickname": "Bones",
  "nationality": "United States",
  "birthplace": "Rochester, New York",
  "birthDate": "1987-07-19T00:00:00.000Z",
  "age": 39,
  "height": "6'4\"",
  "heightCm": 193.04,
  "weight": "238 lbs",
  "weightKg": 107.95,
  "weightClass": "Heavyweight",
  "association": "Jackson-Wink MMA",
  "wins": 28,
  "losses": 1,
  "noContests": 1,
  "totalFights": 30,
  "winsByKo": 11,
  "winsBySubmission": 7,
  "winsByDecision": 10,
  "winsByOther": 0,
  "lossesByKo": 0,
  "lossesBySubmission": 0,
  "lossesByDecision": 0,
  "lossesByOther": 1,
  "proFightCount": 30,
  "imageUrl": "https://www.sherdog.com/image_crop/200/300/_images/fighter/20220331052526_Jon_Jones_ff.JPG",
  "associationUrl": "https://www.sherdog.com/stats/fightfinder?association=Jackson-Wink+MMA",
  "url": "https://www.sherdog.com/fighter/Jon-Jones-27944",
  "scrapedAt": "2026-08-18T18:59:53.321Z"
}
```

Not every field exists on every source, because Sherdog does not publish the same things everywhere. Measured on real runs:

| Field | Fighter history rows | Event card rows |
| --- | --- | --- |
| `opponent`, `result`, `method`, `methodDetail`, `round`, `time`, `eventDate` | 100% | 100% |
| `referee` | ~83% — older and regional bouts often have none on record | 100% |
| `weightClass`, `organization`, `location`, `matchNumber`, `isTitleFight` | not in Sherdog's history table | 100% |
| `fighterRecord`, `opponentRecord` | not in Sherdog's history table | main event always; undercard only on **upcoming** cards |

That last row is Sherdog's own layout: a finished undercard shows each fighter's result where an upcoming one shows their record. Feed the `eventUrl` values from a history run back in as `eventUrls` when you need the card-level fields.

### Configure the run

Drive the Actor from four source types, alone or together: fighter URLs, fighter names, event URLs, and a `weightClass`/`association` browse. `resultType` decides whether you get bouts or profiles. The Input tab lists every parameter.

A fighter's complete record:

```json
{ "fighterUrls": ["https://www.sherdog.com/fighter/Jon-Jones-27944"], "resultType": "fights", "maxItems": 100 }
```

A whole event card, main event and undercard:

```json
{ "eventUrls": ["https://www.sherdog.com/events/UFC-309-Jones-vs-Miocic-103896"], "resultType": "fights" }
```

Career records for every fighter on a card, plus one fighter by name:

```json
{ "fighterNames": ["Amanda Nunes"], "eventUrls": ["https://www.sherdog.com/events/UFC-309-Jones-vs-Miocic-103896"], "resultType": "fighters", "maxItems": 50 }
```

Professional bouts only, amateur record excluded:

```json
{ "fighterUrls": ["https://www.sherdog.com/fighter/Trent-Miller-382805"], "includeAmateurFights": false }
```

Browse a whole roster with no fighter named at all — every heavyweight listed with American Top Team:

```json
{ "weightClass": "Heavyweight", "association": "American Top Team", "resultType": "fighters", "maxItems": 100 }
```

Sherdog matches `association` partially, so `American Top Team` also returns its affiliates, and it matches **any** gym a fighter is listed with. A fighter whose primary `association` reads `Gym 23` can still belong in an American Top Team run — the full list is in `associations`.

**Fighter URLs beat fighter names.** Sherdog identifies a fighter by the number at the end of the URL and ignores the name in it — `/fighter/Nick-Diaz-9` serves whoever fighter 9 actually is. Names are resolved through Fight Finder, which matches on the **surname only** and returns 20 alphabetically ordered fighters per page, so a common surname costs extra requests. Only an exact full-name match is accepted; an ambiguous name is reported as a warning rather than resolved to the wrong fighter.

#### Narrow the run with filters

Every filter runs on rows the Actor already extracted, so none of them costs an extra request — and because a filtered row is never saved, it is never charged either. Filtering is the cheapest way to run this Actor.

Every UFC title fight on a card:

```json
{ "eventUrls": ["https://www.sherdog.com/events/UFC-309-Jones-vs-Miocic-103896"], "titleFightsOnly": true }
```

One fighter's finishes since 2015, UFC only:

```json
{ "fighterUrls": ["https://www.sherdog.com/fighter/Jon-Jones-27944"], "organizationFilter": "UFC", "dateFrom": "2015-01-01", "finishesOnly": true }
```

Only submission wins, whatever the promotion:

```json
{ "fighterUrls": ["https://www.sherdog.com/fighter/Jon-Jones-27944"], "resultFilter": ["win"], "methodFilter": ["Submission"] }
```

| Filter | What it keeps |
| --- | --- |
| `dateFrom` / `dateTo` | Bouts inside a `YYYY-MM-DD` range, on event date. |
| `resultFilter` | `win`, `loss`, `draw`, `no contest`, `upcoming`. |
| `methodFilter` | `KO/TKO`, `Submission`, `Decision`, `Other`. |
| `organizationFilter` | Partial, case-insensitive promotion match. Falls back to the event name, which is where the promotion appears in a fighter's history. |
| `titleFightsOnly` | Needs at least one `eventUrl` — Sherdog marks title bouts on event cards only. |
| `finishesOnly` | KO/TKO and submissions; drops decisions, DQs and no contests. |

Two filters depend on data only an event card carries, so asking for them without an `eventUrl` fails immediately with that reason instead of handing you an empty dataset: `titleFightsOnly`, and a `resultFilter` of `upcoming` alone.

#### Add the opponent's profile

`enrichOpponents` fetches every **distinct** opponent's own Sherdog page and folds their nationality, gym, division, height, weight and career record into the fight row.

```json
{ "fighterUrls": ["https://www.sherdog.com/fighter/Jon-Jones-27944"], "enrichOpponents": true, "maxItems": 30 }
```

A rematch costs one fetch, not two — profiles are cached for the run. A record already on the page is never overwritten: `opponentRecord` on an event card is the record **as of that night**, and replacing it with today's would rewrite history, so enrichment only fills the field when it is empty.

### Pricing

Pay-per-event: **$0.025 per result**, dropping to **$0.01875** on the Gold tier, plus a $0.05 run-start fee. You pay only for rows written to your dataset.

| Rows collected | Approximate cost |
| --- | --- |
| 100 | $2.55 |
| 1,000 | $25.05 |
| 10,000 | $250.05 |

At higher monthly volume the per-row rate steps down through $0.022 and $0.0208 to **$0.01875**, so 10,000 rows runs about **$188** rather than $250. New Apify accounts start with $5 in free credit.

#### The full event list

Every event maps to one unit of work the Actor performs. A plain run — fighter URLs or event URLs, no filters, no enrichment — only ever charges the first two.

| Event | Charged when | Price |
| --- | --- | --- |
| Actor start | Once per run. This Actor is capped at 1 GB of memory, so it is always **one** event, never a multiple. | $0.05 |
| Result | Each fight or fighter profile written to your dataset. | $0.025 |
| Fight Finder search | Each 20-result search page read while resolving a name from `fighterNames`, or browsing a `weightClass`/`association`. | $0.005 |
| Opponent profile | Each **distinct** opponent fetched when `enrichOpponents` is on. | $0.015 |

Every event except the start fee follows your Apify plan tier. On Gold that is **$0.01875** per result, **$0.00375** per Fight Finder search and **$0.01125** per opponent profile — a quarter off the prices above.

Three things this list is designed to make true:

- **Passing fighter URLs and event URLs costs nothing beyond start and results.** The two optional events only fire when you ask for the work that triggers them.
- **The search fee has a ceiling you set.** `maxSearchPages` caps the number of Fight Finder pages per name — at the default of 25 that is at most $0.125 for a name, and the search stops early on its own once results sort past the name you asked for.
- **Nothing is charged before it exists.** A result is charged as it is written, a search page after it is read, an opponent profile once it is in hand. A failed request, a Sherdog "Page Not Found" and a row your filters dropped are all free.

### Free users

Free-plan runs return up to 100 rows as a preview. [Upgrade your Apify plan](https://console.apify.com/sign-up?fpr=vmoqkp) to collect up to 100,000 rows per run.

**A run is also bounded by its timeout, and the two input styles work at very different speeds.** Measured through Apify Proxy at the default 900-second timeout: about **1,600 fight rows** when you pass fighter or event URLs, because one page yields around 20 bouts, and about **230 fighter profiles** when you browse a weight class, because that path costs one request per fighter. Raise the timeout in the run options for a bigger job, or split it across scheduled runs.

### Run it

1. [Create a free Apify account with $5 in credit](https://console.apify.com/sign-up?fpr=vmoqkp).
2. Open the [Sherdog Scraper](https://apify.com/parseforge/sherdog-scraper?fpr=vmoqkp).
3. Enter `fighterUrls`, `fighterNames`, or `eventUrls`, pick a `resultType`, add any filters, and click **Start**.
4. Export the results as CSV, Excel, JSON, or XML from the **Dataset** tab.

Run it programmatically through the [Apify API](https://docs.apify.com/api/v2) or the [ApifyClient](https://docs.apify.com/api/client/js) for JavaScript and Python.

### Use with AI agents (MCP)

Give an AI agent live access to MMA records through the Model Context Protocol. Add the Actor to Claude, Cursor, or any MCP client:

```
claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/sherdog-scraper"
```

Then prompt it in plain language:

- "Pull Jon Jones's full Sherdog record and tell me how many wins came by submission."
- "Get the whole UFC 309 card with methods and rounds, and list every finish inside two rounds."
- "Look up Amanda Nunes and Valentina Shevchenko and compare their KO rates."

Copy this into ChatGPT, Claude, or Cursor to start:

```text
Use the Apify Actor "parseforge/sherdog-scraper" to collect MMA data from Sherdog. Input: { "fighterUrls": ["<sherdog fighter URL>"], "fighterNames": ["<full name>"], "eventUrls": ["<sherdog event URL>"], "resultType": "<fights|fighters>", "maxItems": <n> }. With resultType "fights" it returns one row per bout with opponent, result, method and methodDetail, referee, round, timeSeconds, eventName, and ISO eventDate. With "fighters" it returns one row per fighter with the career record including draws and no contests, plus wins and losses broken out by KO, submission, and decision. Prefer fighter URLs over names, since Sherdog identifies fighters by the numeric id at the end of the URL. Call it with the ApifyClient and my APIFY_TOKEN.
```

### Troubleshooting

**Why was my fighter URL skipped?**

Sherdog serves a "Page Not Found" page with an **HTTP 200** status, so a bad id looks like a successful response. The Actor detects it and skips the source with a warning instead of returning an empty dataset. Check the number at the end of the URL — that is the only part Sherdog reads.

**Why couldn't it find my fighter by name?**

Only exact full-name matches are accepted, and Fight Finder searches by surname alone. If the surname is common the fighter may sit past the pages searched — raise `maxSearchPages`, or pass the fighter's URL instead.

**Why fewer rows than I asked for?**

`maxItems` is a ceiling, not a target. A fighter with 12 bouts returns 12 rows. Add more fighters or events to fill a larger run.

**Why is `weightClass`, `referee`, or `fighterRecord` empty?**

Sherdog's fight-history table does not publish weight class, organization, or card position — only event cards do. Referees are missing on many older and regional bouts. And on a finished card, the undercard shows each fighter's result where an upcoming card shows their record, so `fighterRecord` fills for the main event but not for past undercard bouts. That is the source's real state, not a parsing failure.

**Why does a fighter from an `association` run show a different gym?**

Sherdog lists fighters under every gym they are associated with, and the filter matches any of them. `association` holds the primary gym Sherdog shows first; `associations` holds all of them, and that is where the gym you filtered on will be.

**Why is a breakdown field like `winsByOther` missing?**

Sherdog only renders a bar for a category a fighter actually has. Verified across profiles: the categories present always add up exactly to `wins` and `losses`, so a missing breakdown field is a real zero.

**Why do upcoming fights have no method or round?**

They have not happened yet. Announced bouts return `result: "upcoming"` with those fields absent rather than filled with placeholders.

**Why is the run slow?**

Each fighter and each event is one page request, and name lookups add a search page or more each. Pass URLs instead of names, and split large jobs into scheduled runs.

**A field stopped filling.**

Sherdog changed its page markup. Email us with your run ID so we can update the parser.

### FAQ

| Question | Answer |
| --- | --- |
| Do I need a Sherdog account or API key? | No. Sherdog has no public API. This reads public pages, so there is nothing to register or authenticate. |
| Does it cover promotions other than the UFC? | Yes. Sherdog records ONE, PFL, RIZIN, LFA, Oktagon, Shooto, ACA, and regional shows worldwide, and all of them come through the same schema. |
| Can I get a fighter's complete career, not just recent fights? | Yes. The full history table is returned, newest bout first, pro and amateur. |
| Does it handle upcoming events? | Yes. Upcoming cards return with `result: "upcoming"`, and an announced next bout appears on the fighter profile. |
| Can I look fighters up by name? | Yes, with exact full-name matching. Fighter URLs are faster and unambiguous — prefer them when you have them. |
| What is the difference between the two result types? | `fights` gives one row per bout. `fighters` gives one row per fighter with the career record and method breakdown. |
| Does it scrape referees, judges, or scorecards? | Referee yes, on every bout that lists one. Judges and scorecards are not part of Sherdog's public tables. |
| How many rows per run? | Free plan: 100. Paid: up to 100,000, bounded by how many bouts your sources actually contain and by the run timeout — at the default 900 seconds that is roughly 1,600 fight rows from URLs, or 230 profiles when browsing a weight class. |
| Are the records official? | They are Sherdog's records, the sport's most widely cited public database. Sherdog is not a sanctioning body. |
| Is this an official Sherdog product? | No. It is unofficial and reads only public Sherdog data. |

### Related actors

- [UFC Stats Scraper](https://apify.com/parseforge/ufc-stats-scraper?fpr=vmoqkp): official UFC statistics, strikes and takedowns per round.
- [Tapology MMA Fighters Scraper](https://apify.com/parseforge/tapology-mma-fighters-scraper?fpr=vmoqkp): fighter profiles and records from Tapology.
- [ESPN MMA Scraper](https://apify.com/parseforge/espn-mma-scraper?fpr=vmoqkp): UFC scoreboard, news, and team data.
- [DraftKings DFS Scraper](https://apify.com/parseforge/draftkings-scraper?fpr=vmoqkp): contests and player salaries.
- [SofaScore Live Scraper](https://apify.com/parseforge/sofascore-live-scraper?fpr=vmoqkp): live scores and match data across sports.

Browse the full [ParseForge collection](https://apify.com/parseforge?fpr=vmoqkp) for more scrapers.

🆘 **Need help?** Email parseforge@protonmail.com with your run ID, your input, and what you expected.

⚠️ **Disclaimer.** This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by Sherdog.com or its owners. It collects only publicly available Sherdog data. You are responsible for using the data in compliance with Sherdog's terms and applicable laws, including GDPR, CCPA, and PIPL. Fighter records are public sporting results; do not use this data to identify, profile, or target individuals.

# Actor input Schema

## `fighterUrls` (type: `array`):

Sherdog fighter profile URLs, e.g. https://www.sherdog.com/fighter/Jon-Jones-27944. This is the most reliable input — Sherdog identifies a fighter by the number at the end of the URL.

## `fighterNames` (type: `array`):

Full fighter names to look up in Sherdog's Fight Finder, e.g. "Amanda Nunes". Only an exact full-name match is used. Sherdog searches by surname only, so a common surname costs extra requests — pass the fighter URL when you already have it.

## `eventUrls` (type: `array`):

Sherdog event URLs, e.g. https://www.sherdog.com/events/UFC-309-Jones-vs-Miocic-103896. The whole card is scraped, including the main event and every undercard bout. Works for upcoming events too.

## `weightClass` (type: `string`):

Limit the Fight Finder search to one division. On its own, with no fighter name, it browses every fighter Sherdog lists in that division.

## `association` (type: `string`):

Limit the search to one team. Sherdog matches this as a partial name, so "American Top Team" also returns its affiliates. On its own it browses every fighter listed with that team.

## `resultType` (type: `string`):

"Fights" returns one row per bout — the full fight history of each fighter and every bout on each event card. "Fighter profiles" returns one row per fighter, with the career record and method breakdown; in this mode an event URL means "every fighter on this card", which costs one request per fighter.

## `includeAmateurFights` (type: `boolean`):

Sherdog lists amateur bouts in a separate table from the pro record. Turn this off to return professional bouts only. Applies to the "Fights" result type.

## `maxSearchPages` (type: `integer`):

How many 20-result search pages to read when resolving a name. Raise it for common surnames; the search stops early once the results sort past the name you asked for.

## `enrichOpponents` (type: `boolean`):

Fetches every distinct opponent's own Sherdog page and adds their nationality, gym, division, height, weight and career record to the fight row. Costs one extra request and one "Opponent profile" event per distinct opponent, however many times they appear — a rematch is fetched once. Applies to the "Fights" result type.

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

YYYY-MM-DD. Filters on the event date. Rows excluded by a filter are never saved and never charged.

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

YYYY-MM-DD. Filters on the event date.

## `resultFilter` (type: `array`):

Keep only bouts that ended this way. Leave empty for all of them. "Upcoming" only ever appears on event cards, so it needs at least one event URL.

## `methodFilter` (type: `array`):

Sherdog writes the method free-form ("TKO (Spinning Back Kick and Punches)"). Every value is also bucketed into one of these four so you can filter on it. Leave empty for all.

## `organizationFilter` (type: `string`):

Case-insensitive partial match, e.g. "UFC", "Bellator", "PFL". A fighter's history table has no promotion column, so this matches the event name there — which is where the promotion appears.

## `titleFightsOnly` (type: `boolean`):

Sherdog marks title bouts on event cards only, never in a fighter's history table, so this needs at least one event URL. The run fails with that message rather than returning an empty dataset.

## `finishesOnly` (type: `boolean`):

Keep only bouts that ended by KO/TKO or submission. Decisions, DQs and no contests are dropped.

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

Maximum number of rows to save, counted across every source. Free-plan runs are capped at 100 rows.

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

Sherdog rate-limits by IP. Datacenter proxies are enough for most runs; switch to RESIDENTIAL if you start seeing 403s.

## Actor input object example

```json
{
  "fighterUrls": [
    "https://www.sherdog.com/fighter/Jon-Jones-27944"
  ],
  "fighterNames": [
    "Amanda Nunes"
  ],
  "eventUrls": [
    "https://www.sherdog.com/events/UFC-309-Jones-vs-Miocic-103896"
  ],
  "weightClass": "",
  "association": "American Top Team",
  "resultType": "fights",
  "includeAmateurFights": true,
  "maxSearchPages": 25,
  "enrichOpponents": false,
  "dateFrom": "2015-01-01",
  "dateTo": "2024-12-31",
  "resultFilter": [],
  "methodFilter": [],
  "organizationFilter": "UFC",
  "titleFightsOnly": false,
  "finishesOnly": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `fights` (type: `string`):

Every row this run saved.

# 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 = {
    "fighterUrls": [
        "https://www.sherdog.com/fighter/Jon-Jones-27944"
    ],
    "resultType": "fights",
    "includeAmateurFights": true,
    "maxSearchPages": 25,
    "enrichOpponents": false,
    "maxItems": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/sherdog-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 = {
    "fighterUrls": ["https://www.sherdog.com/fighter/Jon-Jones-27944"],
    "resultType": "fights",
    "includeAmateurFights": True,
    "maxSearchPages": 25,
    "enrichOpponents": False,
    "maxItems": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/sherdog-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 '{
  "fighterUrls": [
    "https://www.sherdog.com/fighter/Jon-Jones-27944"
  ],
  "resultType": "fights",
  "includeAmateurFights": true,
  "maxSearchPages": 25,
  "enrichOpponents": false,
  "maxItems": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call parseforge/sherdog-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parseforge/sherdog-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/xSqP1eQASVHWcdNoE/builds/pCfCMgJv5O7OinOf6/openapi.json
