{"openapi":"3.1.0","info":{"title":"UFCalendar Fight API","version":"1.0.0","description":"Fight data API by [UFCalendar](https://www.ufcalendar.com) — MMA + bare-knuckle boxing: events, full cards, results,\nper-fight and per-round statistics, fighters with complete multi-promotion careers,\nofficial rankings history (UFC 2013→), UFCalendar Power Index ratings, AI win\nprobabilities and per-country broadcast rights — for **UFC, PFL, OKTAGON and BKFC**.\n\nKeys live at [ufcalendar.com/account/api](https://www.ufcalendar.com/account/api) — an active plan or the free 1-day trial (100 requests, no card) is required.\nPlans and quotas: [ufcalendar.com/developers](https://www.ufcalendar.com/developers).\n\nConventions: snake_case JSON in a `{\"data\": ..., \"meta\": ...}` envelope; cursor\npagination; UTC ISO-8601 timestamps plus venue IANA `tz`; errors as\n`{\"error\": {\"code\", \"message\", \"request_id\"}}`; monthly-quota headers\n`X-RateLimit-Limit/-Remaining/-Reset` and `Retry-After` on 429.\n\nNo betting odds are served, by design. Fighter images are Wikimedia Commons/CC\nonly — the `license`/`artist` fields you receive MUST be displayed as a credit.\nNot affiliated with UFC/Zuffa/TKO or any promotion.","contact":{"name":"UFCalendar","email":"api@ufcalendar.com","url":"https://www.ufcalendar.com/developers"},"termsOfService":"https://www.ufcalendar.com/developers/terms"},"servers":[{"url":"https://api.ufcalendar.com"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key, e.g. `Authorization: Bearer ufcalendar_ab12…`"}}},"tags":[{"name":"Orgs"},{"name":"Events"},{"name":"Fights"},{"name":"Fighters"},{"name":"Rankings"},{"name":"Power Index"},{"name":"Predictions"},{"name":"Broadcast"},{"name":"Search"},{"name":"Account"}],"paths":{"/v1/orgs":{"get":{"tags":["Orgs"],"summary":"List launch orgs with capability flags","description":"Each org carries flags (`stats`, `rounds`, `rankings`, `broadcasts`, `predictions`, `scorecards`) so clients discover coverage programmatically — plus `sport` (`mma`, `bare-knuckle-boxing`). Staged orgs (ONE, KSW, RIZIN, ACA) appear the day they clear the reliability bar.","parameters":[],"responses":{"200":{"description":"Launch orgs","content":{"application/json":{"example":{"data":[{"id":1,"slug":"ufc","name":"Ultimate Fighting Championship","short_name":"UFC","country":"United States","website":"https://www.ufc.com","capabilities":{"stats":true,"rounds":true,"rankings":true,"broadcasts":true,"predictions":true,"scorecards":false}}]}}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/orgs/{slug}":{"get":{"tags":["Orgs"],"summary":"One org","description":"Single org by slug.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Org","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/events":{"get":{"tags":["Events"],"summary":"List events (schedule + results)","description":"A bare listing is the upcoming calendar: events from the last ~6h onward, soonest first. Ordering defaults: explicit `order` always wins; else `from=` or a forward status (`announced|scheduled|live`) → `asc`; else (`completed|cancelled|to=`) → `desc`, newest first. `order=desc` with no filters browses the full archive newest-first. Live results land within ≤5 minutes (UFC ≤2).","parameters":[{"name":"org","in":"query","required":false,"description":"Launch org slug: `ufc`, `pfl`, `oktagon` or `bkfc`. Staged orgs 400 until promoted.","schema":{"type":"string","enum":["ufc","pfl","oktagon","bkfc"]}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["announced","scheduled","live","completed","cancelled"]}},{"name":"from","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]},"description":"Sort by start time. Defaults are contextual — see endpoint description."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from `meta.pagination.next_cursor`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"Events page","content":{"application/json":{"example":{"data":[{"id":812,"slug":"ufc-320","title":"UFC 320","numbering":"UFC 320","org":"ufc","sport":"mma","starts_at":"2026-10-04T02:00:00.000Z","main_card_at":"2026-10-04T02:00:00.000Z","tz":"America/Los_Angeles","status":"scheduled","is_ppv":true,"is_title_card":true}],"meta":{"pagination":{"next_cursor":"eyJpZCI6ODEyfQ","has_more":true}}}}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/events/{idOrSlug}":{"get":{"tags":["Events"],"summary":"Event with full card","description":"Full fight card (both corners, results when completed), venue and event-scoped broadcast rows. Every event and card entry carries `sport` (e.g. `mma`, `bare-knuckle-boxing`). Renamed events 308-redirect from stale slugs.","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric id or slug of the event. Stale slugs 308-redirect to the canonical URL."}],"responses":{"200":{"description":"Event detail","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/events/{idOrSlug}/changes":{"get":{"tags":["Events"],"summary":"Card-change log","description":"The diff log behind \"card updated\": fight added/removed, opponent swapped, card order or date moved. Each entry has `kind`, `before`, `after`, `observed_at`.","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric id or slug of the event. Stale slugs 308-redirect to the canonical URL."}],"responses":{"200":{"description":"Change entries","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fights/{id}":{"get":{"tags":["Fights"],"summary":"One bout","description":"Bout with corners, `sport` (bout override, else the org sport), result (method/round/time/referee) and bonus flags.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Fight","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fights/{id}/stats":{"get":{"tags":["Fights"],"summary":"Per-fight totals","description":"Both corners: knockdowns, significant/total strikes, takedowns, submission attempts, reversals, control time, and target/position splits (head/body/leg, distance/clinch/ground) where the source provides them. `distance_time_sec`, `clinch_time_sec`, `ground_time_sec` (integers, nullable) are seconds spent at distance / in the clinch / on the ground — Sofascore-sourced, and can appear alongside official strike counts on any org (Sofascore fills position time even where another source owns the rest of the row).","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Stat lines","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fights/{id}/rounds":{"get":{"tags":["Fights"],"summary":"Round-by-round stats","description":"Per-round stat lines for both corners, including target/position splits (head/body/leg, distance/clinch/ground) where the source logs them per round (BKFC for head/body/distance/clinch; Sofascore additionally for leg/ground). `distance_time_sec`, `clinch_time_sec`, `ground_time_sec` (integers, nullable) are seconds spent at distance / in the clinch / on the ground, per round — Sofascore-sourced.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Round lines","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fighters":{"get":{"tags":["Fighters"],"summary":"Roster search","description":"Fighters with at least one launch-org fight (~4.5k). `q` is accent-insensitive.","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"org","in":"query","required":false,"description":"Launch org slug: `ufc`, `pfl`, `oktagon` or `bkfc`. Staged orgs 400 until promoted.","schema":{"type":"string","enum":["ufc","pfl","oktagon","bkfc"]}},{"name":"country","in":"query","required":false,"schema":{"type":"string"},"description":"ISO-2 code or country name."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from `meta.pagination.next_cursor`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":25}}],"responses":{"200":{"description":"Fighters page","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fighters/{idOrSlug}":{"get":{"tags":["Fighters"],"summary":"Fighter profile","description":"Bio, per-scope career records, UFCalendar Power Index summary, and CC-licensed images with attribution metadata (displaying the credit is a license requirement).","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric id or slug of the fighter. Stale slugs 308-redirect to the canonical URL."}],"responses":{"200":{"description":"Fighter detail","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fighters/{idOrSlug}/history":{"get":{"tags":["Fighters"],"summary":"Complete career timeline","description":"The fighter's FULL multi-promotion career: native tracked bouts (richest data, `source: \"native\"`) merged with fill-source history rows (`source: \"history\"`). Spans every promotion they fought in — not just launch orgs.","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric id or slug of the fighter. Stale slugs 308-redirect to the canonical URL."}],"responses":{"200":{"description":"Timeline entries, newest first","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fighters/{idOrSlug}/stats":{"get":{"tags":["Fighters"],"summary":"Career statistics","description":"Per-scope career stats (`pro-mma`, `amateur-mma`, …): record, strikes landed/absorbed per minute, accuracy/defense, takedown and submission averages. Scope `tracked` rows are computed by UFCalendar from per-fight totals when no scraped panel carries data (e.g. Contender Series debutants, PFL/OKTAGON rosters); their `record` is always null.","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric id or slug of the fighter. Stale slugs 308-redirect to the canonical URL."}],"responses":{"200":{"description":"Career stat rows","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fighters/{idOrSlug}/rankings":{"get":{"tags":["Fighters"],"summary":"Ranking history","description":"Official-board rows over time (org, board, division, snapshot_date, rank). Rank 0 = champion.","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric id or slug of the fighter. Stale slugs 308-redirect to the canonical URL."}],"responses":{"200":{"description":"Ranking rows","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/fighters/{idOrSlug}/power-index":{"get":{"tags":["Fighters"],"summary":"Power Index trajectory","description":"Per-bout rating history from the UFCalendar Power Index engine (rating before/after, model win probability, outcome).","parameters":[{"name":"idOrSlug","in":"path","required":true,"schema":{"type":"string"},"description":"Numeric id or slug of the fighter. Stale slugs 308-redirect to the canonical URL."}],"responses":{"200":{"description":"Rating points","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/rankings/{org}":{"get":{"tags":["Rankings"],"summary":"Official board (point-in-time)","description":"**The time machine**: pass `?date=YYYY-MM-DD` for the board as it stood on any date (UFC official back to 2013, 543 snapshots). A snapshot is valid until superseded. Rank 0 = champion; P4P has no rank 0.","parameters":[{"name":"org","in":"path","required":true,"schema":{"type":"string","enum":["ufc","pfl","oktagon","bkfc"]}},{"name":"date","in":"query","required":false,"schema":{"type":"string","format":"date"}},{"name":"board","in":"query","required":false,"schema":{"type":"string","default":"official"},"description":"Default `official` (for UFC that is the media-panel vote ufc.com publishes). UFC additionally has `meta`."}],"responses":{"200":{"description":"Board grouped by division","content":{"application/json":{"example":{"data":{"org":"ufc","board":"official","snapshot_date":"2016-11-14","divisions":[{"division":"Lightweight","entries":[{"rank":0,"is_champion":true,"fighter_id":3021,"fighter_slug":"conor-mcgregor","name":"Conor McGregor"}]}]}}}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/rankings/{org}/{division}":{"get":{"tags":["Rankings"],"summary":"One division","description":"Same as the board endpoint, filtered to a division (`lightweight`, `womens-strawweight`, `pound-for-pound`, …).","parameters":[{"name":"org","in":"path","required":true,"schema":{"type":"string"}},{"name":"division","in":"path","required":true,"schema":{"type":"string"}},{"name":"date","in":"query","required":false,"schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Division entries","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/champions":{"get":{"tags":["Rankings"],"summary":"Current champions","description":"Rank-0 rows of each launch org's latest official board.","parameters":[],"responses":{"200":{"description":"Champions","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/power-index/{org}":{"get":{"tags":["Power Index"],"summary":"Power Index board","description":"Top-rated active fighters whose latest bout was in this org, by the UFCalendar Power Index (our own rating engine, hourly refresh).","parameters":[{"name":"org","in":"path","required":true,"schema":{"type":"string","enum":["ufc","pfl","oktagon","bkfc"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"default":50}}],"responses":{"200":{"description":"Board rows","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/predictions/upcoming":{"get":{"tags":["Predictions"],"summary":"Model win probabilities (UFC)","description":"UFCalendar model win probabilities for upcoming UFC bouts, refreshed every 30 minutes. Corner-guarded: a probability is only served while the stored pair matches the bout's current pair — a late opponent swap removes the row rather than mislabeling it. Not betting advice.","parameters":[],"responses":{"200":{"description":"Predictions","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/broadcast-rights/{org}":{"get":{"tags":["Broadcast"],"summary":"Who airs it, per country","description":"Org-level standing media rights per country (PFL harvested weekly across 212 countries; UFC ~110 curated). `WORLD` rows apply globally.","parameters":[{"name":"org","in":"path","required":true,"schema":{"type":"string"}},{"name":"country","in":"query","required":false,"schema":{"type":"string"},"description":"ISO-2 country code."}],"responses":{"200":{"description":"Rights rows","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/venues/{id}":{"get":{"tags":["Events"],"summary":"Venue","description":"Venue with city, country, coordinates, capacity and IANA tz.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Venue","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/search":{"get":{"tags":["Search"],"summary":"Typeahead search","description":"Accent-insensitive search across roster fighters and events. Great for building pickers.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2}}],"responses":{"200":{"description":"Matches","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/calendar/{org}.ics":{"get":{"tags":["Events"],"summary":"ICS calendar feed","description":"Subscribe your calendar app to an org's schedule. Calendar apps can't send headers, so pass the key as `?key=`. Refresh hourly at most.","parameters":[{"name":"org.ics","in":"path","required":true,"schema":{"type":"string"},"description":"`ufc.ics`, `pfl.ics`, `oktagon.ics` or `bkfc.ics`"},{"name":"key","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"text/calendar VEVENT feed of upcoming events"},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/webhook-endpoints":{"get":{"tags":["Account"],"summary":"List your webhook endpoints","description":"Pro and above. Counts as one request against your quota; the deliveries themselves do not.","parameters":[],"responses":{"200":{"description":"Endpoints","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"Requires Pro or above"},"404":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}},"post":{"tags":["Account"],"summary":"Register a webhook endpoint","description":"Pro+. Body: `{\"url\": \"https://...\", \"events\": [\"event.announced\", \"fight.result\", \"card.changed\", \"event.completed\"]}`. Subscribe to `event.announced` and you do not need to poll `/v1/events` to discover new cards — it fires once, within a minute of a card first landing in our data, and carries the same event object the list endpoint returns. The response contains the signing `secret` ONCE. Deliveries carry `X-UFCalendar-Signature: t=<unix>,v1=<hmac>` where the HMAC-SHA256 input is `\"<t>.<rawBody>\"`. **Verify the timestamp too**: reject anything where `|now - t|` exceeds 300 seconds, otherwise a captured delivery can be replayed at you forever with a valid HMAC. Delivery is at-least-once — deduplicate on the event body, and expect a retry roughly every 60s until your endpoint returns 2xx. Endpoints auto-disable after 20 consecutive failures, and you may hold at most 3 active endpoints. Latency: results are dispatched within ~1 minute of our scrapers writing them. `event.announced` only fires for cards that have not started yet, so archive backfills never reach you as new-card noise. Deliveries are free — they never count against your monthly request quota, only the calls you make to manage endpoints do.","responses":{"201":{"description":"Created — includes the one-time secret"},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"Requires Pro or above"},"404":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/webhook-endpoints/{id}":{"delete":{"tags":["Account"],"summary":"Delete a webhook endpoint","description":"Pro and above.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"Requires Pro or above"},"404":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/webhook-endpoints/{id}/rotate-secret":{"post":{"tags":["Account"],"summary":"Rotate an endpoint signing secret","description":"Pro and above. Issues a fresh `whsec_` secret for the endpoint and returns it ONCE, keeping the endpoint id and its delivery history. The previous secret stops verifying the moment this returns, so deploy the new one to your receiver first (or accept both during the cutover). Use this instead of delete-and-recreate when a secret leaks.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Rotated — includes the new one-time secret"},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"Requires Pro or above"},"404":{"description":"No such endpoint on this account"},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/bulk/{kind}":{"get":{"tags":["Account"],"summary":"Bulk snapshot (Enterprise only)","description":"Enterprise only — the full dataset is licensed, not self-serve; contact api@ufcalendar.com. Downloads the full launch-scope dataset as gzipped JSON: `events.json.gz`, `fights.json.gz` or `fighters.json.gz`. Responds 302 to a presigned URL; snapshots regenerate at most every 6 hours. One request per download (the redirect is free).","parameters":[{"name":"kind","in":"path","required":true,"schema":{"type":"string","enum":["events.json.gz","fights.json.gz","fighters.json.gz"]}}],"responses":{"302":{"description":"Redirect to a time-limited download URL"},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"Requires an Enterprise agreement"},"404":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}},"/v1/usage":{"get":{"tags":["Account"],"summary":"Your quota usage","description":"Current-month usage for the calling key: tier, requests used/limit, rpm limit, reset.","parameters":[],"responses":{"200":{"description":"Usage","content":{"application/json":{"example":{"data":{"tier":"pro","month":"202608","requests_used":1204,"requests_limit":50000,"rpm_limit":120,"reset":1756684800}}}}},"401":{"description":"Missing/invalid API key. `{\"error\":{\"code\":\"unauthorized\",...}}`"},"403":{"description":"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":{"description":"Not found (staged-org data 404s until the org is promoted)."},"429":{"description":"Rate limited (`rate_limited`) or monthly quota reached (`quota_exceeded`). Honor `Retry-After`."}}}}}}