API live
Contract 2026-09-06.3 Fight DNA v1 1,437 fighters 898 events 1,795 bouts 5,724 rounds of stats Next card Noche UFC: Silva vs. Delgado · 2026-09-12
Updated 21 min ago Docs →

Methodology

PropBetEdge Fight DNA, for developers.

Raw data tells you what happened. Fight DNA reveals the patterns inside the record. This page explains exactly how, using the live metric registry (definition version 1, captured Sep 7, 2026).

What Fight DNA is

Fight DNA is the proprietary analytics layer above the normalized UFC record. It is a versioned, reproducible, as-of feature system that transforms event-dated bout and round history into fighter-specific and matchup-specific intelligence. It is deterministic: the same source rows always produce the same output. It is not a model, and it is not a prediction.

It answers questions a fighter page does not: how does a fighter do against southpaws, does pace survive into round three, is offense head-heavy or leg-heavy, does a takedown produce control, where do finishes happen, and which of those variables are unusually different between two fighters about to meet.

Source facts versus derived features

The API labels origin on every payload so you never confuse the two.

OriginLabelMeaningExamples
sourceSourceNormalized facts from ESPN, UFC Stats and ufc.com. Copied, never computed.event, fighter identity, fight result, strike counts, takedowns, official ranking snapshot
pbe_derivedPBE derivedComputed by the Fight DNA builder from canonical rows. Every value is a MetricObject.stance splits, strike differential, target and phase shares, per-minute and per-15 rates, finish distributions, control yield, pace retention, context splits, matchup comparisons
licensedLicensedReserved for licensed enrichment stored separately from derived features.position profile (control time by position, finish weapon) — explicitly unavailable until a licensed source exists
modelModelReserved for actual model output. Fight DNA is not labelled model.none today

The feature pipeline

  1. Source rows. Only canonical tables: fighters, events, bouts, results, round stats. Career snapshot fields are never inputs.
  2. Per-bout features. Two rows per completed bout, one from each fighter's perspective: stance context, outcome, method, scheduled rounds, title and main-event flags, stat coverage, observed seconds, raw totals, derived per-bout values and provenance.
  3. Observed time. 300 seconds per full standard round; a partial final round uses the recorded stoppage time; unrecognised time formats set observed seconds to null with a warning.
  4. As-of snapshots. One snapshot per fighter per as-of date: metrics, stance splits, round profile, finish profile, context splits, provenance.
  5. Matchup composition. Two snapshots compared against each other's actual profile with threshold-gated insights.

As-of reconstruction

as_of_date is exclusive: the snapshot dated D contains bouts with event_date < D, so a bout fought on D is excluded by the snapshot dated D. ?as_of=D resolves to the latest stored snapshot with as_of_date <= D, which therefore never contains a bout fought on or after D.

Use ?as_of=YYYY-MM-DD on any fighter DNA route (Pro and above) to reconstruct what was knowable before a given date. If no snapshot exists at or before that date the API answers 404 dna_not_available with the reason, never an empty profile. Example, captured live:

GET /v1/ufc/fighters/ec94d296-2db3-4e0d-be6a-46de4f480672/dna?as_of=2024-01-01 404 · truthful
{
  "ok": false,
  "data": null,
  "error": {
    "code": "dna_not_available",
    "message": "No Fight DNA snapshot exists for Sean Strickland at or before 2024-01-01. Nothing is synthesized.",
    "detail": {
      "fighter_id": "ec94d296-2db3-4e0d-be6a-46de4f480672",
      "requested_as_of": "2024-01-01",
      "definition_version": 1,
      "reason": "no_snapshot_at_or_before_as_of"
    }
  },
  "meta": {
    "api": "PropSports UFC",
    "version": "2026-09-06.3",
    "request_id": "475fa213-d202-4353-a79d-d31519c3b4a3"
  }
}

Why sample size matters

Round-stat coverage is a backfill in progress, and many fighters have few covered bouts. A rate built on ten minutes of observed time is not the same as one built on ninety. Fight DNA therefore never returns a bare number: sample_bouts, sample_rounds and sample_seconds travel with every value, and the UI contract forbids turning a low-sample split into a categorical claim.

