UFC Statistics Scraper
Pricing
Pay per event
UFC Statistics Scraper
Export UFCStats events, bout results and detailed fight statistics, plus fighter profiles, records, career rates, and fight histories as normalized JSON.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Stas Persiianenko
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
5 days ago
Last modified
Categories
Share
Export normalized UFC statistics from UFCStats as event, fight, or fighter records. Collect event schedules and results, bout participants and outcome summaries, detailed fight totals and significant-strike splits, or fighter profiles, career rates, records, and fight histories.
The Actor is designed for sports analysts, MMA publishers, researchers, and data teams that need repeatable UFC stats without maintaining a session bootstrap and HTML parser.
What can you extract?
Choose one record type per run:
- Events — event name, date, location, status, source ID and URL, plus the full bout card when details are enabled.
- Fights — participants, W/L result, weight class, method, round, time, referee, aggregate totals, and significant strikes by target and position.
- Fighters — name, nickname, record, height, weight, reach, stance, date of birth, career statistics, and fight history.
Every record includes a stable UFCStats ID, canonical source URL, recordType, and collection timestamp.
Who is this UFC stats scraper for?
- MMA analysts building bout and fighter datasets
- Sports publishers preparing event previews and result pages
- Researchers comparing striking, grappling, and outcome data
- Data engineers loading recurring UFCStats exports into a warehouse
- Automation builders monitoring event cards or fighter records on a schedule
Why use this Actor?
UFCStats presents useful public data across separate event, fight, and fighter pages. It also uses a first-party browser-check session. This Actor handles that bounded session bootstrap, validates page shapes, follows stable source IDs, and converts the tables into typed JSON.
It uses direct HTTP rather than a browser or paid proxy. Requests retry only transient failures, and an upstream challenge or parser change fails visibly instead of producing a misleading empty result.
Input parameters
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | events | Return events, fights, or fighters. |
eventStatus | string | completed | Discover completed, upcoming, or all events. Used by event and fight discovery. |
fighterSearch | string | empty | Full or partial fighter name in fighter mode. |
startUrls | array | empty | Optional UFCStats event, fight, or fighter detail URLs. |
fromDate | string | empty | Inclusive event date in YYYY-MM-DD format. |
toDate | string | empty | Inclusive event date in YYYY-MM-DD format. |
includeDetails | boolean | true | Include bout cards, fight stat tables, or fighter fight histories. |
maxItems | integer | 10 | Maximum primary records, from 1 to 5,000. |
Only ufcstats.com URLs are accepted. An event URL in fight mode expands into its bouts. Date filters apply to both discovered and explicit event inputs.
Getting started
- Open the Actor input page.
- Select Events, Fights, or Fighter profiles.
- Optionally enter a fighter name, date range, or specific UFCStats URLs.
- Set the maximum number of records.
- Run the Actor.
- Download the default dataset as JSON, CSV, Excel, XML, or another supported Apify format.
A useful first run is:
{"mode": "events","eventStatus": "completed","includeDetails": true,"maxItems": 5}
Real output examples
A fight record has this shape:
{"recordType": "fight","sourceId": "c13dc0cccef263f7","url": "http://ufcstats.com/fight-details/c13dc0cccef263f7","fighters": [{"id": "c814b4c899793af6","name": "Rafael Fiziev","result": "W"},{"id": "2e7878927067fdca","name": "Manuel Torres","result": "L"}],"weightClass": "Lightweight","method": "KO/TKO","round": 2,"time": "0:15","totals": {"Rafael Fiziev": {"KD": "1","Sig. str.": "25 of 39","Td": "2 of 2"}}}
Event and fighter records use the same default dataset but expose fields appropriate to their recordType. Fields unavailable on UFCStats are returned as null or omitted.
How much does it cost to export UFC statistics?
The Actor uses pay-per-event pricing:
- a one-time $0.005 start fee per run;
- an item charge for each event, fight, or fighter record saved to the dataset.
At the BRONZE tier the item price is $0.04516 per record. For example:
| Records | BRONZE calculation | Approximate charge |
|---|---|---|
| 1 | 0.005 + 1 × 0.04516 USD | 0.05016 USD |
| 10 | 0.005 + 10 × 0.04516 USD | 0.45660 USD |
| 100 | 0.005 + 100 × 0.04516 USD | 4.52100 USD |
| 1,000 | 0.005 + 1,000 × 0.04516 USD | 45.16500 USD |
Higher subscription tiers receive lower per-record prices. Apify platform compute usage is included through the Actor's pay-per-event model; the displayed run charge is governed by your active pricing tier.
Schedule event and fighter monitoring
Create an Apify Schedule with a stable input, such as a completed-events export or a fighter name. Store each run's dataset in your destination and compare stable id fields to detect:
- newly listed events;
- changes to an upcoming card;
- completed bout outcomes;
- additions to a fighter's history;
- changes to a displayed fighter record or career rate.
The Actor itself returns current public UFCStats records. It does not send alerts or maintain a historical change database.
Integrations and export workflows
Send results to:
- Google Sheets for editorial planning;
- a database or warehouse for sports analysis;
- webhooks for downstream enrichment;
- Make, Zapier, or n8n for no-code workflows;
- Python, R, or notebooks for model and visualization work.
Use stable source IDs for deduplication. Keep scrapedAt as collection metadata rather than an event timestamp.
Run with the Apify API
cURL
curl -X POST \"https://api.apify.com/v2/acts/automation-lab~ufc-events-fights-fighters/runs?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"mode":"fighters","fighterSearch":"Anthony Hernandez","maxItems":1}'
JavaScript
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation-lab/ufc-events-fights-fighters').call({mode: 'fights',eventStatus: 'completed',includeDetails: true,maxItems: 10,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python
from apify_client import ApifyClientimport osclient = ApifyClient(os.environ['APIFY_TOKEN'])run = client.actor('automation-lab/ufc-events-fights-fighters').call(run_input={'mode': 'events','eventStatus': 'upcoming','includeDetails': True,'maxItems': 10,})items = client.dataset(run['defaultDatasetId']).list_items().itemsprint(items)
Use with Apify MCP
Add the Actor to Claude Code:
claude mcp add --transport http apify \"https://mcp.apify.com?tools=automation-lab/ufc-events-fights-fighters"
Claude Desktop, Cursor, and VS Code
Claude Desktop, Cursor, and VS Code can use this equivalent remote MCP configuration:
{"mcpServers": {"apify": {"url": "https://mcp.apify.com?tools=automation-lab/ufc-events-fights-fighters"}}}
Example prompts:
- “Export the five most recent completed UFC events with bout cards.”
- “Get detailed stats for this UFCStats fight URL and summarize the striking difference.”
- “Fetch Anthony Hernandez's profile and fight history as structured JSON.”
Limits
Large detail runs make one or more source requests per result. Use sensible limits and schedules. The Actor runs sequentially at conservative request volume to reduce source load.
Legality and responsible use
The Actor reads public UFCStats pages. It does not provide video, live round-by-round feeds, betting odds, unofficial predictions, or data from other MMA promotions unless UFCStats displays those records.
Respect UFCStats terms, applicable law, database rights, and personal-data rules. Do not use the data for harassment, deceptive publishing, or decisions that require an official governing-body record. Verify high-stakes facts against the original source linked in each item.
Troubleshooting
Why did my run return no records?
Check that the selected mode matches the supplied URL or filter. A fighter name is matched against UFCStats' fighter directory. Date ranges may naturally contain no events.
Why did the run fail instead of returning an empty dataset?
A changed browser challenge, HTTP error, or unrecognized page shape is treated as an upstream error. This prevents challenge HTML from being mistaken for a valid empty result. Retry later; if the failure persists, include the run link in a support report.
Why are some fight fields null?
Upcoming bouts do not yet have an outcome, method, totals, or significant-strike table. Historical pages may also omit individual values.
FAQ
Is this an official UFC API?
No. It is an independent Apify Actor that normalizes public pages from UFCStats. It is not affiliated with or endorsed by UFC.
Can I scrape one fight or fighter URL?
Yes. Supply a matching UFCStats detail URL in startUrls and select the corresponding mode.
Can I fetch upcoming cards?
Yes. Use event mode with eventStatus: "upcoming". Upcoming fights naturally lack result statistics.
Does maxItems count nested bouts?
In event mode it counts event records. In fight mode it counts fight records. In fighter mode it counts fighter records. Nested bout histories are included with their parent and are not separately charged.
Are nested records charged separately?
No. Only each primary dataset item triggers the item event. Event bout cards and fighter fight histories included inside that record have no separate item charge.
Related Actors
For another structured sports dataset from automation-lab, see FIFA World Cup 2026 Data. Use it for official World Cup fixtures rather than UFCStats records.