{"openapi":"3.1.0","info":{"title":"PeekSeek","version":"0.1.0"},"paths":{"/queue/heartbeat":{"get":{"tags":["queue"],"summary":"Queue Heartbeat","description":"Keep the player, and their whole party, if they lead one, in queue, and\nreport back if they've been matched.\n\nQueueing does not make a match. A free game server in the player's region is what\nscans this queue and forms one (see `/server/v1/session`), so this only ever adds\nthem to it and reports what happened elsewhere.","operationId":"queue_heartbeat_queue_heartbeat_get","parameters":[{"name":"gamemode","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gamemode"}},{"name":"region","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Region"}},{"name":"team","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Team"}},{"name":"eventId","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Eventid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/queue/quit":{"get":{"tags":["queue"],"summary":"Queue Quit","operationId":"queue_quit_queue_quit_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/ping":{"get":{"tags":["queue","ops"],"summary":"Liveness check","description":"Answers `Pong` as long as the app is serving. Nothing behind it is checked.","operationId":"ping_ping_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/build":{"get":{"tags":["queue","ops"],"summary":"Which build is deployed","description":"The `BUILD` label this instance was started with, so a deploy can be identified\nwithout reading the container's logs.","operationId":"build_build_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/match/current":{"get":{"tags":["match"],"summary":"Match Current","description":"Polled by the in-match screen, returns the live match state as JSON.","operationId":"match_current_match_current_get","parameters":[{"name":"matchId","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Matchid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/match/decide":{"post":{"tags":["match"],"summary":"Match Decide","description":"Submit a pre-match decision: map/side pick, kit, or powerup.","operationId":"match_decide_match_decide_post","parameters":[{"name":"pick","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pick"}},{"name":"kit","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kit"}},{"name":"powerup","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Powerup"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/match/custom":{"post":{"tags":["match"],"summary":"Custom Create","description":"Create a custom match (premium only).","operationId":"custom_create_match_custom_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/user/changeuuid":{"post":{"tags":["account"],"summary":"Change Uuid","description":"Rotate the caller's session UUID and notify them.","operationId":"change_uuid_user_changeuuid_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/kit/{steam64}":{"get":{"tags":["player"],"summary":"Public Kit Data","description":"Every saved kit for a player, fully resolved into ready-to-equip item lists:\npublic, no auth, no match context needed. For anything that has to equip\nsomeone without a live match (the lobby server, in particular).","operationId":"public_kit_data_kit__steam64__get","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/reputation/{steam64}":{"get":{"tags":["player"],"summary":"Public Reputation","description":"A player's Elo, public and unauthenticated, what the lobby server mirrors\ninto their in-game reputation so rank is visible over someone's head.\n\nDeliberately just Elo: Unturned moves reputation itself on kills and other\nactions, so anything reading this has to be able to re-assert the real value\nrather than track a drifting one.","operationId":"public_reputation_reputation__steam64__get","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/session":{"get":{"tags":["game server"],"summary":"Server Session","description":"The one call a game server makes on a loop. Answers what it should be doing.\n\n`matchId` is the match the server holds, including one it has finished but not yet\nreported; `0` means it is free. Matchmaking runs here, so a match is only ever made\nfor a server standing by to host it.\n\n`action` is one of:\n\n- `idle`: nothing to do. Ask again shortly.\n- `wait`: the match is yours but its players are still choosing. Keep sending its id.\n- `host`: start it. Sent once per match; asking again while hosting answers `idle`.\n- `abort`: drop it. Nobody is coming.\n\nA match a server still names is never written off, which is what makes the result\nreport safe to retry indefinitely.","operationId":"server_session_server_v1_session_get","parameters":[{"name":"serverCode","in":"query","required":false,"schema":{"type":"string","default":"0","title":"Servercode"}},{"name":"matchId","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Matchid"}}],"responses":{"200":{"description":"What to do next","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionAnswer"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/matches/{matchId}":{"get":{"tags":["game server"],"summary":"Gameserver Match","description":"A match's state. `relayTo` is the server code to send its players to, and stays\nnull until there is a server to send them to.","operationId":"gameserver_match_server_v1_matches__matchId__get","parameters":[{"name":"matchId","in":"path","required":true,"schema":{"type":"integer","title":"Matchid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MatchState"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/matches/{matchId}/rounds":{"post":{"tags":["game server"],"summary":"Match Rounds","description":"Rounds won per team, sent each time a round is decided.\n\nBody: `{\"wins\": {\"<team name>\": <rounds won>, ...}}`. Each report replaces the last,\nso a lost one is covered by the next.","operationId":"match_rounds_server_v1_matches__matchId__rounds_post","parameters":[{"name":"matchId","in":"path","required":true,"schema":{"type":"integer","title":"Matchid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"description":"`POST /matches/{matchId}/rounds`. Each report replaces the last, so a lost one is\ncovered by the next.","properties":{"wins":{"additionalProperties":{"type":"integer"},"description":"team name -> rounds won","title":"Wins","type":"object"}},"required":["wins"],"title":"RoundWinsReport","type":"object"}}}}}},"/server/v1/matches/{matchId}/result":{"post":{"tags":["game server"],"summary":"Match Result","description":"The match's final per-player line. This is what moves Elo, and what ends a match.\n\nSafe to retry: a repeat is answered `alreadyRecorded` and changes nothing. Accepted\nfor a match already marked finished, since that is what happens to one whose result\nwas slow to arrive.\n\nBody:\n    played       false when nobody turned up. Scores nothing, releases the match.\n    winningTeam  the `name` of the winning team, or null.\n    draw         true when the match ended level. Elo moves on kills and deaths.\n    players      every player on the roster, including no-shows and leavers.","operationId":"match_result_server_v1_matches__matchId__result_post","parameters":[{"name":"matchId","in":"path","required":true,"schema":{"type":"integer","title":"Matchid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"description":"`POST /matches/{matchId}/result`. The match's final per-player line.","properties":{"played":{"default":true,"description":"false when nobody turned up: scores nothing","title":"Played","type":"boolean"},"winningTeam":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Winningteam"},"draw":{"default":false,"title":"Draw","type":"boolean"},"players":{"description":"every player on the roster, including no-shows and leavers","items":{"description":"One player's line on a match result. Everything but the id is optional.","properties":{"steam64":{"title":"Steam64","type":"integer"},"won":{"default":false,"title":"Won","type":"boolean"},"kills":{"default":0,"minimum":0,"title":"Kills","type":"integer"},"deaths":{"default":0,"minimum":0,"title":"Deaths","type":"integer"},"headshotKills":{"default":0,"minimum":0,"title":"Headshotkills","type":"integer"},"hits":{"default":0,"minimum":0,"title":"Hits","type":"integer"},"headshotHits":{"default":0,"minimum":0,"title":"Headshothits","type":"integer"},"damageDealt":{"default":0,"minimum":0,"title":"Damagedealt","type":"integer"},"damageTaken":{"default":0,"minimum":0,"title":"Damagetaken","type":"integer"}},"required":["steam64"],"title":"PlayerLine","type":"object"},"title":"Players","type":"array"}},"title":"MatchResultReport","type":"object"}}}}}},"/server/v1/players/{steam64}/decide":{"post":{"tags":["game server"],"summary":"Decide Player","description":"Lock this player's kit and/or powerup for the match they are on.\n\nBoth fields are optional and checked against the gamemode. Once every player has\nlocked both, the outstanding map/ballistics/movement picks are decided at once,\nsince nobody picking in game is at a browser to make them.\n\nAnswers with the same `choose` block `GET /players/{steam64}` returns.","operationId":"decide_player_server_v1_players__steam64__decide_post","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}},{"name":"kit","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kit"}},{"name":"powerup","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Powerup"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Decision"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/gamemodes":{"get":{"tags":["game server"],"summary":"Gamemodes","description":"What a player can queue for, in menu order, for a server that asks in game.\n`bit` is the gamemode's position in the whole list, which is what a queue mask means.","operationId":"gamemodes_server_v1_gamemodes_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Gamemodes"}}}}}}},"/server/v1/lobby/population":{"post":{"tags":["game server"],"summary":"Lobby Population","description":"How many are in this lobby right now, once per heartbeat.\n\nBody:\n    players   connected to the lobby and not on a match.\n    queueing  how many of those want a match. Optional.\n    held      how many the lobby is keeping out of the queue. Optional.\n\nOptional counts are stored as absent rather than zero, so an older lobby that does\nnot report them never reads as nobody wanting a match.","operationId":"lobby_population_server_v1_lobby_population_post","requestBody":{"content":{"application/json":{"schema":{"properties":{"players":{"type":"integer","minimum":0.0,"title":"Players","default":0},"queueing":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Queueing"},"held":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Held"}},"type":"object","title":"LobbyPopulationReport","description":"`POST /lobby/population`, once per lobby heartbeat.\n\n`queueing` and `held` stay None when the lobby does not report them, rather than\nbecoming zero: an older lobby that has never sent them must not read as nobody\nwanting a match."}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}}}}},"/server/v1/players/{steam64}":{"get":{"tags":["game server"],"summary":"Gameserver Player","description":"Everything a server needs to know about one player. Asking does not queue them.","operationId":"gameserver_player_server_v1_players__steam64__get","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerState"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/players/{steam64}/kits":{"get":{"tags":["game server"],"summary":"Player Kits","description":"Every kit this player has saved, resolved into ready-to-equip items, with the\nmagazine broken out so a caller can keep the spare topped up.","operationId":"player_kits_server_v1_players__steam64__kits_get","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/SavedKit"},"title":"Response Player Kits Server V1 Players  Steam64  Kits Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/players/{steam64}/queue":{"put":{"tags":["game server"],"summary":"Join Queue","description":"Put this player in the matchmaking queue, or keep them in it.\n\nCalled on a timer for everyone in a lobby, so it is both \"join\" and \"still here\".\n`gamemodes` is a bitmask and `ip` the address they play from. Answers like\n`GET /players/{steam64}`. A barred player is refused, and the ban comes back on\nthe `ban` field.","operationId":"join_queue_server_v1_players__steam64__queue_put","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}},{"name":"gamemodes","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Gamemodes"}},{"name":"region","in":"query","required":false,"schema":{"type":"string","default":"paris","title":"Region"}},{"name":"ip","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerState"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["game server"],"summary":"Leave Queue","operationId":"leave_queue_server_v1_players__steam64__queue_delete","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/reports":{"post":{"tags":["game server"],"summary":"Submit Report","description":"An in-game /report, multipart so the reported player's screenshot arrives with it.\n\nThe counters are the server's own, since a lobby and a match server reset them at\ndifferent times.","operationId":"submit_report_server_v1_reports_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_submit_report_server_v1_reports_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReportAccepted"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/server/v1/players/{steam64}/bans":{"post":{"tags":["game server"],"summary":"Ban Player","description":"A ban issued by anti-cheat on a game server. An empty body bans for \"Cheating\".","operationId":"ban_player_server_v1_players__steam64__bans_post","parameters":[{"name":"steam64","in":"path","required":true,"schema":{"type":"integer","title":"Steam64"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Status"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"description":"`POST /players/{steam64}/bans`. An empty body bans for \"Cheating\".","properties":{"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"title":"GuardBan","type":"object"}}}}}},"/party/":{"get":{"tags":["party"],"summary":"Party Status","description":"Polled by the play page: your party's roster, your pending invites, and\n(so a non-owner member's tab knows to redirect once the leader queues) whether\nyou're already in a match.","operationId":"party_status_party__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/party/invite":{"post":{"tags":["party"],"summary":"Party Invite","operationId":"party_invite_party_invite_post","parameters":[{"name":"target","in":"query","required":true,"schema":{"type":"integer","title":"Target"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/party/accept":{"post":{"tags":["party"],"summary":"Party Accept","operationId":"party_accept_party_accept_post","parameters":[{"name":"partyId","in":"query","required":true,"schema":{"type":"integer","title":"Partyid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/party/decline":{"post":{"tags":["party"],"summary":"Party Decline","operationId":"party_decline_party_decline_post","parameters":[{"name":"partyId","in":"query","required":true,"schema":{"type":"integer","title":"Partyid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/party/leave":{"post":{"tags":["party"],"summary":"Party Leave","operationId":"party_leave_party_leave_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"Ban":{"properties":{"reason":{"type":"string","title":"Reason"},"expires":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires"},"permanent":{"type":"boolean","title":"Permanent"}},"type":"object","required":["reason","expires","permanent"],"title":"Ban"},"Body_submit_report_server_v1_reports_post":{"properties":{"reported":{"type":"integer","title":"Reported"},"reporter":{"type":"integer","title":"Reporter"},"reason":{"type":"string","title":"Reason"},"serverCode":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Servercode"},"where":{"type":"string","title":"Where","default":"a PeekSeek server"},"channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel"},"staffRole":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Staffrole"},"damageDealt":{"type":"integer","title":"Damagedealt","default":0},"shotsFired":{"type":"integer","title":"Shotsfired","default":0},"shotsHit":{"type":"integer","title":"Shotshit","default":0},"headshotHits":{"type":"integer","title":"Headshothits","default":0},"screenshot":{"anyOf":[{"type":"string","contentMediaType":"application/octet-stream"},{"type":"null"}],"title":"Screenshot"}},"type":"object","required":["reported","reporter","reason"],"title":"Body_submit_report_server_v1_reports_post"},"Choices":{"properties":{"kits":{"items":{"type":"string"},"type":"array","title":"Kits"},"powerups":{"items":{"type":"string"},"type":"array","title":"Powerups"},"kit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kit"},"powerup":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Powerup"}},"type":"object","required":["kits","powerups","kit","powerup"],"title":"Choices","description":"What a player still gets to decide, and what they have decided so far. A list with\none entry is not a choice and comes back empty."},"Decision":{"properties":{"matchId":{"type":"integer","title":"Matchid"},"choose":{"anyOf":[{"$ref":"#/components/schemas/Choices"},{"type":"null"}]}},"type":"object","required":["matchId","choose"],"title":"Decision","description":"`POST /players/{steam64}/decide`."},"Gamemode":{"properties":{"bit":{"type":"integer","title":"Bit"},"name":{"type":"string","title":"Name"},"blurb":{"type":"string","title":"Blurb"},"usesElo":{"type":"boolean","title":"Useselo"}},"type":"object","required":["bit","name","blurb","usesElo"],"title":"Gamemode","description":"`bit` is the gamemode's position in the whole list, which is what a queue mask\nmeans. Positions never move."},"Gamemodes":{"properties":{"gamemodes":{"items":{"$ref":"#/components/schemas/Gamemode"},"type":"array","title":"Gamemodes"}},"type":"object","required":["gamemodes"],"title":"Gamemodes"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"Item":{"properties":{"itemId":{"type":"integer","title":"Itemid"},"amount":{"type":"integer","title":"Amount"},"state":{"items":{"type":"integer"},"type":"array","title":"State"}},"type":"object","required":["itemId","amount","state"],"title":"Item","description":"A kit item, resolved from the stored `[itemId, amount, \"1,2,3\"]` tuple."},"MatchState":{"properties":{"id":{"type":"integer","title":"Id"},"region":{"type":"string","title":"Region"},"status":{"type":"string","title":"Status"},"relayTo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relayto"}},"type":"object","required":["id","region","status","relayTo"],"title":"MatchState","description":"`GET /matches/{matchId}`. `relayTo` is the server code to send this match's\nplayers to, and stays null until there is a server to send them to."},"PlayerState":{"properties":{"steam64":{"type":"string","title":"Steam64"},"name":{"type":"string","title":"Name"},"avatar":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar"},"elo":{"type":"integer","title":"Elo"},"rankIcon":{"type":"string","title":"Rankicon"},"matchId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Matchid"},"relayTo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relayto"},"choose":{"anyOf":[{"$ref":"#/components/schemas/Choices"},{"type":"null"}]},"ban":{"anyOf":[{"$ref":"#/components/schemas/Ban"},{"type":"null"}]}},"type":"object","required":["steam64","name","avatar","elo","rankIcon","matchId","relayTo","choose","ban"],"title":"PlayerState","description":"One player as every player-facing route here reports them. A `matchId` with no\n`relayTo` means matched and still choosing."},"ReportAccepted":{"properties":{"status":{"type":"string","title":"Status"},"delivered":{"type":"boolean","title":"Delivered"}},"type":"object","required":["status","delivered"],"title":"ReportAccepted","description":"`POST /reports`. `delivered` is false when Discord was down, which is not an\nerror the game server could do anything about."},"SavedKit":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Item"},"type":"array","title":"Items"},"magazine":{"anyOf":[{"$ref":"#/components/schemas/Item"},{"type":"null"}]}},"type":"object","required":["items","magazine"],"title":"SavedKit","description":"One of a player's saved kits, with the magazine broken out so a caller can keep\nthe spare topped up."},"SessionAnswer":{"properties":{"action":{"type":"string","title":"Action","description":"idle | wait | host | abort"},"region":{"type":"string","title":"Region"},"queuedInRegion":{"type":"integer","title":"Queuedinregion"},"matchId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Matchid","description":"on wait and abort"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"on abort: unknownMatch | matchOver | hostedElsewhere"},"waiting_on":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Waiting On","description":"on wait"},"selection_ends_at":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Selection Ends At","description":"on wait, Unix seconds"},"match":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Match","description":"the roster on wait, the whole match on host"},"options":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Options","description":"on wait: the kits and powerups to choose between"},"picked":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Picked","description":"on wait: what each player has locked so far"}},"type":"object","required":["action","region","queuedInRegion"],"title":"SessionAnswer","description":"`GET /session`, the one call a game server makes on a loop.\n\nDocumented rather than enforced: this is the only answer here whose shape depends on\n`action`, and a response model would have to list every field as optional, which\nwould add a null for each one a given answer does not carry. The contract is that a\nfield is absent, not null, so the model describes the union and the route returns\nexactly what it built.\n\n`region` and `queuedInRegion` are on every answer, so a region mismatch reads off the\nconsole instead of looking like an empty queue."},"Status":{"properties":{"status":{"type":"string","title":"Status"},"matchId":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Matchid"}},"type":"object","required":["status"],"title":"Status","description":"What a write answers. `status` says which of the two things happened, so a retried\nwrite can be told apart from a first one."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}