{"openapi":"3.1.0","info":{"title":"ValCord Central API","description":"API for looking up consenting Discord members' Valorant stats. See https://docs.valcord.smasse.xyz for integration guides.","version":"1.0.0"},"paths":{"/auth/login":{"get":{"tags":["auth"],"summary":"Login","operationId":"login_auth_login_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/callback":{"get":{"tags":["auth"],"summary":"Callback","operationId":"callback_auth_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","operationId":"logout_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/revoke":{"post":{"tags":["auth"],"summary":"Revoke Access","description":"Turns off global consent AND destroys the session in one action —\nthe user is fully logged out and must click \"Login with Discord\" (which\nalways forces Discord's own authorize/consent screen via prompt=consent)\nto be visible to any server again.","operationId":"revoke_access_auth_revoke_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/users/me":{"get":{"tags":["users"],"summary":"Get Me","operationId":"get_me_v1_users_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/users/me/guilds":{"get":{"tags":["users"],"summary":"List Guilds","description":"Every guild this user is in (from the cached OAuth guilds list),\njoined with whether they currently allow stat lookups there. A guild\nwith no server_permissions row is reported as not-allowed — the API\nnever implies an opt-in that was never explicitly recorded.","operationId":"list_guilds_v1_users_me_guilds_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/users/me/accounts":{"post":{"tags":["users"],"summary":"Link Account","description":"Riot RSO (real ownership-verified linking) is pending Riot Developer\nProgram approval — see docs/ARCHITECTURE.md. Until then this accepts a\nself-reported Riot ID and stores it with verified_via_rso=False, purely\nto exercise the rest of the pipeline. The pseudo-PUUID is a deterministic\nhash of the Riot ID so the UNIQUE(riot_puuid) constraint still behaves\nlike it will in production (same Riot ID can't be linked twice).","operationId":"link_account_v1_users_me_accounts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkAccountRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/accounts/{account_id}/primary":{"post":{"tags":["users"],"summary":"Set Primary Account","operationId":"set_primary_account_v1_users_me_accounts__account_id__primary_post","parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/accounts/{account_id}":{"delete":{"tags":["users"],"summary":"Unlink Account","operationId":"unlink_account_v1_users_me_accounts__account_id__delete","parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/users/me/servers/{guild_id}/permission":{"put":{"tags":["users"],"summary":"Set Server Permission","operationId":"set_server_permission_v1_users_me_servers__guild_id__permission_put","parameters":[{"name":"guild_id","in":"path","required":true,"schema":{"type":"integer","title":"Guild Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PermissionUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stats/player":{"post":{"tags":["stats"],"summary":"Get Player Stats","operationId":"get_player_stats_v1_stats_player_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerStatsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/stats/matches":{"post":{"tags":["stats"],"summary":"Get Player Matches","description":"Recent match history for a consenting player, tracker.gg-style: every\nparticipant in each match is included (that's inherent to what a match\nis — Riot's own data always contains all 10 players), but the gate that\ndecides whether you can look up this match history at all is the exact\nsame one /v1/stats/player uses. You still cannot target a non-consenting\nDiscord user directly; the other 9 names per match are a side effect of\na consenting player's own history, never an independent lookup target.","operationId":"get_player_matches_v1_stats_matches_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerMatchesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerMatchesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/instances":{"get":{"tags":["instances"],"summary":"List Instances","operationId":"list_instances_v1_instances_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["instances"],"summary":"Create Instance","operationId":"create_instance_v1_instances_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInstanceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/instances/{instance_id}/revoke":{"post":{"tags":["instances"],"summary":"Revoke Instance","operationId":"revoke_instance_v1_instances__instance_id__revoke_post","parameters":[{"name":"instance_id","in":"path","required":true,"schema":{"type":"string","title":"Instance Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/content":{"get":{"tags":["riot-data"],"summary":"Get Content","operationId":"get_content_v1_content_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/leaderboard":{"get":{"tags":["riot-data"],"summary":"Get Leaderboard","operationId":"get_leaderboard_v1_leaderboard_get","parameters":[{"name":"region","in":"query","required":false,"schema":{"type":"string","default":"na","title":"Region"}},{"name":"act_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Act Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaderboardResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/status":{"get":{"tags":["riot-data"],"summary":"Get Status","operationId":"get_status_v1_status_get","parameters":[{"name":"region","in":"query","required":false,"schema":{"type":"string","default":"na","title":"Region"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/healthz":{"get":{"summary":"Healthz","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"ContentAct":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","name","is_active"],"title":"ContentAct"},"ContentAgent":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"ContentAgent"},"ContentGameMode":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"}},"type":"object","required":["id","name"],"title":"ContentGameMode"},"ContentMap":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"asset_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Asset Path"}},"type":"object","required":["id","name"],"title":"ContentMap"},"ContentResponse":{"properties":{"version":{"type":"string","title":"Version"},"maps":{"items":{"$ref":"#/components/schemas/ContentMap"},"type":"array","title":"Maps"},"agents":{"items":{"$ref":"#/components/schemas/ContentAgent"},"type":"array","title":"Agents"},"game_modes":{"items":{"$ref":"#/components/schemas/ContentGameMode"},"type":"array","title":"Game Modes"},"acts":{"items":{"$ref":"#/components/schemas/ContentAct"},"type":"array","title":"Acts"}},"type":"object","required":["version","maps","agents","game_modes","acts"],"title":"ContentResponse"},"CreateInstanceRequest":{"properties":{"guild_id":{"type":"string","title":"Guild Id"}},"type":"object","required":["guild_id"],"title":"CreateInstanceRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"LeaderboardEntry":{"properties":{"riot_game_name":{"type":"string","title":"Riot Game Name"},"riot_tag_line":{"type":"string","title":"Riot Tag Line"},"leaderboard_rank":{"type":"integer","title":"Leaderboard Rank"},"ranked_rating":{"type":"integer","title":"Ranked Rating"},"wins":{"type":"integer","title":"Wins"}},"type":"object","required":["riot_game_name","riot_tag_line","leaderboard_rank","ranked_rating","wins"],"title":"LeaderboardEntry"},"LeaderboardResponse":{"properties":{"region":{"type":"string","title":"Region"},"act_id":{"type":"string","title":"Act Id"},"entries":{"items":{"$ref":"#/components/schemas/LeaderboardEntry"},"type":"array","title":"Entries"}},"type":"object","required":["region","act_id","entries"],"title":"LeaderboardResponse"},"LinkAccountRequest":{"properties":{"riot_game_name":{"type":"string","title":"Riot Game Name"},"riot_tag_line":{"type":"string","title":"Riot Tag Line"},"region":{"type":"string","title":"Region"}},"type":"object","required":["riot_game_name","riot_tag_line","region"],"title":"LinkAccountRequest"},"MatchParticipant":{"properties":{"riot_game_name":{"type":"string","title":"Riot Game Name"},"riot_tag_line":{"type":"string","title":"Riot Tag Line"},"team":{"type":"string","title":"Team"},"agent":{"type":"string","title":"Agent"},"kills":{"type":"integer","title":"Kills"},"deaths":{"type":"integer","title":"Deaths"},"assists":{"type":"integer","title":"Assists"},"score":{"type":"integer","title":"Score"},"is_target":{"type":"boolean","title":"Is Target","description":"True for the consenting player this lookup was for"}},"type":"object","required":["riot_game_name","riot_tag_line","team","agent","kills","deaths","assists","score","is_target"],"title":"MatchParticipant"},"MatchSummary":{"properties":{"match_id":{"type":"string","title":"Match Id"},"map":{"type":"string","title":"Map"},"mode":{"type":"string","title":"Mode"},"started_at":{"type":"string","format":"date-time","title":"Started At"},"result":{"type":"string","title":"Result","description":"'win', 'loss', or 'draw', from the target player's perspective"},"rounds_won":{"type":"integer","title":"Rounds Won"},"rounds_lost":{"type":"integer","title":"Rounds Lost"},"participants":{"items":{"$ref":"#/components/schemas/MatchParticipant"},"type":"array","title":"Participants"}},"type":"object","required":["match_id","map","mode","started_at","result","rounds_won","rounds_lost","participants"],"title":"MatchSummary"},"PermissionUpdate":{"properties":{"is_allowed":{"type":"boolean","title":"Is Allowed"}},"type":"object","required":["is_allowed"],"title":"PermissionUpdate"},"PlatformIncident":{"properties":{"id":{"type":"integer","title":"Id"},"title":{"type":"string","title":"Title"},"severity":{"type":"string","title":"Severity","description":"'info', 'warning', or 'critical'"}},"type":"object","required":["id","title","severity"],"title":"PlatformIncident"},"PlatformStatusResponse":{"properties":{"region":{"type":"string","title":"Region"},"maintenances":{"items":{"$ref":"#/components/schemas/PlatformIncident"},"type":"array","title":"Maintenances"},"incidents":{"items":{"$ref":"#/components/schemas/PlatformIncident"},"type":"array","title":"Incidents"}},"type":"object","required":["region","maintenances","incidents"],"title":"PlatformStatusResponse"},"PlayerMatchesRequest":{"properties":{"guild_id":{"type":"integer","title":"Guild Id","description":"Discord Guild ID the request originates from"},"target_discord_id":{"type":"integer","title":"Target Discord Id","description":"Discord user ID whose match history is being requested"},"riot_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Riot Account Id","description":"Optional: specific linked riot_accounts.id; defaults to the user's primary account"},"count":{"type":"integer","maximum":10.0,"minimum":1.0,"title":"Count","description":"Number of recent matches to return","default":5}},"type":"object","required":["guild_id","target_discord_id"],"title":"PlayerMatchesRequest"},"PlayerMatchesResponse":{"properties":{"matches":{"items":{"$ref":"#/components/schemas/MatchSummary"},"type":"array","title":"Matches"}},"type":"object","required":["matches"],"title":"PlayerMatchesResponse"},"PlayerStatsRequest":{"properties":{"guild_id":{"type":"integer","title":"Guild Id","description":"Discord Guild ID the request originates from"},"target_discord_id":{"type":"integer","title":"Target Discord Id","description":"Discord user ID whose stats are being requested"},"riot_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Riot Account Id","description":"Optional: specific linked riot_accounts.id; defaults to the user's primary account"}},"type":"object","required":["guild_id","target_discord_id"],"title":"PlayerStatsRequest"},"PlayerStatsResponse":{"properties":{"riot_game_name":{"type":"string","title":"Riot Game Name"},"riot_tag_line":{"type":"string","title":"Riot Tag Line"},"region":{"type":"string","title":"Region"},"rank":{"type":"string","title":"Rank"},"rr":{"type":"integer","title":"Rr"},"kd_ratio":{"type":"number","title":"Kd Ratio"},"win_rate":{"type":"number","title":"Win Rate"},"matches_played":{"type":"integer","title":"Matches Played"},"headshot_pct":{"type":"number","title":"Headshot Pct"}},"type":"object","required":["riot_game_name","riot_tag_line","region","rank","rr","kd_ratio","win_rate","matches_played","headshot_pct"],"title":"PlayerStatsResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}