Example: Sean Strickland's sig_landed_per_min is 6.2327 per minute from 2 stat-covered bouts, 8 rounds and 37.4 observed minutes, confidence medium. That is exactly how it is reported.

Confidence

TierRule (v1)
insufficientsample below the metric's registry minimum (min_bouts / min_rounds / min_seconds); value is null when there is no denominator
lowminimum met but sample_bouts < 3 (result metrics) or sample_seconds < 1800 (rate metrics)
mediumsample_bouts < 8 (result metrics) or sample_seconds < 5400 (rate metrics)
highsample_bouts >= 8 (result metrics) or sample_seconds >= 5400 (rate metrics)

coverage_status uses the same scale and describes how much of the fighter's bout history has round-stat coverage. A zero denominator produces value: null with confidence: "insufficient".

Stance DNA

How a fighter performs against southpaws, orthodox fighters and switch hitters. Record, finish, KO and submission rates, and significant-strike differential are grouped by the opponent's listed stance; open-stance and same-stance contexts are reported separately. Result counts reconcile exactly to canonical bout results.

MetricDefinitionFormulaUnitMinimum sample
open_stance_record
Open-Stance Record
W/L/D/NC when one fighter is listed orthodox and the other southpaw.aggregate outcomes where stance_context = openrecord1 bouts · 0 rounds · 0s
same_stance_record
Same-Stance Record
W/L/D/NC when both listed stances are the same.aggregate outcomes where stance_context = samerecord1 bouts · 0 rounds · 0s
stance_finish_rate
Finish Rate vs Stance
KO/TKO plus submission wins divided by wins against a listed opponent stance.(ko_tko_wins + submission_wins) / wins_vs_stanceratio2 bouts · 0 rounds · 0s
stance_kd_rate_15
Knockdowns / 15 vs Stance
Knockdowns created per 15 observed minutes, grouped by opponent stance.kd * 900 / observed_secondsper_151 bouts · 2 rounds · 300s
stance_ko_rate
KO/TKO Rate vs Stance
KO/TKO wins divided by completed appearances against a listed opponent stance.ko_tko_wins / completed_appearances_vs_stanceratio2 bouts · 0 rounds · 0s
stance_record
Record vs Stance
W/L/D/NC by opponent listed stance.aggregate outcomes grouped by opponent_stancerecord1 bouts · 0 rounds · 0s
stance_sig_diff_per_min
Sig. Strike Differential / Min vs Stance
Fighter significant strikes landed minus opponent landed, per observed minute, grouped by opponent stance.(sig_str_landed - opponent_sig_str_landed) / observed_minutesper_min1 bouts · 2 rounds · 300s
stance_sub_rate
Submission Rate vs Stance
Submission wins divided by completed appearances against a listed opponent stance.submission_wins / completed_appearances_vs_stanceratio2 bouts · 0 rounds · 0s
stance_td_rate_15
Takedowns Landed / 15 vs Stance
Takedowns landed per 15 observed minutes, grouped by opponent stance.td_landed * 900 / observed_secondsper_151 bouts · 2 rounds · 300s

Striking DNA

Pace, accuracy and defense normalized per observed minute, target shares (head, body, leg) and phase shares (distance, clinch, ground) from UFC Stats round rows. Denominators are actual observed seconds, not scheduled time.

