{
    "openapi": "3.1.0",
    "info": {
        "title": "Critical Ops Public API",
        "description": "Access to Critical Ops player profiles and statistics, leaderboards, match history and game server status, and,\nfor tokens granted the permission, hosting custom games on the game servers.\n\n## Authentication\n\nEvery request, except fetching this document, needs an API token issued to a Critical Ops player account.\nSend it as `Authorization: Bearer <token>`, or as `X-Api-Key: <token>` when your client cannot set\n`Authorization`. Tokens look like `cops_` followed by 48 hexadecimal digits.\n\nKeep tokens secret. A token acts on behalf of the player it was issued to and can be revoked, so call the API\nfrom a server rather than exposing the token in a browser or app.\n\n## Rate limiting\n\nEach token has a quota of requests per minute, by default 60. The minute is the wall-clock minute, and every\nauthenticated request counts, including those that fail. Responses carry the quota:\n\n- `X-RateLimit-Limit`: requests allowed per minute\n- `X-RateLimit-Remaining`: requests left in the current minute\n- `X-RateLimit-Reset`: Unix time when the current minute ends\n\nRequests over the quota fail with `429 Too Many Requests` and a `Retry-After` header.\n\n## Hosting games\n\nWith the `Autohost` permission, a token can have game servers host custom games that players join by room\ncode. Creating a game returns at once; poll it until the room code shows. Name all the games you follow in one\n`GET /autohost/poll` every 5 seconds, which is how often game servers update them, since every request counts\ntowards the quota. A game that polling no longer returns is gone and will not come back: host another one.\nWhile the room is open, `POST /autohost/control` kicks players, restarts the match and changes the room owners.\n\n### Game modes and maps\n\n`game_mode_id` is one of the game modes below, and `map_id` one of the maps listed for it: the custom\ngame modes of the in-game host menu that may be hosted through the API, on the maps the menu offers for\nthem. Other ids fail with `400`. These are the ids at the time this spec was generated.\n\n| Game mode | `game_mode_id` | `map_id` |\n| --- | --- | --- |\n| Defuse | 15773 | 613, 615, 617, 618, 619, 1311, 1312, 1360, 6677, 7201, 7316, 7584, 8024, 8427, 8872, 13410, 15391 |\n| Elimination | 15775 | 6655, 14066, 15028 |\n| Gungame | 15776 | 839, 841, 1311, 1312, 4483, 6655, 6670, 7201, 7554, 7584, 8024, 9310, 14066, 15028 |\n| Team Deathmatch | 15777 | 613, 615, 617, 618, 619, 839, 841, 1311, 1312, 1360, 4483, 6655, 6670, 6677, 7201, 7316, 7554, 7584, 8024, 8427, 8872, 9310, 13410, 14066, 15028, 15391 |\n| Manhunt | 15846 | 7316 |\n| Tournament Mode | 15847 | 613, 615, 617, 618, 619, 1360, 6677, 8427, 13410, 15391 |\n| Rush | 15860 | 613, 615, 617, 618, 619, 839, 841, 1311, 1312, 1360, 4483, 6655, 6670, 6677, 7201, 7316, 7554, 7584, 8024, 8427, 8872, 9310, 13410, 14066, 15028, 15391 |\n| Defend | 15861 | 8872 |\n| Manhunt Z | 18596 | 7316 |\n| Wingman | 18850 | 613, 615, 617, 619, 1360, 13410, 15391 |\n\n| `map_id` | Map |\n| --- | --- |\n| 613 | Canals |\n| 615 | Plaza |\n| 617 | Legacy |\n| 618 | Grounded |\n| 619 | Bureau |\n| 839 | Brewery |\n| 841 | Division |\n| 1311 | Uplink |\n| 1312 | Yard |\n| 1360 | Raid |\n| 4483 | Heat |\n| 6655 | Warehouse |\n| 6670 | Gallery |\n| 6677 | Port |\n| 7201 | Park |\n| 7316 | Purify |\n| 7554 | Cargo |\n| 7584 | Arctic |\n| 8024 | Bout |\n| 8427 | Soar |\n| 8872 | Shanty |\n| 9310 | Hangar |\n| 13410 | Village |\n| 14066 | Impasse |\n| 15028 | Overhaul |\n| 15391 | Castello |\n\n## Errors\n\nErrors come with an HTTP status code and a JSON body such as\n`{\"error\": {\"code\": \"user_not_found\", \"message\": \"Unable to find user by username\"}}`.\nBranch on `code`, which is stable; `message` is for people and its wording may change. Each operation lists\nthe error responses it can return, and each error response lists its codes.\n\n## Compatibility\n\nResponses may gain new fields. Ignore fields you do not recognise.",
        "version": "2.0.0"
    },
    "servers": [
        {
            "url": "https://default.prod.copsapi.criticalforce.fi/api/public/v2",
            "description": "Production"
        }
    ],
    "paths": {
        "/openapi.json": {
            "get": {
                "tags": [
                    "Meta"
                ],
                "summary": "Get the OpenAPI document",
                "description": "This document: the OpenAPI 3.1 description of the public API. Fetching it needs no API token and does not count\ntowards any rate limit.",
                "operationId": "getOpenApiSpec",
                "responses": {
                    "200": {
                        "description": "The OpenAPI document.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                },
                "security": []
            }
        },
        "/profile": {
            "get": {
                "tags": [
                    "Players"
                ],
                "summary": "Look up player profiles",
                "description": "Returns the profiles of the players named by `ids` and then `usernames`, in request order and without\nduplicates. Naming no players returns an empty list. If any named player does not exist, the whole request\nfails with `user_not_found`.",
                "operationId": "getProfiles",
                "parameters": [
                    {
                        "name": "ids",
                        "in": "query",
                        "description": "Comma-separated player user IDs. A request may name up to 20 players by default, `ids` and `usernames` together; naming more fails with `bad_request`.",
                        "style": "form",
                        "explode": false,
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "integer",
                                "minimum": 1
                            }
                        },
                        "example": [
                            1234567,
                            7654321
                        ]
                    },
                    {
                        "name": "usernames",
                        "in": "query",
                        "description": "Comma-separated player usernames. Surrounding whitespace is ignored. A request may name up to 20 players by default, `ids` and `usernames` together; naming more fails with `bad_request`.",
                        "style": "form",
                        "explode": false,
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string",
                                "minLength": 1
                            }
                        },
                        "example": [
                            "Player123"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The requested profiles.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "$ref": "#/components/schemas/Profile"
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                }
            }
        },
        "/status/servers": {
            "get": {
                "tags": [
                    "Servers"
                ],
                "summary": "Get game server status",
                "description": "Lists every game server and whether it currently accepts players.",
                "operationId": "getServerStatus",
                "responses": {
                    "200": {
                        "description": "Status of each game server, keyed by server ID.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "additionalProperties": {
                                        "$ref": "#/components/schemas/ServerStatus"
                                    }
                                },
                                "example": {
                                    "1": {
                                        "name": "EU-1",
                                        "status": "online"
                                    },
                                    "2": {
                                        "name": "US-1",
                                        "status": "offline"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                }
            }
        },
        "/matches/player": {
            "get": {
                "tags": [
                    "Matches"
                ],
                "summary": "Get a player's match history",
                "description": "Returns the player's recent matches, newest first. Matches the player left early are listed only if ranked. The\nhistory resets with each game update, and a player who does not exist has none. While match history is switched\noff, this fails with `503`.",
                "operationId": "getPlayerMatches",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/UserId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The player's matches.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "matches"
                                    ],
                                    "properties": {
                                        "matches": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/MatchHistoryEntry"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                }
            }
        },
        "/matches/fetch": {
            "get": {
                "tags": [
                    "Matches"
                ],
                "summary": "Get matches",
                "description": "Returns the named matches with their scoreboards, leaving out those that no longer exist. While match history is\nswitched off, this fails with `503`.",
                "operationId": "getMatches",
                "parameters": [
                    {
                        "name": "ids",
                        "in": "query",
                        "description": "Comma-separated `id`s of matches from `GET /matches/player`.",
                        "required": true,
                        "style": "form",
                        "explode": false,
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string",
                                "pattern": "^[0-9a-f]{64}$"
                            },
                            "maxItems": 20,
                            "minItems": 1
                        },
                        "example": [
                            "9f2c4e7a1b3d5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The matches found, in request order.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "matches"
                                    ],
                                    "properties": {
                                        "matches": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/MatchInfo"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                }
            }
        },
        "/stats/weapons": {
            "get": {
                "tags": [
                    "Players"
                ],
                "summary": "Get a player's weapon statistics",
                "description": "Returns the player's all-time totals in ranked or casual matches, per weapon they have scored with. Custom\ngames, including those hosted through this API, have no totals of their own: they count as casual matches.\nTotals are updated about once a minute, so a match that just ended can count in the player's profile before it\ncounts here.",
                "operationId": "getWeaponStats",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/UserId"
                    },
                    {
                        "name": "game_type",
                        "in": "query",
                        "description": "The matches to total: `1` for ranked matches, `2` for casual matches and custom games.",
                        "required": true,
                        "schema": {
                            "description": "`1` Ranked, `2` Casual",
                            "type": "integer",
                            "enum": [
                                1,
                                2
                            ],
                            "x-enum-varnames": [
                                "Ranked",
                                "Casual"
                            ]
                        },
                        "example": 1
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The player's weapons.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "weapons"
                                    ],
                                    "properties": {
                                        "weapons": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/WeaponStats"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                }
            }
        },
        "/leaderboards": {
            "get": {
                "tags": [
                    "Leaderboards"
                ],
                "summary": "Get a leaderboard",
                "description": "Returns a page of a leaderboard of the current ranked season, best first. Leaderboards count ranked matches only\nand start over each season. Players move up and down as matches end, so paging through a leaderboard can skip or\nrepeat players. While leaderboards are switched off, this fails with `503`.",
                "operationId": "getLeaderboard",
                "parameters": [
                    {
                        "name": "type",
                        "in": "query",
                        "description": "What players are ranked by. `mmr`: matchmaking rating, of the players who have played their placement matches. The others: the player's total over the season's ranked matches.",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "mmr",
                                "kills",
                                "deaths",
                                "assists",
                                "matches",
                                "wins",
                                "losses",
                                "xp",
                                "mvp"
                            ]
                        },
                        "example": "kills"
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "description": "Page of 10 entries, starting from 1. Pages past the end are empty.",
                        "schema": {
                            "type": "integer",
                            "default": 1,
                            "minimum": 1
                        },
                        "example": 1
                    },
                    {
                        "name": "rank",
                        "in": "query",
                        "description": "Lists only the players of this rank, from `0` for players in placement matches to `9` for Elite Ops, each ranked as of their last rating change.",
                        "schema": {
                            "type": "integer",
                            "maximum": 9,
                            "minimum": 0
                        },
                        "example": 5
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The page.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "entries",
                                        "leaderboard_size"
                                    ],
                                    "properties": {
                                        "entries": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/LeaderboardEntry"
                                            }
                                        },
                                        "leaderboard_size": {
                                            "description": "Players on the leaderboard, of the rank when `rank` is given.",
                                            "type": "integer",
                                            "minimum": 0,
                                            "example": 48210
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                }
            }
        },
        "/autohost/create": {
            "post": {
                "tags": [
                    "Autohost"
                ],
                "summary": "Host a game",
                "description": "Asks a game server to create a custom room that players join by its room code. Nobody owns the room until\n`POST /autohost/control` adds an owner. Only the game modes and maps listed in the API description can be\nhosted. Poll for the room code, which normally appears within a second. A game whose room is not created within\n30 seconds is gone.\n\nThe room closes when nobody joins within 3 minutes, when everyone leaves, or after 3 hours. A game server\nrefuses the game when it is full or in maintenance, or already hosts 100 games, or 10 of the token's: these\nlimits are per game server. The game then ends without a room.\n\nA `server_id` that `GET /status/servers` does not list fails with `400`; a listed server that is not taking\nrequests, such as one that is restarting, fails with `503`. While hosting is switched off, creating a game\nfails with `503`, but the games already hosted can still be polled and controlled.\n\nRequires the API token permission `Autohost`.",
                "operationId": "createAutohost",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AutohostCreateRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "The game server was asked to host the game.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "autohost"
                                    ],
                                    "properties": {
                                        "autohost": {
                                            "$ref": "#/components/schemas/AutohostGame"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                },
                "x-required-permissions": [
                    "Autohost"
                ]
            }
        },
        "/autohost/poll": {
            "get": {
                "tags": [
                    "Autohost"
                ],
                "summary": "Get hosted games",
                "description": "Returns the named games with their status, the players in the room and the results of the matches that\nconcluded. A game that is left out is gone: never created, lost with its game server, or ended over 48 hours\nago.\n\nGame servers update the players, scores and state of an open game every 5 seconds, and at once when a player\njoins or leaves or a round ends. Poll every 5 seconds, naming all your games in one request: every request\ncounts towards the per-minute quota.\n\nRequires the API token permission `Autohost`.",
                "operationId": "pollAutohosts",
                "parameters": [
                    {
                        "name": "ids",
                        "in": "query",
                        "description": "Comma-separated ids returned when the games were created.",
                        "required": true,
                        "style": "form",
                        "explode": false,
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "integer",
                                "minimum": 1
                            },
                            "maxItems": 50,
                            "minItems": 1
                        },
                        "example": [
                            1042,
                            1043
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The named games that exist, in request order.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "autohosts"
                                    ],
                                    "properties": {
                                        "autohosts": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/AutohostGame"
                                            }
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                },
                "x-required-permissions": [
                    "Autohost"
                ]
            }
        },
        "/autohost/control": {
            "post": {
                "tags": [
                    "Autohost"
                ],
                "summary": "Control a hosted game",
                "description": "Sends a command to the room of one of the token's games that has an open room. The command runs on the game\nserver shortly after; poll the game to see its effect.\n\n- `kick`: removes `user_id` from the room, and from its owners, and keeps them out of it for an hour.\n- `restart`: restarts the match, as the owner's restart command does.\n- `room_owner_add`: makes `user_id` a room owner, also before they join.\n- `room_owner_remove`: takes room ownership from `user_id`. It does not pass to anyone else.\n- `close`: closes the room right away, also mid-match. The game ends like one that reached its lifetime limit,\nwith the matches concluded so far in its results.\n\nRequires the API token permission `Autohost`.",
                "operationId": "controlAutohost",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/AutohostControlRequest"
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "The game server was sent the command.",
                        "headers": {
                            "X-RateLimit-Limit": {
                                "$ref": "#/components/headers/X-RateLimit-Limit"
                            },
                            "X-RateLimit-Remaining": {
                                "$ref": "#/components/headers/X-RateLimit-Remaining"
                            },
                            "X-RateLimit-Reset": {
                                "$ref": "#/components/headers/X-RateLimit-Reset"
                            }
                        },
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "autohost"
                                    ],
                                    "properties": {
                                        "autohost": {
                                            "$ref": "#/components/schemas/AutohostGame"
                                        }
                                    },
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/BadRequest"
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/TooManyRequests"
                    },
                    "500": {
                        "$ref": "#/components/responses/InternalServerError"
                    },
                    "503": {
                        "$ref": "#/components/responses/ServiceUnavailable"
                    }
                },
                "x-required-permissions": [
                    "Autohost"
                ]
            }
        }
    },
    "components": {
        "schemas": {
            "AutohostControlRequest": {
                "description": "A command for a hosted game's room.",
                "required": [
                    "id",
                    "command"
                ],
                "properties": {
                    "id": {
                        "description": "Id of the hosted game, as returned when it was created",
                        "type": "integer",
                        "minimum": 1,
                        "example": 1042
                    },
                    "command": {
                        "description": "What to do in the room. `kick`, `room_owner_add` and `room_owner_remove` need `user_id`.",
                        "type": "string",
                        "enum": [
                            "kick",
                            "restart",
                            "room_owner_add",
                            "room_owner_remove",
                            "close"
                        ],
                        "example": "kick"
                    },
                    "user_id": {
                        "description": "The player the command is about",
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 1,
                        "example": 1234567
                    }
                },
                "type": "object"
            },
            "AutohostCreateRequest": {
                "description": "A game to host. The room has the game mode's default options, as when a player hosts it from the in-game host menu\nwithout changing any.",
                "required": [
                    "server_id",
                    "room_name",
                    "map_id",
                    "game_mode_id"
                ],
                "properties": {
                    "server_id": {
                        "description": "Game server to host the game on: one of the ids `GET /status/servers` lists",
                        "type": "integer",
                        "minimum": 1,
                        "example": 12
                    },
                    "room_name": {
                        "description": "Room name shown to players",
                        "type": "string",
                        "maxLength": 32,
                        "minLength": 1,
                        "example": "Cup R1 #3"
                    },
                    "password": {
                        "description": "Password players need to join. Empty or absent for a room without one.",
                        "type": "string",
                        "maxLength": 32,
                        "example": "x7k2"
                    },
                    "map_id": {
                        "description": "Map to play",
                        "type": "integer",
                        "minimum": 1,
                        "example": 619
                    },
                    "game_mode_id": {
                        "description": "Custom game mode to play",
                        "type": "integer",
                        "minimum": 1,
                        "example": 15847
                    }
                },
                "type": "object"
            },
            "AutohostGame": {
                "description": "A hosted game. Times are Unix timestamps in seconds.",
                "required": [
                    "id",
                    "status",
                    "created_at",
                    "updated_at",
                    "ended_at",
                    "pending_expires_at",
                    "server_id",
                    "room",
                    "player_count",
                    "match_started_at",
                    "match_state",
                    "round",
                    "scores",
                    "players",
                    "results",
                    "replay_id",
                    "rejection_reason"
                ],
                "properties": {
                    "id": {
                        "description": "Unique within the current game version only: a new version starts again from 1.",
                        "type": "integer",
                        "minimum": 1,
                        "example": 1042
                    },
                    "status": {
                        "description": "`open` until the room closes, then `ended`. A game that ended without a room was refused by the game server.",
                        "type": "string",
                        "enum": [
                            "open",
                            "ended"
                        ],
                        "example": "open"
                    },
                    "created_at": {
                        "type": "integer",
                        "example": 1790000000
                    },
                    "updated_at": {
                        "type": "integer",
                        "example": 1790000461
                    },
                    "ended_at": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "example": null
                    },
                    "pending_expires_at": {
                        "description": "Until the room exists: when the game is gone unless the game server has created the room.",
                        "type": [
                            "integer",
                            "null"
                        ],
                        "example": null
                    },
                    "server_id": {
                        "type": "integer",
                        "example": 12
                    },
                    "room": {
                        "$ref": "#/components/schemas/AutohostRoom"
                    },
                    "player_count": {
                        "description": "Players in the room now, including spectators and those who have not picked a team. `0` once the game ended.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 7
                    },
                    "match_started_at": {
                        "description": "When the match now being played started, `null` between matches and once the game ended. It changes when the\nowner restarts the match.",
                        "type": [
                            "integer",
                            "null"
                        ],
                        "example": 1790000190
                    },
                    "match_state": {
                        "description": "State of the game as of `updated_at`: `WaitingForPlayers`, `Starting`, `Freezetime`, `OnGoing`, `BombPlanted`,\n`Win`, `TeamFlip`, `GameEnd` or `ChangingMap`. `null` until the game server first reports on the room, up to\n5 seconds after it exists, and once the game ended.",
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "OnGoing"
                    },
                    "round": {
                        "description": "Round of the match now being played, as of `updated_at`.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 5
                    },
                    "scores": {
                        "description": "Score of each team in the match now being played, as of `updated_at`. Empty until the game server first\nreports on the room, and once the game ended.",
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "example": [
                            3,
                            1
                        ]
                    },
                    "players": {
                        "description": "The players in the room with their scoreboard of the match now being played, as of `updated_at`; `team` is\n`-1` for one who has not picked a team and `left_match` is always `false` here. Empty once the game ended.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/PlayerMatchStats"
                        }
                    },
                    "results": {
                        "description": "Every contested match that ended in the room, oldest first, so the last one is the latest. A match the owner\nrestarts before it ends leaves no result, so a warmup that is restarted does not count; one that is played to\nthe end does, and the proper match that follows is listed after it.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/AutohostResult"
                        }
                    },
                    "replay_id": {
                        "description": "The room's replay, once the game ended. `null` when the game server saved none: it records only some game\nmodes, such as Tournament.",
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "9c1f04ab"
                    },
                    "rejection_reason": {
                        "description": "Why the game server refused the game, for a game that ended without a room; `null` otherwise.",
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": null
                    }
                },
                "type": "object"
            },
            "AutohostResult": {
                "description": "Outcome of the concluded autohosted match",
                "required": [
                    "match_id",
                    "map_id",
                    "team_factions",
                    "winning_team",
                    "win_condition",
                    "scores",
                    "started_at",
                    "ended_at",
                    "map_variation",
                    "rounds_played",
                    "players"
                ],
                "properties": {
                    "match_id": {
                        "description": "Unique id of the match",
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "6f1d2c3b-4a5e-4f60-9b7c-8d9e0f1a2b3c"
                    },
                    "map_id": {
                        "description": "The map the match was played on",
                        "type": "integer",
                        "example": 619
                    },
                    "team_factions": {
                        "description": "Faction of each team, by team index: which side each team played.",
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "example": [
                            1,
                            2
                        ]
                    },
                    "winning_team": {
                        "description": "Index of the winning team, `-1` for none.",
                        "type": "integer",
                        "minimum": -1,
                        "example": 0
                    },
                    "win_condition": {
                        "description": "How the match was won, such as `TeamEliminated`, `TeamKills`, `TimeUp` or `Surrendered`.",
                        "type": "string",
                        "example": "TeamEliminated"
                    },
                    "scores": {
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "example": [
                            13,
                            7
                        ]
                    },
                    "started_at": {
                        "type": "integer",
                        "example": 1790000190
                    },
                    "ended_at": {
                        "type": "integer",
                        "example": 1790001790
                    },
                    "map_variation": {
                        "type": "integer",
                        "example": 0
                    },
                    "rounds_played": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 11
                    },
                    "players": {
                        "description": "Scoreboard of the players who were on a team in the match, including those who left it.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/PlayerMatchStats"
                        }
                    }
                },
                "type": "object"
            },
            "AutohostRoom": {
                "description": "The autohosted game's room.",
                "required": [
                    "id",
                    "code",
                    "name",
                    "map_id",
                    "game_mode_id",
                    "has_password"
                ],
                "properties": {
                    "id": {
                        "description": "Room id on its game server, `-1` until the room exists and for a game that got none.",
                        "type": "integer",
                        "example": 345
                    },
                    "code": {
                        "description": "Room code, `null` until the room exists and once the game ended.",
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": "ICQK"
                    },
                    "name": {
                        "type": "string",
                        "maxLength": 32,
                        "example": "Cup R1 #3"
                    },
                    "map_id": {
                        "description": "The map the room plays now: the owner can change it.",
                        "type": "integer",
                        "example": 619
                    },
                    "game_mode_id": {
                        "type": "integer",
                        "example": 15847
                    },
                    "has_password": {
                        "type": "boolean",
                        "example": true
                    }
                },
                "type": "object"
            },
            "Ban": {
                "description": "An active ban. When a player has several, this is the most severe one.",
                "required": [
                    "type",
                    "reason",
                    "days_left"
                ],
                "properties": {
                    "type": {
                        "description": "Ban type.\n\n`0` Permanent, `1` Temporary",
                        "type": "integer",
                        "enum": [
                            0,
                            1
                        ],
                        "example": 1,
                        "x-enum-varnames": [
                            "Permanent",
                            "Temporary"
                        ]
                    },
                    "reason": {
                        "description": "Publicly shown ban reason.\n\n`0` Unknown, `1` Fraud attempt, `2` Hacking, `3` Griefing, `4` Verbal abuse, `5` Idle, `6` Spam, `7` Report abuse, `8` Account trading, `9` Glitching, `10` Ghosting, `11` Partying with hacker, `12` Under investigation, `13` Marketplace abuse",
                        "type": "integer",
                        "enum": [
                            0,
                            1,
                            2,
                            3,
                            4,
                            5,
                            6,
                            7,
                            8,
                            9,
                            10,
                            11,
                            12,
                            13
                        ],
                        "example": 2,
                        "x-enum-varnames": [
                            "Unknown",
                            "FraudAttempt",
                            "Hacking",
                            "Griefing",
                            "VerbalAbuse",
                            "Idle",
                            "Spam",
                            "ReportAbuse",
                            "AccountTrading",
                            "Glitching",
                            "Ghosting",
                            "PartyingWithHacker",
                            "UnderInvestigation",
                            "MarketplaceAbuse"
                        ]
                    },
                    "days_left": {
                        "description": "Days until a temporary ban ends, rounded up. `0` for a ban that never ends: a permanent ban, or a temporary ban\nissued without a duration.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 3
                    }
                },
                "type": "object"
            },
            "ClanBasicInfo": {
                "description": "Identity of a clan.",
                "required": [
                    "id",
                    "name",
                    "tag",
                    "emblem_id"
                ],
                "properties": {
                    "id": {
                        "description": "Clan ID.",
                        "type": "integer",
                        "minimum": 1,
                        "example": 8812
                    },
                    "name": {
                        "description": "Clan name.",
                        "type": "string",
                        "example": "Tactical Squad"
                    },
                    "tag": {
                        "description": "Clan tag.",
                        "type": "string",
                        "example": "TSQD"
                    },
                    "emblem_id": {
                        "description": "ID of the clan emblem, `0` when none.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 3
                    }
                },
                "type": "object"
            },
            "ClanMembership": {
                "description": "Clan of a player and the player's place in it.",
                "required": [
                    "basic_info",
                    "member_rank",
                    "joined"
                ],
                "properties": {
                    "basic_info": {
                        "$ref": "#/components/schemas/ClanBasicInfo"
                    },
                    "member_rank": {
                        "description": "Role of the player in the clan.\n\n`10` Member, `20` Officer, `30` Co leader, `40` Leader",
                        "type": "integer",
                        "enum": [
                            10,
                            20,
                            30,
                            40
                        ],
                        "example": 10,
                        "x-enum-varnames": [
                            "Member",
                            "Officer",
                            "CoLeader",
                            "Leader"
                        ]
                    },
                    "joined": {
                        "description": "When the player joined the clan, as `YYYY-MM-DD HH:MM:SS` in UTC.",
                        "type": "string",
                        "pattern": "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$",
                        "example": "2026-03-14 18:05:09"
                    }
                },
                "type": "object"
            },
            "Error": {
                "description": "Body of every error response.",
                "required": [
                    "error"
                ],
                "properties": {
                    "error": {
                        "$ref": "#/components/schemas/ErrorDetail"
                    }
                },
                "type": "object"
            },
            "ErrorDetail": {
                "description": "What went wrong.",
                "required": [
                    "code",
                    "message"
                ],
                "properties": {
                    "code": {
                        "description": "Stable, machine-readable error code. Each error response lists the codes it can carry.",
                        "type": "string",
                        "enum": [
                            "missing_token",
                            "invalid_token",
                            "token_revoked",
                            "insufficient_permissions",
                            "rate_limited",
                            "bad_request",
                            "user_not_found",
                            "game_not_found",
                            "server_unavailable",
                            "api_disabled",
                            "internal_error"
                        ],
                        "example": "bad_request"
                    },
                    "message": {
                        "description": "Human-readable explanation. Meant for people, not for parsing: the wording may change.",
                        "type": "string",
                        "example": "Malformed user id: \"abc\"."
                    },
                    "retry_after": {
                        "description": "Seconds to wait before retrying. Only sent with `rate_limited`, and equal to the `Retry-After` header.",
                        "type": "integer",
                        "minimum": 1,
                        "example": 17
                    }
                },
                "type": "object"
            },
            "LeaderboardEntry": {
                "description": "A player on a leaderboard.",
                "required": [
                    "position",
                    "score",
                    "basic_info",
                    "ranked"
                ],
                "properties": {
                    "position": {
                        "description": "Position on the leaderboard, starting from 1.",
                        "type": "integer",
                        "minimum": 1,
                        "example": 1
                    },
                    "score": {
                        "description": "The player's rating or total that the leaderboard ranks by.",
                        "type": "integer",
                        "example": 1520
                    },
                    "basic_info": {
                        "$ref": "#/components/schemas/ProfileBasicInfo"
                    },
                    "ranked": {
                        "$ref": "#/components/schemas/RankedStats"
                    },
                    "clan": {
                        "$ref": "#/components/schemas/ClanMembership",
                        "description": "The player's clan. Absent when the player is not in a clan."
                    }
                },
                "type": "object"
            },
            "LeaderboardPosition": {
                "description": "Place of a player on the seasonal rating leaderboard. A player who is not on the leaderboard gets position `0` with\nscore `0`.",
                "required": [
                    "position",
                    "score"
                ],
                "properties": {
                    "position": {
                        "description": "Position on the leaderboard, starting from 1; `0` when the player is not on the leaderboard.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 5021
                    },
                    "score": {
                        "description": "Leaderboard score.",
                        "type": "integer",
                        "example": 2150
                    }
                },
                "type": "object"
            },
            "MatchHistoryEntry": {
                "description": "A match in a player's history.",
                "required": [
                    "id",
                    "game_type",
                    "game_mode_id",
                    "map_id",
                    "team",
                    "result",
                    "left_match",
                    "scores"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^[0-9a-f]{64}$",
                        "example": "9f2c4e7a1b3d5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8"
                    },
                    "game_type": {
                        "description": "`1` Ranked, `2` Casual",
                        "type": "integer",
                        "enum": [
                            1,
                            2
                        ],
                        "example": 1,
                        "x-enum-varnames": [
                            "Ranked",
                            "Casual"
                        ]
                    },
                    "game_mode_id": {
                        "type": "integer",
                        "example": 7244
                    },
                    "map_id": {
                        "type": "integer",
                        "example": 619
                    },
                    "team": {
                        "description": "The player's team.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 0
                    },
                    "result": {
                        "description": "`1` Win, `2` Loss, `3` Draw",
                        "type": "integer",
                        "enum": [
                            1,
                            2,
                            3
                        ],
                        "example": 1,
                        "x-enum-varnames": [
                            "Win",
                            "Loss",
                            "Draw"
                        ]
                    },
                    "left_match": {
                        "type": "boolean",
                        "example": false
                    },
                    "scores": {
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "example": [
                            13,
                            7
                        ]
                    }
                },
                "type": "object"
            },
            "MatchInfo": {
                "description": "A concluded match. Times are Unix timestamps in seconds.",
                "required": [
                    "id",
                    "game_type",
                    "game_mode_id",
                    "server_id",
                    "map_id",
                    "team_factions",
                    "winning_team",
                    "win_condition",
                    "scores",
                    "started_at",
                    "ended_at",
                    "players",
                    "replay_id"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "pattern": "^[0-9a-f]{64}$",
                        "example": "9f2c4e7a1b3d5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8"
                    },
                    "game_type": {
                        "description": "`1` Ranked, `2` Casual",
                        "type": "integer",
                        "enum": [
                            1,
                            2
                        ],
                        "example": 1,
                        "x-enum-varnames": [
                            "Ranked",
                            "Casual"
                        ]
                    },
                    "game_mode_id": {
                        "type": "integer",
                        "example": 7244
                    },
                    "server_id": {
                        "type": "integer",
                        "example": 12
                    },
                    "map_id": {
                        "description": "The map the match was played on",
                        "type": "integer",
                        "example": 619
                    },
                    "team_factions": {
                        "description": "Faction of each team, by team index: which side each team played.",
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "example": [
                            1,
                            2
                        ]
                    },
                    "winning_team": {
                        "description": "Index of the winning team, `-1` for none.",
                        "type": "integer",
                        "minimum": -1,
                        "example": 0
                    },
                    "win_condition": {
                        "description": "How the match was won, such as `TeamEliminated`, `TeamKills`, `TimeUp` or `Surrendered`.",
                        "type": "string",
                        "example": "TeamEliminated"
                    },
                    "scores": {
                        "type": "array",
                        "items": {
                            "type": "integer"
                        },
                        "example": [
                            13,
                            7
                        ]
                    },
                    "started_at": {
                        "type": "integer",
                        "example": 1790000190
                    },
                    "ended_at": {
                        "type": "integer",
                        "example": 1790001790
                    },
                    "players": {
                        "description": "Players who left are listed for ranked matches only.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/MatchPlayer"
                        }
                    },
                    "replay_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": null
                    }
                },
                "type": "object"
            },
            "MatchPlayer": {
                "required": [
                    "user_id",
                    "team",
                    "kills",
                    "deaths",
                    "assists",
                    "damage_dealt",
                    "input_device_flags",
                    "left_match",
                    "leave_reason",
                    "level",
                    "match_presence",
                    "party_info"
                ],
                "properties": {
                    "user_id": {
                        "type": "integer",
                        "example": 1234567
                    },
                    "team": {
                        "description": "Team index, `-1` while the player has not picked a team.",
                        "type": "integer",
                        "minimum": -1,
                        "example": 0
                    },
                    "kills": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 18
                    },
                    "deaths": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 9
                    },
                    "assists": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 4
                    },
                    "damage_dealt": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 1870
                    },
                    "input_device_flags": {
                        "description": "Bit flags of the input devices: `1` mouse and keyboard, `2` touch screen, `4` gamepad.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 2
                    },
                    "left_match": {
                        "type": "boolean",
                        "example": false
                    },
                    "leave_reason": {
                        "description": "Why the player left, for one who did: `Left`, `Timeout`, `Kicked`, `Banned`, `PingLimit`, `AFK` or another\nreason. `null` for one who stayed.",
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": null
                    },
                    "level": {
                        "description": "Gun Game level the player reached.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 0
                    },
                    "match_presence": {
                        "description": "Share of the match the player was in, `0` for one who left.",
                        "type": "number",
                        "maximum": 1,
                        "minimum": 0,
                        "example": 1
                    },
                    "party_info": {
                        "description": "The player's party, `null` for none.",
                        "required": [
                            "is_leader",
                            "players"
                        ],
                        "properties": {
                            "is_leader": {
                                "type": "boolean",
                                "example": true
                            },
                            "players": {
                                "type": "array",
                                "items": {
                                    "type": "integer"
                                },
                                "example": [
                                    1234567,
                                    7654321
                                ]
                            }
                        },
                        "type": [
                            "object",
                            "null"
                        ]
                    }
                },
                "type": "object"
            },
            "MatchStats": {
                "description": "Totals over the matches of one game type in one season.",
                "required": [
                    "k",
                    "d",
                    "a",
                    "w",
                    "l"
                ],
                "properties": {
                    "k": {
                        "description": "Kills.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 1520
                    },
                    "d": {
                        "description": "Deaths.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 1310
                    },
                    "a": {
                        "description": "Assists.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 240
                    },
                    "w": {
                        "description": "Matches won.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 95
                    },
                    "l": {
                        "description": "Matches lost.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 80
                    }
                },
                "type": "object"
            },
            "PlayerLevel": {
                "description": "Player level and experience progress.",
                "required": [
                    "level",
                    "current_xp",
                    "next_level_xp"
                ],
                "properties": {
                    "level": {
                        "description": "Player level, starting from 1.",
                        "type": "integer",
                        "minimum": 1,
                        "example": 42
                    },
                    "current_xp": {
                        "description": "Experience gained towards the next level.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 1250
                    },
                    "next_level_xp": {
                        "description": "Experience needed to reach the next level.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 2000
                    }
                },
                "type": "object"
            },
            "PlayerMatchStats": {
                "required": [
                    "user_id",
                    "team",
                    "kills",
                    "deaths",
                    "assists",
                    "damage_dealt",
                    "input_device_flags",
                    "left_match",
                    "leave_reason",
                    "ping",
                    "user_type",
                    "is_owner"
                ],
                "properties": {
                    "user_id": {
                        "type": "integer",
                        "example": 1234567
                    },
                    "team": {
                        "description": "Team index, `-1` while the player has not picked a team.",
                        "type": "integer",
                        "minimum": -1,
                        "example": 0
                    },
                    "kills": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 18
                    },
                    "deaths": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 9
                    },
                    "assists": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 4
                    },
                    "damage_dealt": {
                        "type": "integer",
                        "minimum": 0,
                        "example": 1870
                    },
                    "input_device_flags": {
                        "description": "Bit flags of the input devices: `1` mouse and keyboard, `2` touch screen, `4` gamepad.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 2
                    },
                    "left_match": {
                        "type": "boolean",
                        "example": false
                    },
                    "leave_reason": {
                        "description": "Why the player left, for one who did: `Left`, `Timeout`, `Kicked`, `Banned`, `PingLimit`, `AFK` or another\nreason. `null` for one who stayed.",
                        "type": [
                            "string",
                            "null"
                        ],
                        "example": null
                    },
                    "ping": {
                        "description": "Last measured ping in milliseconds, `-1` while disconnected.",
                        "type": "integer",
                        "minimum": -1,
                        "example": 42
                    },
                    "user_type": {
                        "description": "Account type, as `basic_info.user_type` of a profile.\n\n`0` Spectator, `1` User, `2` Assistant mod, `4` Moderator, `8` Veteran mod, `64` Developer",
                        "type": "integer",
                        "enum": [
                            0,
                            1,
                            2,
                            4,
                            8,
                            64
                        ],
                        "example": 1,
                        "x-enum-varnames": [
                            "Spectator",
                            "User",
                            "AssistantMod",
                            "Moderator",
                            "VeteranMod",
                            "Developer"
                        ]
                    },
                    "is_owner": {
                        "description": "Whether the player owns the room and can restart the match.",
                        "type": "boolean",
                        "example": true
                    }
                },
                "type": "object"
            },
            "Profile": {
                "description": "Public profile of a player.",
                "required": [
                    "basic_info",
                    "account_age",
                    "blocked_friend_requests",
                    "blocked_clan_requests",
                    "party_invite_permissions",
                    "ban",
                    "stats"
                ],
                "properties": {
                    "basic_info": {
                        "$ref": "#/components/schemas/ProfileBasicInfo"
                    },
                    "account_age": {
                        "description": "How old the player's account is at most: `1w` for an account under a week old, `1m` under a month, `3m` under\n3 months, `1y` under a year, and `2y`, `3y` and `4y` likewise. An account 4 years old or older is `5y+`.",
                        "type": "string",
                        "enum": [
                            "1w",
                            "1m",
                            "3m",
                            "1y",
                            "2y",
                            "3y",
                            "4y",
                            "5y+"
                        ],
                        "example": "2y"
                    },
                    "blocked_friend_requests": {
                        "description": "Whether the player refuses friend requests.",
                        "type": "boolean",
                        "example": false
                    },
                    "blocked_clan_requests": {
                        "description": "Whether the player refuses clan invitations.",
                        "type": "boolean",
                        "example": false
                    },
                    "party_invite_permissions": {
                        "description": "Who may invite the player to a party.\n\n`0` Anybody, `1` Only friends and clan members, `2` Nobody",
                        "type": "integer",
                        "enum": [
                            0,
                            1,
                            2
                        ],
                        "example": 0,
                        "x-enum-varnames": [
                            "Anybody",
                            "OnlyFriendsAndClanMembers",
                            "Nobody"
                        ]
                    },
                    "ban": {
                        "description": "The player's active ban, or `null` when the player is not banned.",
                        "oneOf": [
                            {
                                "$ref": "#/components/schemas/Ban"
                            },
                            {
                                "type": "null"
                            }
                        ]
                    },
                    "stats": {
                        "$ref": "#/components/schemas/ProfileStats"
                    },
                    "clan": {
                        "$ref": "#/components/schemas/ClanMembership",
                        "description": "The player's clan. Absent when the player is not in a clan."
                    }
                },
                "type": "object"
            },
            "ProfileBasicInfo": {
                "description": "Identity and level of a player.",
                "required": [
                    "user_id",
                    "name",
                    "user_type",
                    "icon_id",
                    "player_level",
                    "last_seen_time"
                ],
                "properties": {
                    "user_id": {
                        "description": "Player user ID.",
                        "type": "integer",
                        "minimum": 1,
                        "example": 1234567
                    },
                    "name": {
                        "description": "Player username.",
                        "type": "string",
                        "example": "Player123"
                    },
                    "user_type": {
                        "description": "Account type.\n\n`0` Spectator, `1` User, `2` Assistant mod, `4` Moderator, `8` Veteran mod, `64` Developer",
                        "type": "integer",
                        "enum": [
                            0,
                            1,
                            2,
                            4,
                            8,
                            64
                        ],
                        "example": 1,
                        "x-enum-varnames": [
                            "Spectator",
                            "User",
                            "AssistantMod",
                            "Moderator",
                            "VeteranMod",
                            "Developer"
                        ]
                    },
                    "icon_id": {
                        "description": "Item ID of the emblem the player has equipped, `0` when none.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 0
                    },
                    "player_level": {
                        "$ref": "#/components/schemas/PlayerLevel"
                    },
                    "last_seen_time": {
                        "description": "Last time the player was online. Only disclosed to friends, so always an empty string in the public API.",
                        "type": "string",
                        "example": ""
                    }
                },
                "type": "object"
            },
            "ProfileStats": {
                "description": "Match statistics and ranked standing of a player.",
                "required": [
                    "seasonal_stats",
                    "ranked",
                    "leaderboard_data"
                ],
                "properties": {
                    "seasonal_stats": {
                        "description": "One entry per season, from season 0 up to the current season, ordered by season.",
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/SeasonStats"
                        }
                    },
                    "ranked": {
                        "$ref": "#/components/schemas/RankedStats"
                    },
                    "leaderboard_data": {
                        "$ref": "#/components/schemas/LeaderboardPosition"
                    }
                },
                "type": "object"
            },
            "RankedStats": {
                "description": "Standing of a player in the current ranked season.",
                "required": [
                    "placement_matches_left",
                    "wins",
                    "losses",
                    "highest_rank",
                    "mmr",
                    "global_position",
                    "rank"
                ],
                "properties": {
                    "placement_matches_left": {
                        "description": "Placement matches the player still has to play before getting a rank.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 0
                    },
                    "wins": {
                        "description": "Ranked matches won this season.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 95
                    },
                    "losses": {
                        "description": "Ranked matches lost this season.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 80
                    },
                    "highest_rank": {
                        "description": "Highest rank reached this season.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 12
                    },
                    "mmr": {
                        "description": "Matchmaking rating.",
                        "type": "integer",
                        "example": 2150
                    },
                    "global_position": {
                        "description": "Position on the Elite Ops list of top players, `0` when the player is not on it.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 0
                    },
                    "rank": {
                        "description": "Current rank: `0` while placement matches are left, rising with the rating, with the highest rank reserved for\nElite Ops players.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 11
                    }
                },
                "type": "object"
            },
            "SeasonStats": {
                "description": "Statistics of one season, split by game type.",
                "required": [
                    "season",
                    "ranked",
                    "casual",
                    "custom"
                ],
                "properties": {
                    "season": {
                        "description": "Season number.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 18
                    },
                    "ranked": {
                        "$ref": "#/components/schemas/MatchStats",
                        "description": "Ranked matches."
                    },
                    "casual": {
                        "$ref": "#/components/schemas/MatchStats",
                        "description": "Casual matches."
                    },
                    "custom": {
                        "$ref": "#/components/schemas/MatchStats",
                        "description": "Custom matches."
                    }
                },
                "type": "object"
            },
            "ServerStatus": {
                "description": "Availability of one game server.",
                "required": [
                    "name",
                    "status"
                ],
                "properties": {
                    "name": {
                        "description": "Server name.",
                        "type": "string",
                        "example": "EU-1"
                    },
                    "status": {
                        "description": "`online` when the server accepts players; `offline` when it is down or in maintenance.",
                        "type": "string",
                        "enum": [
                            "online",
                            "offline"
                        ],
                        "example": "online"
                    }
                },
                "type": "object"
            },
            "WeaponStats": {
                "description": "Totals of one weapon.",
                "required": [
                    "weapon_id",
                    "name",
                    "k",
                    "a",
                    "h"
                ],
                "properties": {
                    "weapon_id": {
                        "description": "Id of the weapon in the game data.",
                        "type": "integer",
                        "example": 4
                    },
                    "name": {
                        "description": "Name of the weapon in the game data, such as `AK47` or `SmokeGrenade`.",
                        "type": "string",
                        "example": "AK47"
                    },
                    "k": {
                        "description": "Kills.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 1520
                    },
                    "a": {
                        "description": "Assists.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 240
                    },
                    "h": {
                        "description": "Headshots.",
                        "type": "integer",
                        "minimum": 0,
                        "example": 410
                    }
                },
                "type": "object"
            }
        },
        "responses": {
            "BadRequest": {
                "description": "Bad Request.\n\n- `bad_request`: A request parameter is malformed or out of range.",
                "headers": {
                    "X-RateLimit-Limit": {
                        "$ref": "#/components/headers/X-RateLimit-Limit"
                    },
                    "X-RateLimit-Remaining": {
                        "$ref": "#/components/headers/X-RateLimit-Remaining"
                    },
                    "X-RateLimit-Reset": {
                        "$ref": "#/components/headers/X-RateLimit-Reset"
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "bad_request": {
                                "summary": "A request parameter is malformed or out of range.",
                                "value": {
                                    "error": {
                                        "code": "bad_request",
                                        "message": "A request parameter is malformed or out of range."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "Unauthorized": {
                "description": "Unauthorized.\n\n- `missing_token`: The request carries no API token.\n- `invalid_token`: The API token is malformed or does not exist.\n- `token_revoked`: The API token has been revoked.",
                "headers": {
                    "WWW-Authenticate": {
                        "$ref": "#/components/headers/WWW-Authenticate"
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "missing_token": {
                                "summary": "The request carries no API token.",
                                "value": {
                                    "error": {
                                        "code": "missing_token",
                                        "message": "The request carries no API token."
                                    }
                                }
                            },
                            "invalid_token": {
                                "summary": "The API token is malformed or does not exist.",
                                "value": {
                                    "error": {
                                        "code": "invalid_token",
                                        "message": "The API token is malformed or does not exist."
                                    }
                                }
                            },
                            "token_revoked": {
                                "summary": "The API token has been revoked.",
                                "value": {
                                    "error": {
                                        "code": "token_revoked",
                                        "message": "The API token has been revoked."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "Forbidden.\n\n- `insufficient_permissions`: The API token lacks a permission this endpoint requires.",
                "headers": {
                    "X-RateLimit-Limit": {
                        "$ref": "#/components/headers/X-RateLimit-Limit"
                    },
                    "X-RateLimit-Remaining": {
                        "$ref": "#/components/headers/X-RateLimit-Remaining"
                    },
                    "X-RateLimit-Reset": {
                        "$ref": "#/components/headers/X-RateLimit-Reset"
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "insufficient_permissions": {
                                "summary": "The API token lacks a permission this endpoint requires.",
                                "value": {
                                    "error": {
                                        "code": "insufficient_permissions",
                                        "message": "The API token lacks a permission this endpoint requires."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "NotFound": {
                "description": "Not Found.\n\n- `user_not_found`: A requested player does not exist.\n- `game_not_found`: The hosted game is gone, belongs to another token, or has no open room.",
                "headers": {
                    "X-RateLimit-Limit": {
                        "$ref": "#/components/headers/X-RateLimit-Limit"
                    },
                    "X-RateLimit-Remaining": {
                        "$ref": "#/components/headers/X-RateLimit-Remaining"
                    },
                    "X-RateLimit-Reset": {
                        "$ref": "#/components/headers/X-RateLimit-Reset"
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "user_not_found": {
                                "summary": "A requested player does not exist.",
                                "value": {
                                    "error": {
                                        "code": "user_not_found",
                                        "message": "A requested player does not exist."
                                    }
                                }
                            },
                            "game_not_found": {
                                "summary": "The hosted game is gone, belongs to another token, or has no open room.",
                                "value": {
                                    "error": {
                                        "code": "game_not_found",
                                        "message": "The hosted game is gone, belongs to another token, or has no open room."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "TooManyRequests": {
                "description": "Too Many Requests.\n\n- `rate_limited`: The API token used up its requests for the current minute; retry after `retry_after` seconds.",
                "headers": {
                    "X-RateLimit-Limit": {
                        "$ref": "#/components/headers/X-RateLimit-Limit"
                    },
                    "X-RateLimit-Remaining": {
                        "$ref": "#/components/headers/X-RateLimit-Remaining"
                    },
                    "X-RateLimit-Reset": {
                        "$ref": "#/components/headers/X-RateLimit-Reset"
                    },
                    "Retry-After": {
                        "$ref": "#/components/headers/Retry-After"
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "rate_limited": {
                                "summary": "The API token used up its requests for the current minute; retry after `retry_after` seconds.",
                                "value": {
                                    "error": {
                                        "code": "rate_limited",
                                        "message": "The API token used up its requests for the current minute; retry after `retry_after` seconds.",
                                        "retry_after": 17
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "InternalServerError": {
                "description": "Internal Server Error.\n\n- `internal_error`: The server failed to handle the request.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "internal_error": {
                                "summary": "The server failed to handle the request.",
                                "value": {
                                    "error": {
                                        "code": "internal_error",
                                        "message": "The server failed to handle the request."
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "ServiceUnavailable": {
                "description": "Service Unavailable.\n\n- `server_unavailable`: The game server is offline or not taking requests right now; retry later or use another server.\n- `api_disabled`: The public API is temporarily disabled, for example for maintenance.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        },
                        "examples": {
                            "server_unavailable": {
                                "summary": "The game server is offline or not taking requests right now; retry later or use another server.",
                                "value": {
                                    "error": {
                                        "code": "server_unavailable",
                                        "message": "The game server is offline or not taking requests right now; retry later or use another server."
                                    }
                                }
                            },
                            "api_disabled": {
                                "summary": "The public API is temporarily disabled, for example for maintenance.",
                                "value": {
                                    "error": {
                                        "code": "api_disabled",
                                        "message": "The public API is temporarily disabled, for example for maintenance."
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "parameters": {
            "UserId": {
                "name": "user_id",
                "in": "query",
                "description": "User ID of the player.",
                "required": true,
                "schema": {
                    "type": "integer",
                    "minimum": 1
                },
                "example": 1234567
            }
        },
        "headers": {
            "X-RateLimit-Limit": {
                "description": "Requests the token may make per minute.",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "example": 60
                }
            },
            "X-RateLimit-Remaining": {
                "description": "Requests the token has left in the current minute.",
                "schema": {
                    "type": "integer",
                    "minimum": 0,
                    "example": 59
                }
            },
            "X-RateLimit-Reset": {
                "description": "Unix time, in seconds, when the current minute ends and the quota is renewed.",
                "schema": {
                    "type": "integer",
                    "example": 1790000040
                }
            },
            "Retry-After": {
                "description": "Seconds to wait before the token may make requests again.",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "example": 17
                }
            },
            "WWW-Authenticate": {
                "description": "Authentication scheme the API expects.",
                "schema": {
                    "type": "string",
                    "example": "Bearer realm=\"cops-public-api\""
                }
            }
        },
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "description": "API token in the `Authorization` header: `Authorization: Bearer cops_...`.",
                "bearerFormat": "cops_ followed by 48 hex digits",
                "scheme": "bearer"
            },
            "apiKeyAuth": {
                "type": "apiKey",
                "description": "API token in the `X-Api-Key` header, for clients that cannot set `Authorization`.",
                "name": "X-Api-Key",
                "in": "header"
            }
        }
    },
    "security": [
        {
            "bearerAuth": []
        },
        {
            "apiKeyAuth": []
        }
    ],
    "tags": [
        {
            "name": "Players",
            "description": "Player profiles and statistics."
        },
        {
            "name": "Matches",
            "description": "Match history and results."
        },
        {
            "name": "Leaderboards",
            "description": "Players ranked by their statistics in the current ranked season."
        },
        {
            "name": "Servers",
            "description": "Game server availability."
        },
        {
            "name": "Autohost",
            "description": "Custom games hosted on request, for tournaments and similar events. Needs the `Autohost` permission."
        },
        {
            "name": "Meta",
            "description": "The API itself."
        }
    ]
}
