{"openapi":"3.1.0","info":{"title":"MCLadder Developer API","version":"1.0.0","description":"Read-only v1. All DTOs use anonymous-public visibility regardless of cookies or partner keys. Optional keys grant scopes and managed quotas, not player/admin access. Unknown parameters fail closed. Responses use Cache-Control: no-store so shared caches cannot bypass admission or retain retired profiles. Browser CORS does not allow credentials. No writes, wallets, inventories, administrative or game-auth APIs are part of this contract."},"servers":[{"url":"https://mcladder.com/api/v1","description":"Public API (availability controlled by deployment)"}],"tags":[{"name":"players","description":"Public player profiles"},{"name":"leaderboard","description":"Current public leaderboard"},{"name":"matches","description":"Completed public matches"},{"name":"seasons","description":"Season metadata"},{"name":"catalogs","description":"Public presentation catalogs"},{"name":"live","description":"Anonymous aggregate player-presence snapshot; no player identities or game stream"}],"paths":{"/players/{player}":{"get":{"operationId":"getPlayer","tags":["players"],"summary":"Get a public player profile","description":"Deleted profiles return 404. Calibration redacts Elo, peak and rank. Presence, premium expiry, private settings, bans and admin fields are excluded. Name/country follow public profile policy.","x-required-scope":"players:read","parameters":[{"name":"player","in":"path","required":true,"description":"Canonical dashed UUID or known Minecraft username (1–16 letters/digits/underscores). DB identity lookup only, no external account discovery.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|[A-Za-z0-9_]{1,16})$"}}],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Player"}}},"example":{"data":{"uuid":"01234567-89ab-cdef-0123-456789abcdef","name":"ExamplePlayer","country":null,"rating":{"elo":null,"peak":null,"rank":null,"calibrating":true,"gamesLeft":3},"records":{"overall":{"wins":1,"draws":0,"losses":1},"solo":{"wins":1,"draws":0,"losses":1},"duo":{"wins":0,"draws":0,"losses":0}},"joinedAt":null,"updatedAt":null}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/leaderboard":{"get":{"operationId":"getLeaderboard","tags":["leaderboard"],"summary":"Get current public leaderboard","description":"Current global season/live rating only. Shared eligibility requires both calibration and leaderboard minimum games; hidden/deleted players are excluded. Stable tie-breakers: Elo, peak Elo, wins, UUID. Country filtering re-numbers places within that country. There is no archived season leaderboard in v1.","x-required-scope":"leaderboard:read","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size. Unknown and repeated parameters are rejected.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","required":false,"description":"Offset in current ordering; live data may move between requests. Deep exports are intentionally unavailable.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}},{"name":"country","in":"query","required":false,"description":"Public country code, e.g. RU, DE, or supported custom region RU-TA. Unknown codes are rejected; omit for all countries.","schema":{"type":"string","pattern":"^(?:[A-Za-z]{2}|[Rr][Uu]-[Tt][Aa])$"},"example":"DE"}],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LeaderboardEntry"},"maxItems":100},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"example":{"data":[],"pagination":{"limit":25,"offset":0,"hasMore":false,"nextOffset":null}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/players/{player}/matches":{"get":{"operationId":"getPlayerMatches","tags":["matches"],"summary":"List a player's completed public matches","description":"Anonymous privacy always applies, even with an owner/admin cookie or partner key. Hidden premium history returns an empty page with hidden=true. Deleted profiles return 404. Pending verification, pending review, annulled and incomplete matches are excluded. Historical rating visibility is preserved; no seed, replay, inventory or raw event metadata.","x-required-scope":"matches:read","parameters":[{"name":"player","in":"path","required":true,"description":"Canonical dashed UUID or known Minecraft username (1–16 letters/digits/underscores). DB identity lookup only, no external account discovery.","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}|[A-Za-z0-9_]{1,16})$"}},{"name":"limit","in":"query","required":false,"description":"Page size. Unknown and repeated parameters are rejected.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","required":false,"description":"Offset in current ordering; live data may move between requests. Deep exports are intentionally unavailable.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","pagination","hidden"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Match"},"maxItems":100},"pagination":{"$ref":"#/components/schemas/Pagination"},"hidden":{"type":"boolean"}}},"example":{"data":[],"pagination":{"limit":25,"offset":0,"hasMore":false,"nextOffset":null},"hidden":true}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/matches/{match}":{"get":{"operationId":"getMatch","tags":["matches"],"summary":"Get one completed public match","description":"The direct match record has the same public visibility as the anonymous match page, independently of a player's private history listing. Only terminal public records. Historical participant calibration is never reopened; no seeds, inventory, raw end metadata, events or replay downloads.","x-required-scope":"matches:read","parameters":[{"name":"match","in":"path","required":true,"description":"Canonical dashed UUID or canonical 16-hex short ID (case-insensitive).","schema":{"type":"string","pattern":"^(?:[0-9a-fA-F]{16}|[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$"}}],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Match"}}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/seasons":{"get":{"operationId":"listSeasons","tags":["seasons"],"summary":"List season metadata","description":"Active season first, then season number and ID descending. This endpoint contains metadata only, not archive standings, aggregate records or future scheduled announcements.","x-required-scope":"seasons:read","parameters":[{"name":"limit","in":"query","required":false,"description":"Page size. Unknown and repeated parameters are rejected.","schema":{"type":"integer","minimum":1,"maximum":100,"default":25}},{"name":"offset","in":"query","required":false,"description":"Offset in current ordering; live data may move between requests. Deep exports are intentionally unavailable.","schema":{"type":"integer","minimum":0,"maximum":10000,"default":0}}],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","pagination"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Season"},"maxItems":100},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/seasons/{season}":{"get":{"operationId":"getSeason","tags":["seasons"],"summary":"Get season metadata","description":"Lookup by positive integer ID or public lowercase slug. Metadata only; archived season leaderboard and scheduled announcements are intentionally excluded.","x-required-scope":"seasons:read","parameters":[{"name":"season","in":"path","required":true,"description":"Positive integer ID (up to 2147483647) or lowercase slug (letters, digits, hyphens; max64).","schema":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,63}$"},"example":"season-1"}],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/Season"}}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/catalogs/ranks":{"get":{"operationId":"getRanksCatalog","tags":["catalogs"],"summary":"Get active rank presentation catalog","description":"Public names, colors, authoritative icon URLs and minimum Elo. No effect configuration or inactive drafts. Relative icon URLs resolve against the API origin; existing media cache/revision policies apply.","x-required-scope":"catalogs:read","parameters":[],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data","revision"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Rank"},"maxItems":1000},"revision":{"type":"string"}}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/catalogs/maps":{"get":{"operationId":"getMapsCatalog","tags":["catalogs"],"summary":"Get active map rotation catalog","description":"Only active maps. Images use the existing public map-image endpoint. No seeds, world files, spawn geometry or admin settings.","x-required-scope":"catalogs:read","parameters":[],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Map"},"maxItems":1000}}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/catalogs/match-conditions":{"get":{"operationId":"getMatchConditionsCatalog","tags":["catalogs"],"summary":"Get localized match-condition presentation","description":"Static authoritative condition presentation catalog. No runtime probability, gates, rule parameters or administrative configuration.","x-required-scope":"catalogs:read","parameters":[],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/MatchCondition"}}}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/live":{"get":{"operationId":"getLive","tags":["live"],"summary":"Get aggregate live activity","description":"One shared coalesced sample per API process per second. Only aggregate counts are public: no player names, UUIDs, opponents, match cards, seeds, game progress, spectator streams or OBS secrets. Cached reads do not reserve a request database connection. After a sampling failure the last good snapshot is returned with stale=true and its original asOf; before any successful sample, returns 503. No query parameters are accepted.","x-required-scope":"live:read","parameters":[],"security":[{},{"DeveloperKey":[]}],"responses":{"200":{"description":"Successful anonymous-public projection. Cookie/key identity never changes data visibility.","headers":{"X-RateLimit-Limit":{"description":"Sustained requests per minute for the admitted anonymous-IP or integration policy; not the burst capacity.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining request tokens in the admitted policy's bucket.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the admitted request bucket would be fully replenished without further traffic.","schema":{"type":"integer"}},"X-Daily-Budget-Remaining":{"description":"Partner integrations only: remaining UTC-day weighted request budget. Anonymous responses omit this header; absence is not zero.","schema":{"type":"integer"}},"X-RateLimit-Burst":{"description":"Maximum tokens in the admitted request bucket, separate from sustained requests per minute.","schema":{"type":"integer","minimum":1}},"X-RateLimit-Level":{"description":"Policy level represented by the rate headers.","schema":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"]}}},"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["data"],"properties":{"data":{"$ref":"#/components/schemas/LiveSnapshot"}}},"example":{"data":{"online":42,"inMatch":28,"searching":6,"asOf":"2026-09-06T12:00:00.000Z","stale":false}}}}},"400":{"description":"Unknown/repeated query parameter or invalid identifier/range.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Explicit malformed or invalid API credential; never treated as anonymous.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Valid API key lacks the required scope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Record unavailable to anonymous viewers, deleted profile, non-completed/hidden match, or unknown identifier.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Request body exceeds the parser limit; v1 reads do not require a request body.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A rate, concurrency or partner daily-budget policy rejected the request. Retry-After is integer seconds. Developer admission errors include limitLevel and limitReason; the outer legacy IP limiter may return only error and retryAfter. Anonymous users have no daily budget; partner shared protection is independent from anonymous traffic.","headers":{"Retry-After":{"description":"Seconds before retry.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Admission, read pool, trusted visibility settings or catalog unavailable. No partial data or guessed privacy defaults.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"DeveloperKey":{"type":"http","scheme":"bearer","bearerFormat":"mcl_live_<prefix>.<secret>","description":"Optional integration API key. Invalid explicitly supplied credentials return401, not anonymous fallback. Never send game/OBS/admin credentials."}},"schemas":{"Error":{"type":"object","additionalProperties":false,"required":["error"],"properties":{"error":{"type":"string","enum":["invalid_query","not_found","invalid_api_key","insufficient_scope","api_rate_limited","api_daily_budget_exceeded","api_concurrency_limited","api_request_too_large","api_unavailable"]},"requestId":{"type":"string"},"retryAfter":{"type":"integer","minimum":1},"limitLevel":{"type":"string","enum":["anonymous_ip","anonymous_shared","authentication_ip","authentication_shared","partner_shared","integration"],"description":"The developer admission policy that rejected this request; absent for outer boundary errors."},"limitReason":{"type":"string","enum":["rate","daily_budget","concurrency"]}}},"Pagination":{"type":"object","additionalProperties":false,"required":["limit","offset","hasMore","nextOffset"],"properties":{"limit":{"type":"integer","minimum":1,"maximum":100},"offset":{"type":"integer","minimum":0,"maximum":10000},"hasMore":{"type":"boolean"},"nextOffset":{"anyOf":[{"type":"integer","minimum":1,"maximum":10000},{"type":"null"}]}}},"Player":{"type":"object","additionalProperties":false,"required":["uuid","name","country","rating","records","joinedAt","updatedAt"],"properties":{"uuid":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"rating":{"type":"object","additionalProperties":false,"required":["elo","peak","rank","calibrating","gamesLeft"],"properties":{"elo":{"anyOf":[{"type":"number"},{"type":"null"}]},"peak":{"anyOf":[{"type":"number"},{"type":"null"}]},"rank":{"anyOf":[{"type":"number"},{"type":"null"}]},"calibrating":{"type":"boolean"},"gamesLeft":{"type":"number","minimum":0}}},"records":{"type":"object","additionalProperties":false,"required":["overall","solo","duo"],"properties":{"overall":{"type":"object","additionalProperties":false,"required":["wins","draws","losses"],"properties":{"wins":{"type":"integer","minimum":0},"draws":{"type":"integer","minimum":0},"losses":{"type":"integer","minimum":0}}},"solo":{"type":"object","additionalProperties":false,"required":["wins","draws","losses"],"properties":{"wins":{"type":"integer","minimum":0},"draws":{"type":"integer","minimum":0},"losses":{"type":"integer","minimum":0}}},"duo":{"type":"object","additionalProperties":false,"required":["wins","draws","losses"],"properties":{"wins":{"type":"integer","minimum":0},"draws":{"type":"integer","minimum":0},"losses":{"type":"integer","minimum":0}}}}},"joinedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"updatedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"LeaderboardEntry":{"type":"object","additionalProperties":false,"required":["uuid","name","country","rank","elo","peakElo","wins","draws","losses"],"properties":{"uuid":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"country":{"anyOf":[{"type":"string"},{"type":"null"}]},"rank":{"anyOf":[{"type":"number"},{"type":"null"}]},"elo":{"anyOf":[{"type":"number"},{"type":"null"}]},"peakElo":{"anyOf":[{"type":"number"},{"type":"null"}]},"wins":{"type":"integer","minimum":0},"draws":{"type":"integer","minimum":0},"losses":{"type":"integer","minimum":0}}},"Participant":{"type":"object","additionalProperties":false,"required":["uuid","name","result","ratingRevealed","eloBefore","eloAfter"],"properties":{"country":{"description":"Public profile country only; null when hidden or unset.","anyOf":[{"type":"string"},{"type":"null"}]},"uuid":{"anyOf":[{"type":"string"},{"type":"null"}]},"name":{"anyOf":[{"type":"string"},{"type":"null"}]},"result":{"anyOf":[{"type":"string","enum":["WIN","LOSS","DRAW","VOID"]},{"type":"null"}]},"ratingRevealed":{"type":"boolean"},"eloBefore":{"anyOf":[{"type":"number"},{"type":"null"}]},"eloAfter":{"anyOf":[{"type":"number"},{"type":"null"}]}}},"Match":{"type":"object","additionalProperties":false,"required":["id","shortId","mode","map","seasonId","startedAt","endedAt","durationSeconds","condition","participants"],"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}]},"shortId":{"anyOf":[{"type":"string"},{"type":"null"}]},"mode":{"anyOf":[{"type":"string","enum":["solo","duo"]},{"type":"null"}]},"map":{"anyOf":[{"type":"string"},{"type":"null"}]},"seasonId":{"anyOf":[{"type":"number"},{"type":"null"}]},"startedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"endedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"durationSeconds":{"anyOf":[{"type":"number"},{"type":"null"}]},"condition":{"anyOf":[{"type":"string"},{"type":"null"}]},"participants":{"type":"array","items":{"$ref":"#/components/schemas/Participant"}}}},"Season":{"type":"object","additionalProperties":false,"required":["id","number","slug","title","status","startingElo","startedAt","endedAt"],"properties":{"id":{"anyOf":[{"type":"number"},{"type":"null"}]},"number":{"anyOf":[{"type":"number"},{"type":"null"}]},"slug":{"anyOf":[{"type":"string"},{"type":"null"}]},"title":{"anyOf":[{"type":"string"},{"type":"null"}]},"status":{"anyOf":[{"type":"string"},{"type":"null"}]},"startingElo":{"anyOf":[{"type":"number"},{"type":"null"}]},"startedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"endedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"Rank":{"type":"object","additionalProperties":false,"required":["key","names","color","icon","minElo","kind","animated"],"properties":{"key":{"type":"string"},"names":{"type":"object","additionalProperties":{"type":"string"}},"color":{"anyOf":[{"type":"string"},{"type":"null"}]},"icon":{"anyOf":[{"type":"string"},{"type":"null"}]},"minElo":{"anyOf":[{"type":"number"},{"type":"null"}]},"kind":{"anyOf":[{"type":"string"},{"type":"null"}]},"animated":{"type":"boolean"}}},"Map":{"type":"object","additionalProperties":false,"required":["slug","name","image"],"properties":{"slug":{"type":"string"},"name":{"type":"string"},"image":{"type":"string"}}},"MatchCondition":{"type":"object","additionalProperties":false,"required":["key","names","descriptions","icon"],"properties":{"key":{"type":"string"},"names":{"type":"object","additionalProperties":{"type":"string"}},"descriptions":{"type":"object","additionalProperties":{"type":"string"}},"icon":{"type":"object","additionalProperties":false,"required":["kind","id"],"properties":{"kind":{"type":"string"},"id":{"type":"string"}}}}},"LiveSnapshot":{"type":"object","additionalProperties":false,"required":["online","inMatch","searching","asOf","stale"],"properties":{"online":{"type":"integer","minimum":0,"description":"Players with an online heartbeat newer than 30 seconds."},"inMatch":{"type":"integer","minimum":0,"description":"Online players in MATCH or MATCH_STARTING, not a count of matches."},"searching":{"type":"integer","minimum":0,"description":"Online players in QUEUE."},"asOf":{"type":"string","format":"date-time","description":"Time of the last successful aggregate sample, never the time of this response."},"stale":{"type":"boolean","description":"True when refresh failed and this is the last successful sample. An unavailable initial sample returns 503, never fabricated fresh zeros."}}}}}}