MetricDefinitionFormulaUnitMinimum sample
body_attack_share
Body Attack Share
Body significant-strike attempts divided by all significant-strike attempts.body_att / sig_str_attratio1 bouts · 2 rounds · 300s
clinch_attack_share
Clinch Attack Share
Clinch significant-strike attempts divided by all significant-strike attempts.clinch_att / sig_str_attratio1 bouts · 2 rounds · 300s
distance_attack_share
Distance Attack Share
Distance significant-strike attempts divided by all significant-strike attempts.distance_att / sig_str_attratio1 bouts · 2 rounds · 300s
ground_attack_share
Ground Attack Share
Ground significant-strike attempts divided by all significant-strike attempts.ground_att / sig_str_attratio1 bouts · 2 rounds · 300s
head_attack_share
Head Attack Share
Head significant-strike attempts divided by all significant-strike attempts.head_att / sig_str_attratio1 bouts · 2 rounds · 300s
knockdowns_absorbed_per_15
Knockdowns Absorbed / 15
Opponent knockdowns per 15 stat-covered minutes.opponent_kd * 900 / observed_secondsper_151 bouts · 2 rounds · 300s
knockdowns_per_15
Knockdowns / 15
Knockdowns created per 15 stat-covered minutes.kd * 900 / observed_secondsper_151 bouts · 2 rounds · 300s
leg_attack_share
Leg Attack Share
Leg significant-strike attempts divided by all significant-strike attempts.leg_att / sig_str_attratio1 bouts · 2 rounds · 300s
sig_absorbed_per_min
Sig. Strikes Absorbed / Min
Opponent significant strikes landed divided by observed stat-covered minutes.opponent_sig_str_landed / observed_minutesper_min1 bouts · 2 rounds · 300s
sig_accuracy
Sig. Strike Accuracy
Significant strikes landed divided by significant strikes attempted.sig_str_landed / sig_str_attratio1 bouts · 2 rounds · 300s
sig_defense
Sig. Strike Defense
One minus opponent significant strikes landed divided by opponent attempts.1 - opponent_sig_str_landed / opponent_sig_str_attratio1 bouts · 2 rounds · 300s
sig_diff_per_min
Sig. Strike Differential / Min
Significant strikes landed minus absorbed, per observed minute.(sig_str_landed - opponent_sig_str_landed) / observed_minutesper_min1 bouts · 2 rounds · 300s
sig_landed_per_min
Sig. Strikes Landed / Min
Significant strikes landed divided by observed stat-covered minutes.sig_str_landed / observed_minutesper_min1 bouts · 2 rounds · 300s

Grappling DNA

Takedown volume and accuracy per 15 observed minutes, control seconds per takedown landed, control share of observed time, submission attempts and reversals.

MetricDefinitionFormulaUnitMinimum sample
control_seconds_per_td
Control Seconds / Takedown
Recorded control seconds divided by takedowns landed.ctrl_sec / td_landedseconds_per_td1 bouts · 2 rounds · 300s
control_share
Control Share
Recorded control seconds divided by observed stat-covered seconds.ctrl_sec / observed_secondsratio1 bouts · 2 rounds · 300s
reversals_per_15
Reversals / 15
Reversals per 15 stat-covered minutes.rev * 900 / observed_secondsper_151 bouts · 2 rounds · 300s
sub_attempts_per_15
Submission Attempts / 15
Submission attempts per 15 stat-covered minutes.sub_att * 900 / observed_secondsper_151 bouts · 2 rounds · 300s
td_accuracy
Takedown Accuracy
Takedowns landed divided by takedowns attempted.td_landed / td_attratio1 bouts · 2 rounds · 300s
td_attempts_per_15
Takedown Attempts / 15
Takedown attempts per 15 stat-covered minutes.td_att * 900 / observed_secondsper_151 bouts · 2 rounds · 300s
td_landed_per_15
Takedowns Landed / 15
Takedowns landed per 15 stat-covered minutes.td_landed * 900 / observed_secondsper_151 bouts · 2 rounds · 300s

Finish DNA

How and when finishes happen: finish, KO and submission finish rates, finish-round distribution and median elapsed finish time, computed from canonical results only.

MetricDefinitionFormulaUnitMinimum sample
finish_rate
Finish Rate
KO/TKO plus submission wins divided by wins.(ko_tko_wins + submission_wins) / winsratio2 bouts · 0 rounds · 0s
finish_round_distribution
Finish Round Distribution
Finish wins grouped by ending round.count finish wins by rounddistribution1 bouts · 0 rounds · 0s
finish_time_median_sec
Median Finish Time
Median elapsed fight seconds of finish wins with a standard time format.median((round - 1) * 300 + time_sec) over finish winsseconds1 bouts · 0 rounds · 0s
finished_by_round_distribution
Finished-By Round Distribution
Losses by KO/TKO or submission grouped by ending round.count finish losses by rounddistribution1 bouts · 0 rounds · 0s
ko_finish_rate
KO/TKO Finish Rate
KO/TKO wins divided by wins.ko_tko_wins / winsratio2 bouts · 0 rounds · 0s
submission_finish_rate
Submission Finish Rate
Submission wins divided by wins.submission_wins / winsratio2 bouts · 0 rounds · 0s

