---
title: "Compare two fighters"
method: GET
path: "/v1/compare"
tags: ["Fighters"]
---

# Compare two fighters

`GET /v1/compare`

## Request

- Base URL: `https://api.ufcalendar.com`
- URL: `https://api.ufcalendar.com/v1/compare`
- Auth: HTTP bearer

The tale of the tape in one call. `a` and `b` are fighter slugs or ids (a renamed slug is followed and named in `meta.resolved`); both are required and must differ (400 `invalid_query`), and each must be on the roster (404 `not_found`). Returns both bios (the `/v1/fighters/{idOrSlug}` bio fields plus `age`), `career_stats` (the `/v1/fighters/{idOrSlug}/stats` rows), `aggregates` per fighter over every completed bout with per-fight totals (`fights_analyzed`, average and best significant strikes and takedowns, average control time in seconds, and the strike mix: `location_pct` head/body/leg and `position_pct` distance/clinch/ground, whole percents, null when nothing was logged), `recent_form` (the last five settled entries of the merged multi-promotion timeline, `/v1/fighters/{idOrSlug}/history` rows), `win_streak`, `head_to_head` (their previous meetings, from `a`'s side), `common_opponents` (up to 5: the shared opponent with each fighter's most recent bout against them), `booked_bout` (the upcoming or live bout between them in a covered promotion, in its stored corner order, or null), `prediction` (UFCalendar model win probability for that booked bout, oriented to `a` — UFC only, served only while its corner stamp matches the bout, else null) and `power_index` (each fighter's UFCalendar Power Index rating, peak and fights rated, and `win_probability_a` from the two ratings). Model output is information, not betting advice.

## Query parameters

- `a` string, required
- `b` string, required

## Response `200`

Side-by-side comparison

- CompareResponse
  - `data` Compare, required
    - `a` CompareFighter, required: The bio half of a fighter profile plus `age` (`/v1/compare`).
      - `id` integer, required
      - `slug` string, required
      - `name` string, required
      - `nickname` string, nullable, required
      - `nationality` string, nullable, required: Country NAME as the source spells it (e.g. `United States`).
      - `country_code` string, nullable, required: ISO 3166-1 alpha-2 derived from `nationality`; null when the name is unknown to our table.
      - `second_nationality` string, nullable, required
      - `height_inches` number, nullable, required
      - `weight_lbs` number, nullable, required
      - `reach_inches` number, nullable, required
      - `stance` string, nullable, required
      - `dob` string, date, nullable, required
      - `team` string, nullable, required
      - `birthplace` string, nullable, required
      - `age` integer, nullable, required: Whole years from `dob`; null when unknown.
    - `b` CompareFighter, required: The bio half of a fighter profile plus `age` (`/v1/compare`).
      - `id` integer, required
      - `slug` string, required
      - `name` string, required
      - `nickname` string, nullable, required
      - `nationality` string, nullable, required: Country NAME as the source spells it (e.g. `United States`).
      - `country_code` string, nullable, required: ISO 3166-1 alpha-2 derived from `nationality`; null when the name is unknown to our table.
      - `second_nationality` string, nullable, required
      - `height_inches` number, nullable, required
      - `weight_lbs` number, nullable, required
      - `reach_inches` number, nullable, required
      - `stance` string, nullable, required
      - `dob` string, date, nullable, required
      - `team` string, nullable, required
      - `birthplace` string, nullable, required
      - `age` integer, nullable, required: Whole years from `dob`; null when unknown.
    - `career_stats` object, required
      - `a` CareerStatRow[], required
        - `scope` string, required: `pro-mma`, `amateur-mma`, `pro-kickboxing`, …, or `ufc-only` / `bkfc-only` / `one-only`.
        - `source` string, required: Who published the record: `ufc-stats` (ufcstats.com), a promotion's own site (`ufc-official`, `bkfc-official`, `one-official`, `oktagon-official`, …), `ufcalendar` (derived by UFCalendar), or `public-records` (the complete multi-promotion career record compiled from public records).
        - `record` string, nullable, required
        - `slpm` string, nullable, required: Significant strikes landed per minute. Display string (`"1.34"`, `"42%"`).
        - `str_acc` string, nullable, required: Significant-strike accuracy. Display string (`"1.34"`, `"42%"`).
        - `sapm` string, nullable, required: Significant strikes absorbed per minute. Display string (`"1.34"`, `"42%"`).
        - `str_def` string, nullable, required: Significant-strike defence. Display string (`"1.34"`, `"42%"`).
        - `td_avg` string, nullable, required: Takedowns landed per 15 minutes. Display string (`"1.34"`, `"42%"`).
        - `td_acc` string, nullable, required: Takedown accuracy. Display string (`"1.34"`, `"42%"`).
        - `td_def` string, nullable, required: Takedown defence. Display string (`"1.34"`, `"42%"`).
        - `sub_avg` string, nullable, required: Submission attempts per 15 minutes. Display string (`"1.34"`, `"42%"`).
        - `updated_at` string, date-time, nullable: Present on `GET /v1/fighters/{idOrSlug}/stats` rows and `/v1/compare` `career_stats` only.
      - `b` CareerStatRow[], required
        - `scope` string, required: `pro-mma`, `amateur-mma`, `pro-kickboxing`, …, or `ufc-only` / `bkfc-only` / `one-only`.
        - `source` string, required: Who published the record: `ufc-stats` (ufcstats.com), a promotion's own site (`ufc-official`, `bkfc-official`, `one-official`, `oktagon-official`, …), `ufcalendar` (derived by UFCalendar), or `public-records` (the complete multi-promotion career record compiled from public records).
        - `record` string, nullable, required
        - `slpm` string, nullable, required: Significant strikes landed per minute. Display string (`"1.34"`, `"42%"`).
        - `str_acc` string, nullable, required: Significant-strike accuracy. Display string (`"1.34"`, `"42%"`).
        - `sapm` string, nullable, required: Significant strikes absorbed per minute. Display string (`"1.34"`, `"42%"`).
        - `str_def` string, nullable, required: Significant-strike defence. Display string (`"1.34"`, `"42%"`).
        - `td_avg` string, nullable, required: Takedowns landed per 15 minutes. Display string (`"1.34"`, `"42%"`).
        - `td_acc` string, nullable, required: Takedown accuracy. Display string (`"1.34"`, `"42%"`).
        - `td_def` string, nullable, required: Takedown defence. Display string (`"1.34"`, `"42%"`).
        - `sub_avg` string, nullable, required: Submission attempts per 15 minutes. Display string (`"1.34"`, `"42%"`).
        - `updated_at` string, date-time, nullable: Present on `GET /v1/fighters/{idOrSlug}/stats` rows and `/v1/compare` `career_stats` only.
    - `aggregates` object, required
      - `a` CompareAggregates, required
        - `fights_analyzed` integer, required: Completed bouts with per-fight totals; 0 ⇒ every other field is null.
        - `avg_sig_strikes` number, nullable, required
        - `avg_takedowns` number, nullable, required
        - `avg_control_time_sec` integer, nullable, required
        - `max_sig_strikes` integer, nullable, required
        - `max_takedowns` integer, nullable, required
        - `location_pct` object, nullable, required: Significant-strike target mix, whole percents.
          - `head` integer, required
          - `body` integer, required
          - `leg` integer, required
        - `position_pct` object, nullable, required: Significant-strike position mix, whole percents.
          - `distance` integer, required
          - `clinch` integer, required
          - `ground` integer, required
      - `b` CompareAggregates, required
        - `fights_analyzed` integer, required: Completed bouts with per-fight totals; 0 ⇒ every other field is null.
        - `avg_sig_strikes` number, nullable, required
        - `avg_takedowns` number, nullable, required
        - `avg_control_time_sec` integer, nullable, required
        - `max_sig_strikes` integer, nullable, required
        - `max_takedowns` integer, nullable, required
        - `location_pct` object, nullable, required: Significant-strike target mix, whole percents.
          - `head` integer, required
          - `body` integer, required
          - `leg` integer, required
        - `position_pct` object, nullable, required: Significant-strike position mix, whole percents.
          - `distance` integer, required
          - `clinch` integer, required
          - `ground` integer, required
    - `recent_form` object, required: The last five SETTLED entries of each merged timeline.
      - `a` HistoryEntry[], required
        - `source` 'native' | 'history', required: `native` = a bout UFCalendar tracks (richest data); `history` = a career row from the wider multi-promotion record.
        - `fight_id` integer, nullable, required
        - `event_id` integer, nullable, required
        - `event_title` string, nullable, required
        - `event_name` string, nullable, required: Same as `event_title`.
        - `event_slug` string, nullable, required
        - `org_slug` string, nullable, required
        - `date` string, date, nullable, required: `native` rows: the UTC calendar day of the event's `starts_at` (first bell) — an evening card in the Americas starts after midnight UTC, so it can read one day after the venue's local date. `history` rows carry no time, only the date as the publisher printed it (usually the venue's local date).
        - `opponent_id` integer, nullable, required
        - `opponent_name` string, nullable, required
        - `opponent_slug` string, nullable, required
        - `opponent` HistoryOpponent, required
          - `id` integer, nullable, required
          - `slug` string, nullable, required
          - `name` string, nullable, required
        - `result` string, nullable, required: Raw result (`win`, `loss`, `draw`, `nc`, `no_contest`, `cancelled`, …). Prefer `status`.
        - `status` 'win' | 'loss' | 'draw' | 'no_contest' | 'cancelled' | 'upcoming' | 'unknown', required: One status vocabulary across native and history rows.
        - `method` string, nullable, required
        - `method_normalized` 'ko_tko' | 'submission' | 'technical_submission' | 'decision_unanimous' | 'decision_split' | 'decision_majority' | 'decision' | 'draw' | 'no_contest' | 'dq' | 'other', required: Closed vocabulary over every source spelling of a result method (`normalize.ts`). `other` = a non-empty method nothing matched.
        - `round` integer, nullable, required
        - `time` string, nullable, required
        - `time_seconds` integer, nullable, required
        - `weight_class` string, nullable, required
        - `is_title` boolean, nullable, required
        - `sport` string, nullable, required
        - `competition_level` string, nullable, required: `pro`, `amateur`, … (native rows are `pro`).
        - `source_slug` string, nullable, required: Who published the row: `ufcalendar` for native bouts; on history rows an official publisher's slug (`ufc-official`, `wikipedia`, a promotion's `*-official`), else `public-records`.
      - `b` HistoryEntry[], required
        - `source` 'native' | 'history', required: `native` = a bout UFCalendar tracks (richest data); `history` = a career row from the wider multi-promotion record.
        - `fight_id` integer, nullable, required
        - `event_id` integer, nullable, required
        - `event_title` string, nullable, required
        - `event_name` string, nullable, required: Same as `event_title`.
        - `event_slug` string, nullable, required
        - `org_slug` string, nullable, required
        - `date` string, date, nullable, required: `native` rows: the UTC calendar day of the event's `starts_at` (first bell) — an evening card in the Americas starts after midnight UTC, so it can read one day after the venue's local date. `history` rows carry no time, only the date as the publisher printed it (usually the venue's local date).
        - `opponent_id` integer, nullable, required
        - `opponent_name` string, nullable, required
        - `opponent_slug` string, nullable, required
        - `opponent` HistoryOpponent, required
          - `id` integer, nullable, required
          - `slug` string, nullable, required
          - `name` string, nullable, required
        - `result` string, nullable, required: Raw result (`win`, `loss`, `draw`, `nc`, `no_contest`, `cancelled`, …). Prefer `status`.
        - `status` 'win' | 'loss' | 'draw' | 'no_contest' | 'cancelled' | 'upcoming' | 'unknown', required: One status vocabulary across native and history rows.
        - `method` string, nullable, required
        - `method_normalized` 'ko_tko' | 'submission' | 'technical_submission' | 'decision_unanimous' | 'decision_split' | 'decision_majority' | 'decision' | 'draw' | 'no_contest' | 'dq' | 'other', required: Closed vocabulary over every source spelling of a result method (`normalize.ts`). `other` = a non-empty method nothing matched.
        - `round` integer, nullable, required
        - `time` string, nullable, required
        - `time_seconds` integer, nullable, required
        - `weight_class` string, nullable, required
        - `is_title` boolean, nullable, required
        - `sport` string, nullable, required
        - `competition_level` string, nullable, required: `pro`, `amateur`, … (native rows are `pro`).
        - `source_slug` string, nullable, required: Who published the row: `ufcalendar` for native bouts; on history rows an official publisher's slug (`ufc-official`, `wikipedia`, a promotion's `*-official`), else `public-records`.
    - `win_streak` object, required
      - `a` integer, required
      - `b` integer, required
    - `head_to_head` CompletedFightRef[], required: Previous meetings, from `a`'s side.
      - `fight_id` integer, required
      - `event` object, required
        - `id` integer, required
        - `slug` string, required
        - `title` string, required
        - `starts_at` string, date-time, required
      - `weight_class` string, nullable, required
      - `is_title` boolean, required
      - `is_main` boolean, required
      - `opponent` object, nullable, required
        - `id` integer, required
        - `name` string, nullable, required
        - `slug` string, nullable, required
      - `outcome` 'win' | 'loss' | 'draw' | 'nc', required: From THIS fighter's side.
      - `winner_fighter_id` integer, nullable, required
      - `method` string, nullable, required
      - `round` integer, nullable, required
      - `time` string, nullable, required
    - `common_opponents` object[], required: Up to 5.
      - `opponent` object, required
        - `id` integer, required
        - `name` string, required
        - `slug` string, nullable, required
      - `a_fight` CompletedFightRef, required: One completed bout from one fighter's side (`head_to_head`, `common_opponents`).
        - `fight_id` integer, required
        - `event` object, required
          - `id` integer, required
          - `slug` string, required
          - `title` string, required
          - `starts_at` string, date-time, required
        - `weight_class` string, nullable, required
        - `is_title` boolean, required
        - `is_main` boolean, required
        - `opponent` object, nullable, required
          - `id` integer, required
          - `name` string, nullable, required
          - `slug` string, nullable, required
        - `outcome` 'win' | 'loss' | 'draw' | 'nc', required: From THIS fighter's side.
        - `winner_fighter_id` integer, nullable, required
        - `method` string, nullable, required
        - `round` integer, nullable, required
        - `time` string, nullable, required
      - `b_fight` CompletedFightRef, required: One completed bout from one fighter's side (`head_to_head`, `common_opponents`).
        - `fight_id` integer, required
        - `event` object, required
          - `id` integer, required
          - `slug` string, required
          - `title` string, required
          - `starts_at` string, date-time, required
        - `weight_class` string, nullable, required
        - `is_title` boolean, required
        - `is_main` boolean, required
        - `opponent` object, nullable, required
          - `id` integer, required
          - `name` string, nullable, required
          - `slug` string, nullable, required
        - `outcome` 'win' | 'loss' | 'draw' | 'nc', required: From THIS fighter's side.
        - `winner_fighter_id` integer, nullable, required
        - `method` string, nullable, required
        - `round` integer, nullable, required
        - `time` string, nullable, required
    - `booked_bout` object, nullable, required
      - `fight_id` integer, required
      - `event` object, required
        - `id` integer, required
        - `slug` string, required
        - `title` string, required
        - `org` string, required
        - `starts_at` string, date-time, nullable, required
      - `weight_class` string, nullable, required
      - `is_title` boolean, required
      - `fighter_a_id` integer, required: Stored corner order — not necessarily `a`.
      - `fighter_b_id` integer, required
    - `prediction` object, nullable, required: UFC only, and only while the stored corner stamp matches the booked bout.
      - `win_probability_a` number, required: Oriented to compare's `a`.
      - `win_probability_b` number, required
      - `model_version` string, nullable, required
      - `generated_at` string, date-time, nullable, required
    - `power_index` object, required
      - `a` ComparePowerIndex, required
        - `rating` integer, required: Rounded.
        - `peak` integer, required: Rounded.
        - `peak_at` string, date, nullable, required
        - `fights_rated` integer, required
        - `last_fought_at` string, date, nullable, required
      - `b` ComparePowerIndex, required
        - `rating` integer, required: Rounded.
        - `peak` integer, required: Rounded.
        - `peak_at` string, date, nullable, required
        - `fights_rated` integer, required
        - `last_fought_at` string, date, nullable, required
      - `win_probability_a` number, nullable, required: From the two ratings; null when either is missing.
  - `meta` object, required
    - `note` string, required
    - `resolved` object: Present when `a` or `b` was a retired slug that was followed.
      - `a` object
        - `requested` string, required
        - `slug` string, required
      - `b` object
        - `requested` string, required
        - `slug` string, required
    - `ignored_params` string[]: Present only when the request carried query parameters this endpoint does not take — they were ignored. Same list as the `X-UFCalendar-Ignored-Params` header. Sorted, unique.

## Other responses

- `304`: Not Modified — `If-None-Match` matched the current weak `ETag`. Empty body.
- `400`: Invalid input (`invalid_query`). `a` and `b` are both required and must differ.
- `401`: Missing/invalid API key (`unauthorized`).
- `403`: No active plan on the key's account (`subscription_required`) — choose a plan or start the free 1-day trial at https://www.ufcalendar.com/account/api.
- `404`: Not found (`not_found`; staged-org data 404s until the org is promoted).
- `429`: Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`.
- `500`: Something broke on our side (`internal_error`). It has been logged under the `request_id`.

---

[API](https://skmtc.dev/ufcalendar/apis/ufcalendar-fight-api.md) · [All operations](https://skmtc.dev/ufcalendar/apis/ufcalendar-fight-api/llms.txt) · [OpenAPI document](https://skmtc.dev/ufcalendar/apis/ufcalendar-fight-api/revisions/9623cc8fb70b?raw)
