# UFCStats Fighter Profile & Fight History Scraper (`parseforge/ufcstats-scraper`) Actor

Scrapes UFCStats.com fighter profiles and optional full fight histories. Returns each fighter as a flat row with physical attributes, career totals, and per-bout striking and grappling stats.

- **URL**: https://apify.com/parseforge/ufcstats-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** Sports, News, Lead generation
- **Features:** Limited permissions
- **Stats:** 220 total users, 11 monthly users, 100.0% 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/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

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

### UFCStats Fighter Profile & Fight History Scraper

**Scrape UFCStats fighter profiles and complete fight histories, up to a million records per run.** Every fighter row includes physical attributes, career stats, and a full bout-by-bout breakdown with strikes, takedowns, and method of victory. Export to CSV, JSON, Excel, or XML.

UFCStats.com holds the deepest public record of UFC fighter data, but browsing it manually means clicking through alphabet pages and individual profiles one by one. This Actor walks the entire fighter directory, or a targeted subset you define, and pulls every stat into a flat, analysis-ready row. No API key, no rate-limit headaches, structured data from the sport's most detailed archive.

| Who uses it | What they scrape UFCStats for |
|---|---|
| Sports analysts | Building predictive models from career-long striking and grappling data. |
| Fantasy MMA players | Comparing fighter stats to set weekly DraftKings lineups. |
| Content creators | Pulling accurate fight records for pre-fight preview graphics. |
| Bettors | Backtesting betting angles against historical fight outcomes. |

### What it does

This Actor collects UFC fighter profiles from UFCStats.com, including physical attributes, career totals, and optional full fight history, and returns each fighter as a single flat record.

- 🥊 **Full fight history:** every bout with opponent, event, method, round, time, knockdowns, significant strikes, takedowns, and submission attempts.
- 🔤 **Alphabet walk:** start from A and crawl every last name, or restrict to specific letters to target a division.
- 🔍 **Free-text search:** filter by first name, last name, or nickname like 'mcgregor' or 'spider' before a single request fires.
- 📏 **Physical filters:** narrow results to a specific stance (Orthodox, Southpaw, Switch) or minimum career wins and losses.
- 🎯 **Direct URLs:** drop in a list of fighter profile URLs and scrape only those, ignoring the directory walk.

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

### What you can do with UFCStats data

**📊 Build a fighter database.**

A data engineer runs the Actor across all 26 letters once a quarter, dumps the results into a warehouse, and powers a Tableau dashboard the coaching staff uses for opponent scouting.

**💰 Model betting edges.**

A quantitative bettor scrapes every lightweight with 10+ wins, joins the fight history to closing odds, and trains a model on striking differentials that predict underdog upsets.

**🎙️ Prep a fight-week show.**

A podcast producer drops in the two headliner URLs on Monday morning, grabs their full histories, and has the stat pack ready for the hosts by lunch.

**🏆 Run a fantasy league draft.**

A league commissioner scrapes the top 50 fighters by wins, exports a CSV, and lets managers sort by strikes landed per minute to make their picks.

### Why choose this scraper

| | What you get |
|---|---|
| **Career stat totals** | Lifetime wins, losses, draws, and no-contests pulled from the fighter header. |
| **Physical profile** | Height (text and inches), weight in pounds, reach in inches, stance, date of birth and age for every fighter. |
| **Striking breakdown** | Significant strikes landed per minute, accuracy, absorbed per minute, and defense percentage. |
| **Grappling breakdown** | Takedown average, takedown accuracy, takedown defense, and submission average per 15 minutes. |
| **Fight-by-fight detail** | Optional nested array with opponent, event, date, method, round, time, and the full stat line for each bout, both as the site shows it and split into numbers for and against. |

### How it compares

This Actor and the UFC Stats API both pull data from ufcstats.com, but they differ in how you target fighters and what shape the output takes.

| Feature | ParseForge | UFC Stats |
|---|---|---|
| Full fight history per fighter | Yes, optional nested array | Yes |
| Free-text name and nickname search | Yes | Not listed |
| Alphabet walk by last-name letter | Yes | Not listed |
| Post-fetch filters (stance, min wins/losses) | Yes | Not listed |
| Direct fighter URL input | Yes | Not listed |
| Flat row output (CSV, JSON, Excel, XML) | Yes | Not listed |