Round DNA

Whether round-one pace survives into rounds two and three, championship-round delta for five-round fights, and defensive drift (absorbed rate in round three minus round one).

MetricDefinitionFormulaUnitMinimum sample
championship_round_delta
Championship-Round Pace Delta
Rounds 4-5 significant-attempt pace minus rounds 1-3 pace, over bouts that reached round 4.late_round_sig_att_per_min - early_round_sig_att_per_minper_min1 bouts · 4 rounds · 1200s
defensive_drift_r3_vs_r1
Defensive Drift R3 vs R1
Round-three significant strikes absorbed per minute minus the round-one rate, over bouts with both rounds covered.r3_absorbed_per_min - r1_absorbed_per_minper_min2 bouts · 6 rounds · 900s
late_round_sig_attempts_per_min
Championship-Round Sig. Attempts / Min
Rounds 4-5 significant-strike attempts per observed rounds 4-5 minute.(r4_sig_str_att + r5_sig_str_att) / (r4_observed_minutes + r5_observed_minutes)per_min1 bouts · 1 rounds · 60s
pace_retention_r2_vs_r1
R2 Pace Retention
Round-two significant-strike attempt pace divided by round-one pace.r2_sig_att_per_min / r1_sig_att_per_minratio2 bouts · 4 rounds · 600s
pace_retention_r3_vs_r1
R3 Pace Retention
Round-three significant-strike attempt pace divided by round-one pace.r3_sig_att_per_min / r1_sig_att_per_minratio2 bouts · 6 rounds · 900s
r1_sig_absorbed_per_min
R1 Sig. Absorbed / Min
Round-1 opponent significant strikes landed per observed round-1 minute.r1_opponent_sig_str_landed / r1_observed_minutesper_min1 bouts · 1 rounds · 60s
r1_sig_attempts_per_min
R1 Sig. Attempts / Min
Round-one significant-strike attempts per observed round-one minute.r1_sig_str_att / r1_observed_minutesper_min1 bouts · 1 rounds · 60s
r1_sig_landed_per_min
R1 Sig. Landed / Min
Round-1 significant strikes landed per observed round-1 minute.r1_sig_str_landed / r1_observed_minutesper_min1 bouts · 1 rounds · 60s
r2_sig_absorbed_per_min
R2 Sig. Absorbed / Min
Round-2 opponent significant strikes landed per observed round-2 minute.r2_opponent_sig_str_landed / r2_observed_minutesper_min1 bouts · 1 rounds · 60s
r2_sig_attempts_per_min
R2 Sig. Attempts / Min
Round-two significant-strike attempts per observed round-two minute.r2_sig_str_att / r2_observed_minutesper_min1 bouts · 1 rounds · 60s
r2_sig_landed_per_min
R2 Sig. Landed / Min
Round-2 significant strikes landed per observed round-2 minute.r2_sig_str_landed / r2_observed_minutesper_min1 bouts · 1 rounds · 60s
r3_sig_absorbed_per_min
R3 Sig. Absorbed / Min
Round-3 opponent significant strikes landed per observed round-3 minute.r3_opponent_sig_str_landed / r3_observed_minutesper_min1 bouts · 1 rounds · 60s
r3_sig_attempts_per_min
R3 Sig. Attempts / Min
Round-three significant-strike attempts per observed round-three minute.r3_sig_str_att / r3_observed_minutesper_min1 bouts · 1 rounds · 60s
r3_sig_landed_per_min
R3 Sig. Landed / Min
Round-3 significant strikes landed per observed round-3 minute.r3_sig_str_landed / r3_observed_minutesper_min1 bouts · 1 rounds · 60s
r4_sig_absorbed_per_min
R4 Sig. Absorbed / Min
Round-4 opponent significant strikes landed per observed round-4 minute.r4_opponent_sig_str_landed / r4_observed_minutesper_min1 bouts · 1 rounds · 60s
r4_sig_attempts_per_min
R4 Sig. Attempts / Min
Round-4 significant-strike attempts per observed round-4 minute.r4_sig_str_att / r4_observed_minutesper_min1 bouts · 1 rounds · 60s
r4_sig_landed_per_min
R4 Sig. Landed / Min
Round-4 significant strikes landed per observed round-4 minute.r4_sig_str_landed / r4_observed_minutesper_min1 bouts · 1 rounds · 60s
r5_sig_absorbed_per_min
R5 Sig. Absorbed / Min
Round-5 opponent significant strikes landed per observed round-5 minute.r5_opponent_sig_str_landed / r5_observed_minutesper_min1 bouts · 1 rounds · 60s
r5_sig_attempts_per_min
R5 Sig. Attempts / Min
Round-5 significant-strike attempts per observed round-5 minute.r5_sig_str_att / r5_observed_minutesper_min1 bouts · 1 rounds · 60s
r5_sig_landed_per_min
R5 Sig. Landed / Min
Round-5 significant strikes landed per observed round-5 minute.r5_sig_str_landed / r5_observed_minutesper_min1 bouts · 1 rounds · 60s

