# MMA Sabermetrics - UFC, Bellator, PFL + Jenko Metrics (`jenko_systems/ufc-historical-stats`) Actor

11,720 MMA fights across UFC, Bellator, PFL, Invicta, Rizin (1993-2026). 6 proprietary Jenko metrics: JFI (Finishing), JSP (Striking), JGD (Grappling), JCG (Clutch), JDS (Damage), JKR (KO Resistance). 7 query modes

- **URL**: https://apify.com/jenko_systems/ufc-historical-stats.md
- **Developed by:** [Jenko Systems](https://apify.com/jenko_systems) (community)
- **Categories:** Other, News, Automation
- **Features:** Limited permissions
- **Stats:** 203 total users, 9 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.70 / 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

## MMA Sabermetrics — UFC, Bellator, PFL + Jenko Metrics

The most complete MMA database as an API, **with proprietary Jenko Sabermetrics**. 10,900+ fights across UFC, Bellator and PFL (1993-2026) and **6 Jenko metrics that nobody else has**.

> **What's new in v2.0:** Jenko Sabermetrics — the first MMA proprietary scoring system. 6 metrics that quantify striking precision, grappling dominance, finishing ability, clutch gene, damage output, and chin durability across eras.

### Why this actor?

Other MMA APIs give you stats. We give you **insights**.

**Example:** Why did Poirier beat McGregor twice in 2021 after losing in 2014?

- JKR (KO Resistance): **Poirier 67** vs McGregor 56 → Poirier's chin held up
- JDS (Damage Score): McGregor **90** vs Poirier 78 → Conor still hits harder
- JFI (Finishing): McGregor **82** vs Poirier 67 → Conor still finishes more
- **But durability matters when the power is gone.** The data tells the story.

### The 6 Jenko Metrics

| ID | Name | Measures | Reference |
|---|---|---|---|
| **JFI** | Jenko Finishing Index | KO+SUB rate × round dominance | Khabib FINISHER_ELITE |
| **JSP** | Jenko Striking Precision | Acc + Volume + Headhunting + KD power | Max Holloway SNIPER_ELITE |
| **JGD** | Jenko Grappling Dominance | TD volume + Accuracy + Submission threat | Khamzat GRAPPLER_ELITE |
| **JCG** | Jenko Clutch Gene | Main event wins + finishes + title fights | Jon Jones CLUTCH_LEGEND |
| **JDS** | Jenko Damage Score | Knockdowns/fight + Total KDs + Volume | McGregor ONE_SHOT_POWER |
| **JKR** | Jenko KO Resistance | % of losses NOT by KO/TKO (chin) | Nate Diaz GRANITE_CHIN |

Each metric returns: `score` (0-100), `verdict` (5-tier categorical), `interpretation`, `formula`, `breakdown`, `verdict_scale`, `example_comparison`. **Calibrated with real data from 1,239 UFC fighters.**

### 🤖 Use with AI agents (MCP) and automations

This actor works out of the box with AI assistants through the [Apify MCP server](https://mcp.apify.com) (Claude, ChatGPT, Cursor and other MCP clients), and with n8n, Make or Zapier.

- **Every input is optional.** Pick a mode and empty fields get a current example (for instance, the latest UFC main event). What was assumed comes back in `defaults_used`.
- **Names are forgiving.** Partial names work (`"Makhachev"`). If a name isn't found, the run fails without charging you and suggests the closest matches (`Did you mean: Conor McGregor?`).
- **Compact answers:** set `"summary_only": true` to get just the key rows (a fighter's profile with Jenko scores, a ranking without the per-fighter breakdown). That's ideal for chat answers and dashboards.
- **Jenko metrics are on by default** in `fighter` and `matchup`.

Typical agent calls:

```json
{ "mode": "fighter", "fighter": "Islam Makhachev", "summary_only": true }
{ "mode": "matchup", "fighter1": "Poirier", "fighter2": "McGregor", "summary_only": true }
{ "mode": "jenko_ranking", "metric": "JKR", "top_n": 10, "summary_only": true }
{ "mode": "event", "event": "UFC 300" }
```

### 7 Query Modes

#### `jenko_ranking` ⭐ (FLAGSHIP)

Rank fighters by any Jenko metric.

```json
{ "mode": "jenko_ranking", "metric": "JFI", "top_n": 20 }
{ "mode": "jenko_ranking", "metric": "JDS", "organization": "UFC", "min_fights": 10 }
```

#### `fighter` — Career history + Jenko

```json
{ "mode": "fighter", "fighter": "Khabib", "include_jenko": true }
```

Add `"jenko_full": true` for complete metric breakdowns (formula, comparison, verdict scale).

#### `matchup` — Head-to-head with Jenko comparison

```json
{ 
  "mode": "matchup", 
  "fighter1": "Poirier", 
  "fighter2": "McGregor",
  "include_jenko": true 
}
```

Returns: profiles + previous fights + **JENKO COMPARISON** showing who wins each metric.

#### `ranking` — Classic stats

```json
{ "mode": "ranking", "stat": "ko_artists", "top_n": 20 }
```

Available: `ko_artists`, `submission_artists`, `decision_wins`, `most_fights`, `finish_rate`

#### `event` — Event card

```json
{ "mode": "event", "event": "UFC 300" }
```

#### `organization` — All fights from an org

```json
{ "mode": "organization", "organization": "Bellator", "max_resultados": 100 }
```

#### `weight_class` — Division history

```json
{ "mode": "weight_class", "weight_class": "Lightweight" }
```

### Dataset coverage

| Organization | Fights | Stats Coverage |
|---|---|---|
| UFC          | 8,912  | Full (sig strikes, takedowns, control time, KDs) for ufcstats fights; basic for the most recent events when ufcstats is offline (filled from Sherdog, upgraded automatically later) |
| Bellator     | 1,150  | Basic (result, method, round) |
| PFL          | 857    | Basic |
| **Total**    | **10,919** | |

Every result carries `data_as_of` — the date of the most recent event in the database.

UFC stats include: `sig_str_landed/att`, `head/body/leg breakdown`, `td_landed/att`, `sub_att`, `knockdowns`, `ctrl_time`. These power the Jenko metrics.

### Top JFI Finishers (sample output)

```
#1  Erick Silva           17f  100.0 FINISHER_ELITE
#2  Terrance McKinney     17f  100.0 FINISHER_ELITE
#3  Daniel Pineda         16f  100.0 FINISHER_ELITE
#5  Bruno Silva           60f   96.0 FINISHER_ELITE
#7  Vitor Belfort         26f   94.0 FINISHER_ELITE
```

### Use cases

- **Sports betting**: Identify mismatches via Jenko comparison (chin vs power, grappler vs striker)
- **Fantasy MMA**: Build scoring models using Jenko scores as features
- **Content creation**: "Top 10 by Jenko Damage Score" instantly
- **Research**: 30+ years of MMA data with calibrated metrics
- **Fight prediction**: Train ML models on standardized 0-100 scores

### Data sources

- **UFC**: [ufcstats.com](http://ufcstats.com) — official UFC statistics
- **Other orgs**: [sherdog.com](https://www.sherdog.com)
- **Updates**: Weekly via Apify schedule (every Monday)

### Methodology — Jenko Calibration

All metrics calibrated with real percentile distributions:

- JSP: P25=41% sig acc, P75=52%, P95=60%
- JGD: P50=49% TD acc, P95=100% (specialists)
- JFI: P25=33%, P50=50%, P75=67% finish rate
- JDS: McGregor reference 0.57 KD/fight = 100

Each fighter needs minimum 5 career fights to qualify (configurable via `min_fights`).

***

🌐 jenkosystems.com

# Actor input Schema

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

Pick a mode. Empty fields get a current example from the database (listed in 'defaults_used' in the output). Fields each mode uses:
• fighter: fighter (empty = winner of the latest UFC main event)
• matchup: fighter1, fighter2 (empty = the latest UFC main event)
• event: event (empty = latest UFC event)
• organization: organization (empty = UFC)
• weight_class: weight_class (empty = Lightweight)
• ranking: stat, top_n, min_fights
• jenko_ranking: metric, top_n, min_fights

## `metric` (type: `string`):

Which Jenko metric to rank by.

## `fighter` (type: `string`):

Fighter name, full or partial (e.g. 'Islam Makhachev', 'McGregor', 'Adesanya'). Accent-free spelling as on UFCStats. If not found, the run suggests the closest names. Empty = winner of the latest UFC main event.

## `fighter1` (type: `string`):

First fighter for matchup mode (e.g. 'Dustin Poirier'). Empty = one side of the latest UFC main event.

## `fighter2` (type: `string`):

Second fighter for matchup mode (e.g. 'Conor McGregor'). Empty = the other side of the latest UFC main event.

## `event` (type: `string`):

Event name, full or partial (e.g. 'UFC 300', 'Bellator 300', 'Fight Night 290'). Empty = latest UFC event.

## `organization` (type: `string`):

UFC, Bellator or PFL.

## `weight_class` (type: `string`):

Lightweight, Heavyweight, Welterweight, etc.

## `stat` (type: `string`):

For 'ranking' mode (not jenko_ranking).

## `top_n` (type: `integer`):

Number of results in rankings.

## `min_fights` (type: `integer`):

Minimum career fights to qualify for jenko_ranking.

## `include_jenko` (type: `boolean`):

Adds the 6 Jenko metric scores (JFI, JSP, JGD, JCG, JDS, JKR) in fighter and matchup modes. On by default.

## `jenko_full` (type: `boolean`):

Returns full payload (formula, breakdown, scale, comparison) per metric.

## `summary_only` (type: `boolean`):

Return only the main rows: the fighter profile without the fight list, rankings without the per-fighter breakdown, the event or division summary without every fight. Best for AI agents (MCP), dashboards and quick lookups.

## `max_resultados` (type: `integer`):

Maximum number of fights to return in organization mode.

## Actor input object example

```json
{
  "mode": "jenko_ranking",
  "metric": "JFI",
  "stat": "ko_artists",
  "top_n": 20,
  "min_fights": 5,
  "include_jenko": true,
  "jenko_full": false,
  "summary_only": false,
  "max_resultados": 100
}
```

# Actor output Schema

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

Results in dataset. Schema varies by mode.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("jenko_systems/ufc-historical-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("jenko_systems/ufc-historical-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 '{}' |
apify call jenko_systems/ufc-historical-stats --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jenko_systems/ufc-historical-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/JDwq20fhNp5fdhQ3b/builds/nW7jpTDMZYK4icslF/openapi.json