### Configure the run

Drive the Actor from specific fighter URLs, a free-text name search, or an alphabet walk by last-name letter, and apply filters for stance, minimum wins, and minimum losses so only relevant fighters land in your dataset. The three targeting modes are exclusive: give start URLs and you get exactly those fighters, give a search term and you get exactly what it matches, leave both empty and the Actor walks the directory. The Input tab lists every parameter.

A first run with the defaults:

```json
{
 "maxItems": 10,
 "proxyConfiguration": {
 "useApifyProxy": true
 }
}
```

A larger pull:

```json
{
 "maxItems": 200,
 "proxyConfiguration": {
 "useApifyProxy": true
 }
}
```

### Pricing

Pay-per-result: **$0.025 per result** collected. You pay only for the results written to your dataset.

| Results collected | Approximate cost |
|---|---|
| 100 results | $2.50 |
| 1,000 results | $25.00 |
| 10,000 results | $250.00 |

#### Optional extras (from 3 October 2026)

The fight history is optional and priced on its own, so a run that only needs fighter profiles pays only for the rows.

| Event | Price | Charged when |
|---|---|---|
| `fight-history` | $0.01 per fighter | the row carries the fighter's bout record |

New Apify accounts start with $5 in free credit.

### Free users

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

### Run it

1. [Create a free Apify account with $5 in credit](https://console.apify.com/sign-up?fpr=vmoqkp).
2. Open the [UFCStats Fighter Profile & Fight History Scraper](https://apify.com/parseforge/ufcstats-scraper?fpr=vmoqkp).
3. Set your inputs and any filters, then 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) (`run-sync-get-dataset-items`) 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 UFCStats through the Model Context Protocol. Add the Actor to Claude, Cursor, or any MCP client:

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

Then prompt it in plain language to run the scraper and read back the results.

### Troubleshooting

**Why am I getting zero results?**

Read the run status message: it names the reason. A search that UFCStats cannot match, start URLs that are not fighter profiles, and filters that nothing passes each produce their own message. If you set a minimum wins or losses filter, try lowering it, and confirm the letters array includes the starting letter of the fighters you expect.

**The run stopped early with fewer records than maxItems.**

The Actor stops when it exhausts the fighters matching your filters. If you set letters to only 'x' and minWins to 20, there may be fewer fighters than your maxItems value. Broaden the letters or lower the win threshold.

**Some fighter profiles are missing data fields.**

UFCStats occasionally has incomplete profiles, especially for older or recently debuted fighters. Missing fields appear as null or empty strings in the output. This is expected behavior reflecting the source data.

**I am getting timeout errors.**

UFCStats can be slow during high-traffic periods. The Actor retries failed requests automatically. If timeouts persist, increase the run memory to 2 GB or switch to residential proxies in the proxy configuration.

**The fight history array is empty even though the fighter has bouts.**

Ensure the includeFightHistory toggle is set to true. If it is and the array is still empty, the fighter's detail page on UFCStats may have a non-standard layout. Try scraping that fighter by direct URL in a separate run.

### FAQ

| Question | Answer |
|---|---|
| Does this scrape every fighter on UFCStats? | Yes. If you leave the start URLs and search query empty and set letters to all A through Z, the Actor walks the full directory. Set maxItems to cap the total records returned. |
| Can I get the fight history for each fighter? | Yes. The includeFightHistory toggle is on by default and attaches a nested array with every bout, including opponent, event, method, round, time, and detailed striking and grappling stats. |
| How do I scrape only one weight class? | UFCStats does not expose a weight-class filter on its directory pages. The best approach is to scrape all fighters and filter the resulting dataset by weight class in your own code, or use the stance and min-wins filters to narrow the pool before export. |
| What proxy do I need? | The Actor defaults to Apify datacenter proxies, which work reliably for ufcstats.com. It rotates sessions and falls back to a direct connection if the proxy fails, so you rarely need to change this setting. |
| Can I search by nickname? | Yes. The searchQuery field matches against first name, last name, and nickname. Searching 'spider' returns Anderson Silva, and 'bones' returns Jon Jones. |
| Can I search a full name like 'Jon Jones'? | Yes. UFCStats itself only matches one name at a time and returns nothing for a full name, so the Actor searches each part separately and keeps the fighters that match all of them. |
| What happens if my search matches nothing? | The run ends with zero results and a status message saying so. It never substitutes fighters you did not ask for, and zero results cost you nothing. |
| How fast does it run? | The Actor processes fighters sequentially and retries with backoff when UFCStats or the proxy fails. A full A-Z walk of several thousand fighters typically completes in under an hour on a standard memory allocation. Raise the run timeout in Run options for large walks: the Actor stops and delivers what it has shortly before the timeout rather than being killed. |
| What output formats are supported? | Your dataset can be exported to CSV, JSON, Excel, or XML directly from the Apify run console. |
| Does it include fighter photo URLs? | No. UFCStats does not publish fighter photos, so there is no image field to return. |
| Can I scrape only specific fighters by URL? | Yes. Paste one or more fighter detail URLs into the startUrls field, and the Actor scrapes only those profiles, ignoring the directory walk and search. |
| What happens if a fighter has no fights listed? | The career totals will show zeros, and the fight history array will be empty. The record still appears in your dataset with the fighter's physical attributes populated. |

### Related sports data actors

Other ParseForge sports data actors:

- [Sherdog Scraper](https://apify.com/parseforge/sherdog-scraper?fpr=vmoqkp): MMA fighter records, bout-by-bout history and full event cards.
- [ESPN MMA UFC Scraper](https://apify.com/parseforge/espn-mma-scraper?fpr=vmoqkp): MMA fight results, UFC news and athlete records from ESPN.
- [Tennis Abstract Scraper](https://apify.com/parseforge/tennis-abstract-scraper?fpr=vmoqkp): every match in a player's history, with surface, round, rank, opponent and score.
- [TennisExplorer Match Results Scraper](https://apify.com/parseforge/tennisexplorer-scraper?fpr=vmoqkp): match results by date and tour, with set scores and odds.
- [MLB Stats Scraper](https://apify.com/parseforge/mlb-stats-scraper?fpr=vmoqkp): official MLB schedules, rosters, player stats and live game detail.

### Related actors

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 UFCStats.com. It collects only publicly available data. You are responsible for using the collected data in compliance with the source's terms of service and applicable data-protection laws, including GDPR, CCPA, and PIPL. Do not use it to collect personal data unlawfully.

# Actor input Schema

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

How many fighter records to collect per run. A targeted run is never padded up to this number: it is a cap, not a target.

## `startUrls` (type: `array`):

Specific fighter profile URLs to scrape, e.g. https://ufcstats.com/fighter-details/f4c49976c75c5ab2. When set, ONLY these fighters are scraped: the search and the alphabet walk stay off, so the run returns at most as many rows as URLs you give. Event and fight URLs are not fighter profiles and are reported as skipped.

## `searchQuery` (type: `string`):

Search UFCStats by first name, last name or nickname, e.g. 'mcgregor', 'silva', 'spider'. UFCStats matches one name at a time, so a full name such as 'Jon Jones' is searched part by part and only the fighters matching every part are kept. When set, the alphabet walk stays off: a search that matches nothing returns zero rows and says so rather than returning other fighters.

## `letters` (type: `array`):

Restrict the alphabet walk to these starting letters of the fighter last name. Leave empty to walk A through Z. Ignored when start URLs or a search term are given.

## `stance` (type: `string`):

Only return fighters with this stance. Leave empty for all stances. Applied from the directory listing where possible, so non-matching fighters are not fetched or charged.

## `minWins` (type: `integer`):

Only include fighters with at least this many career wins. Applied from the directory listing where possible, so non-matching fighters are not fetched or charged.

## `minLosses` (type: `integer`):

Only include fighters with at least this many career losses. Applied from the directory listing where possible, so non-matching fighters are not fetched or charged.

## `includeFightHistory` (type: `boolean`):

Include the full per-fight history table (opponent, event, method, round, time, KDs, strikes, takedowns, submissions) on each fighter record.

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

Proxy configuration for requests. Defaults to Apify datacenter proxy, which works well for ufcstats.com. The scraper rotates proxy sessions and falls back to a direct connection automatically if the proxy fails.

## Actor input object example

```json
{
  "maxItems": 10,
  "stance": "",
  "includeFightHistory": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `results` (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 = {
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/ufcstats-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 = {
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/ufcstats-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 '{
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call parseforge/ufcstats-scraper --silent --output-dataset

```

## MCP server setup

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