How do I get the judges' scorecards for a UFC decision?
Request the bout's scorecards from the MMA Fight Data API, api.fight_scorecards(fight_id) in Python. You get the decision type, any point deductions and one card per judge, with the judge's name, a score for every round and the card totals, oriented to fighter_a and fighter_b. It is the official commission record, back to 1995 for the UFC.
Free plan: 1,000 requests a month, no card. Paid plans from $19/mo.
Endpoints used
| Method & path | What it returns | Plan |
|---|---|---|
GET /v1/fights/{id}/scorecards | Judges' scorecards for any bout: every official, their score for each round, card totals, decision type and point deductions. | All plans |
GET /v1/scorecards/splits | Split and majority decisions, newest first, with every judge's card and the dissenting judges named. | All plans |
GET /v1/judges/{id}/scorecards | Every card a single official has turned in, newest first, with the bout and event attached. | All plans |
GET /v1/judges | Judge directory with career shape: fights worked, rounds scored, 10-8s, split cards and lone dissents. | All plans |
The code
curl and Python read the three cards from Petr Yan vs Merab Dvalishvili; Python also lists the latest split decisions with the dissenting judge. The JavaScript block walks one judge's cards next to the other two judges.
Every block runs as shown with your API key in the UFCAL_API_KEY environment variable. Python uses pip install ufcalendar and JavaScript or TypeScript uses npm install @ufcalendar/sdk; any HTTP client works too.
curl "https://api.ufcalendar.com/v1/fights/83680/scorecards" \
-H "Authorization: Bearer $UFCAL_API_KEY"# pip install ufcalendar
from ufcalendar import FightAPI
api = FightAPI() # reads UFCAL_API_KEY from the environment
sc = api.fight_scorecards(83680) # Petr Yan vs Merab Dvalishvili, UFC 333
print("decision:", sc["decision_type"], "| deductions:", sc["deductions"] or "none")
for card in sc["cards"]:
if not card["scores_known"]: # older bouts: the outcome only, no numbers
print(card["judge_name"], "- outcome only")
continue
rounds = " ".join(f"{r['a']}-{r['b']}" for r in card["rounds"])
print(f"{card['judge_name']:<16} {card['total_a']}-{card['total_b']} {rounds}")
# The latest UFC split decisions, with the judge who dissented
for bout in api.split_decisions("ufc", limit=3):
for j in bout["dissenting_judges"]:
print(bout["event"]["title"], "|", bout["fighter_a"]["name"], "vs", bout["fighter_b"]["name"],
"| dissent:", j["judge_name"], f"{j['total_a']}-{j['total_b']}")// npm install @ufcalendar/sdk
import { FightAPI } from "@ufcalendar/sdk";
const api = new FightAPI(); // reads UFCAL_API_KEY from the environment
// Every card one judge turned in, newest first, next to the other two judges
for await (const row of api.judgeScorecards(36, { limit: 10 })) {
if (!row.decision_type) continue; // stopped early: cards for the completed rounds only, no totals
const mine = `${row.card.total_a}-${row.card.total_b}`;
const others = row.colleagues.map((c) => `${c.total_a}-${c.total_b}`).join(", ");
console.log(row.event.title, "|", row.decision_type, "|", mine, "| others:", others, row.lone_dissent ? "(lone dissent)" : "");
}Sample response
A real response from the live API, trimmed for length. … marks removed fields.
{
"data": {
"fight_id": 83680,
"fighter_a_id": 360,
"fighter_b_id": 194,
"decision_type": "unanimous",
"deductions": [],
"cards": [
{
"judge_id": 3,
"judge_name": "David Lethaby",
"total_a": 48,
"total_b": 47,
"winner_fighter_id": 360,
"is_draw": false,
"scores_known": true,
"rounds": [
{ "round": 1, "a": 9, "b": 10 },
{ "round": 2, "a": 9, "b": 10 },
{ "round": 3, "a": 10, "b": 9 },
{ "round": 4, "a": 10, "b": 9 },
{ "round": 5, "a": 10, "b": 9 }
]
},
…
]
},
"meta": { "fight_id": 83680 }
}Notes and pitfalls
- In each round, a is fighter_a's score and b is fighter_b's. winner_fighter_id on a card is the fighter that judge scored the bout for, which on a split decision is not always the official winner.
- scores_known false means the commission published only the outcome, as on many older bouts: the totals are placeholders and rounds is empty, so skip those cards when you chart.
- A bout stopped inside the distance can still return the cards for the completed rounds, with decision_type and the totals null, and a bout with no cards at all returns 404. Check decision_type before you read totals.
- These are the judges' official cards only: no media scores and no fan scoring. BKFC publishes no commission cards; check capabilities.scorecards for each promotion.
Related pages
More code guides
UFCalendar is an independent publication, not affiliated with UFC/Zuffa/TKO, PFL, OKTAGON MMA, BKFC, RIZIN FF or any promotion. Organization names are used to describe the data. Terms of service · Refund Policy