Context DNA

Records under specific conditions: short notice, three-round and five-round bouts, title fights and main events. Each split carries its own appearances and confidence.

MetricDefinitionFormulaUnitMinimum sample
five_round_record
Five-Round Record
W/L/D/NC in bouts scheduled for 5 rounds.aggregate outcomes where scheduled_rounds = 5record1 bouts · 0 rounds · 0s
main_event_record
Main Event Record
W/L/D/NC when the bout carried the highest bout_order on its event.aggregate outcomes where is_main_eventrecord1 bouts · 0 rounds · 0s
short_notice_record
Short-Notice Record
W/L/D/NC in bouts carrying a verified short_notice_days value.aggregate outcomes where short_notice_days is not nullrecord1 bouts · 0 rounds · 0s
three_round_record
Three-Round Record
W/L/D/NC in bouts scheduled for 3 rounds.aggregate outcomes where scheduled_rounds = 3record1 bouts · 0 rounds · 0s
title_bout_record
Title Bout Record
W/L/D/NC in title bouts.aggregate outcomes where is_titlerecord1 bouts · 0 rounds · 0s

Matchup DNA

Fighter versus the opponent actually in front of them.

A matchup response resolves each fighter's own snapshot (each with its own as-of date), then compares 18 paired metrics with a signed delta and direction, adds stance context (fighter A's history against fighter B's listed stance and vice versa), and emits insights only when every documented rule is met. Below threshold, the missing sample is named in warnings[]. Nothing is fabricated.

Comparison keys

sig_landed_per_min · sig_absorbed_per_min · sig_accuracy · sig_defense · head_attack_share · body_attack_share · leg_attack_share · distance_attack_share · clinch_attack_share · ground_attack_share · kd_per_15 · td_attempts_per_15 · td_accuracy · control_seconds_per_td · sub_attempts_per_15 · pace_retention_r2_vs_r1 · pace_retention_r3_vs_r1 · finish_rate

Insight rules (version 1)

meta.insight_rules
{
  "version": 1,
  "min_confidence": "low",
  "stance_history": {
    "min_appearances": 3,
    "min_confidence": "low"
  },
  "stance_finish_rate": {
    "min_appearances": 3,
    "min_confidence": "low",
    "note": "finish_rate MetricObject of the split must itself be >= low (registry min 2 wins)"
  },
  "pace_retention": {
    "metric": "pace_retention_r3_vs_r1",
    "min_bouts": 2,
    "min_confidence": "low"
  },
  "pace_retention_mismatch": {
    "metric": "pace_retention_r3_vs_r1",
    "min_bouts": 2,
    "min_confidence": "low",
    "min_abs_delta": 0.1
  },
  "target_share_mismatch": {
    "metrics": [
      "head_attack_share",
      "body_attack_share",
      "leg_attack_share"
    ],
    "min_confidence": "low",
    "min_abs_delta": 0.1
  },
  "phase_share_mismatch": {
    "metrics": [
      "distance_attack_share",
      "clinch_attack_share",
      "ground_attack_share"
    ],
    "min_confidence": "low",
    "min_abs_delta": 0.1
  },
  "grappling_mismatch": {
    "min_confidence": "low",
    "min_abs_delta": {
      "td_attempts_per_15": 1,
      "td_accuracy": 0.1,
      "control_seconds_per_td": 30,
      "sub_attempts_per_15": 0.5
    }
  },
  "finish_rate": {
    "metric": "finish_rate",
    "min_confidence": "low"
  }
}

Worked example: Sean Strickland vs Dricus Du Plessis

  • Sean Strickland R3 pace retention — Sean Strickland kept 259% of round-one significant-strike attempt pace into round three across 2 bouts / 4 rounds / 17.4 min of stat-covered fights as of 2026-09-06. medium
  • Sean Strickland finish rate — 50% of Sean Strickland's 2 UFC wins came by finish (0 KO/TKO, 0 submission), PBE-derived from canonical results as of 2026-09-06. low
  • Dricus Du Plessis finish rate — 0% of Dricus Du Plessis's 2 UFC wins came by finish (0 KO/TKO, 0 submission), PBE-derived from canonical results as of 2026-09-06. low

And the warnings the same call produced, verbatim:

  • Sean Strickland vs switch-stance opponents: 1 appearance, confidence low; needs >= 3 appearances and confidence >= low. No stance insight emitted.
  • Dricus Du Plessis vs orthodox opponents: 2 appearances, confidence low; needs >= 3 appearances and confidence >= low. No stance insight emitted.
  • Dricus Du Plessis pace_retention_r3_vs_r1: confidence low (1 bout / 2 rounds / 10.0 min); needs >= 2 stat-covered bouts and confidence >= low. No pace insight emitted.
  • Control seconds / takedown: Sean Strickland confidence medium (2 bouts / 8 rounds / 37.4 min); Dricus Du Plessis confidence low (1 bout / 5 rounds / 25.0 min). Both sides need confidence >= low; no grappling mismatch insight emitted.
Fight DNA is PBE-derived evidence with explicit samples and confidence. It is not a pick, price or probability.

Provenance

Every MetricObject carries: metric_key, value, unit, numerator, denominator, sample_bouts, sample_rounds, sample_seconds, confidence, coverage_status, definition_version, origin, source_families and as_of_date. Snapshots additionally carry the list of bout ids in scope, the source watermark and the build run id. The commercial gateway never strips any of it; it is part of what you pay for.

MetricObject (live)
{
  "unit": "per_min",
  "value": 6.2327,
  "origin": "pbe_derived",
  "numerator": 233,
  "as_of_date": "2026-09-06",
  "confidence": "medium",
  "metric_key": "sig_landed_per_min",
  "denominator": 2243,
  "sample_bouts": 2,
  "sample_rounds": 8,
  "sample_seconds": 2243,
  "coverage_status": "low",
  "source_families": [
    "ufcstats"
  ],
  "definition_version": 1
}

Definition versioning

Every metric is defined in a registry row with definition_version, formula, unit, source families and minimum sample. A change to a definition is a new version, never a silent recalculation; snapshots carry the version they were built with, and GET /v1/ufc/dna/metrics?version= serves the registry for a version. The commercial contract pins the definition version it targets (currently v1) and a drift guard fails our build if it changes upstream.

What Fight DNA cannot tell you

  • It does not predict outcomes, price a market or output a probability. Nothing in the API is a pick.
  • It does not know what is not in the record. Bouts without round stats contribute results only; position data does not exist until a licensed source is added; injuries, weigh-ins and odds are not part of Fight DNA.
  • It does not adjust for opponent quality yet. Opponent-adjusted metrics and archetypes are reserved for a later definition version.
  • It cannot make a small sample large. Low-sample values are reported as low-sample values.
  • It is not an official UFC statistic and must not be presented as one.

Unlock Fight DNA on Pro See Fight DNA in action →