The Lobby API powers the Mixton Arena competitive team-draft system. Admins configure teams and captains; captains log in via Discord OAuth2 and use this API to pick players during the draft phase. All REST endpoints are mounted underDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/VasquezRivero92/Discord_Faceit/llms.txt
Use this file to discover all available pages before exploring further.
/api/lobby and protected by the verifyUserToken middleware, which validates the same JWT cookie issued by the Auth API — but does not require an admin role, allowing assigned captains to authenticate.
Admin-only endpoints in this section additionally apply a
verifyGuildAdmin middleware check. Captains can only call endpoints documented as Draft Action endpoints when it is their turn.Authentication
Every request must carry theauth_token or admin_token cookie. Missing cookies return 401. Role scoping follows the same rules as the Admin API: admin users are restricted to their own guild, while global_admin users can target any guild via ?guildId=, x-guild-id header, or body guildId.
State
GET /api/lobby/me
Returns the current authenticated user’s decoded JWT payload. ResponseGET /api/lobby/users
Returns all verified users from Firestore enriched with Discord display details (displayName, avatarURL). Useful for populating player-selection dropdowns in the lobby UI.
Response
GET /api/lobby/mixton-state
Returns the full, real-time state of the lobby for the resolved guild. This is the primary data source for the lobby UI. ResponsePlayers who have run
/mixton_listo and are not yet assigned to any team. Keyed by ELO tier: S (Level 10), A (Levels 8–9), B (Levels 5–7), C (Levels 1–4). Entries within each tier are sorted by ELO descending. Tier can be overridden per-player by an admin.Whether the
/mixton_listo and /mixton_no_listo Discord commands are currently enabled for this guild.Admin Setup
All endpoints in this section requireadmin or global_admin role.
POST /api/lobby/mixton-setup
Configures the number of teams for the lobby. Resets all teams, pick order, captain assignments, and draft state. Request BodyNumber of teams to create. Must be between
2 and 6.POST /api/lobby/mixton-assign-captain
Assigns a verified user as the captain of a specific team. Captains must be Tier S or Tier A (Level 8+, or with an S/A tier override). Automatically sends a DM to the assigned captain with a login link. Request BodyTeam ID (e.g.
"team_1").Discord user ID of the player to assign as captain. Pass
null or omit to clear the captain.400 if the player’s tier is not S or A.
POST /api/lobby/mixton-pick-order
Sets the captain draft pick order. Every team ID in the array must have a captain assigned. Request BodyOrdered array of team IDs. Example:
["team_2", "team_1", "team_2", "team_1"].POST /api/lobby/mixton-start
Starts the draft phase. Requires all teams to have captains assigned. Clears any previously picked players and setsdraftStarted: true.
Response
400 if fewer than 2 teams exist or any team lacks a captain.
POST /api/lobby/mixton-create-match
Converts two fully-assembled lobby teams into a live Discord match. Both teams must be complete — each needs a captain and exactly 4 picked players (5 total). Creates two locked voice channels, moves members, posts a match announcement embed with result-reporting buttons, sends individual DMs to each player, and saves the match tofaceit_active_matches. After this call, the lobby can be reset for the next session.
Request Body
Team ID of the first team (e.g.
"team_1").Team ID of the second team (e.g.
"team_2").400 if either team is incomplete (missing captain or fewer than 4 picked players), or 404 if the team IDs are not found in the current lobby state.
POST /api/lobby/mixton-reset
Resets the entire lobby to its default state (2 empty teams, no pick order, draft not started). ResponsePOST /api/lobby/mixton-load-team
Bulk-loads a full roster (captain + players) into a team. Resolves Firestore profiles for each player and removes them from any other team they may already occupy. Useful for importing pre-arranged teams. Request BodyTarget team ID.
Discord ID (or Faceit UUID) of the captain.
Array of Discord IDs (or Faceit UUIDs) of players to assign to the team.
POST /api/lobby/mixton-clear-team
Removes the captain and all players from the specified team’s roster. Request BodyTeam ID to clear.
POST /api/lobby/mixton-reset-players
Marks all players who ran/mixton_listo as no longer ready, clearing the available player queue.
Response
Number of players whose ready status was reset.
POST /api/lobby/mixton-remove-player
This route name is registered twice in the router with different parameter shapes, serving two distinct purposes depending on which fields are sent in the request body. Usage 1 — Remove from ready queue Removes a specific player from the/mixton_listo ready queue. The player will no longer appear in the available player list until they run /mixton_listo again.
Discord user ID of the player to remove from the queue. Do not include
teamId.Usage 2 — Remove from a team roster Removes a player from a specific team’s
players array without affecting their ready status.
Team ID to remove the player from (e.g.
"team_1").Discord user ID of the player to remove from the team.
404 if the team ID is not found.
POST /api/lobby/mixton-toggle-command
Enables or disables the/mixton_listo and /mixton_no_listo Discord slash commands for the guild. The setting is persisted in the guild’s Firestore settings document.
Request Body
true to enable the commands, false to disable them.POST /api/lobby/mixton-override-tier
Overrides the ELO tier bucket used to classify a player in the available players list. Settingtier to null removes the override and reverts to the player’s Faceit level.
Request Body
Discord user ID of the player.
One of
"S", "A", "B", "C", or null to reset.POST /api/lobby/mixton-assign-player
Directly assigns a player to a team without waiting for the draft pick order. The player is removed from any other team they were previously on. A team can hold a maximum of 4 picked players (plus the captain). Request BodyTarget team ID.
Discord user ID of the player to assign.
Draft Action
POST /api/lobby/mixton-pick
The captain whose turn it is picks a player from the available pool. Admins can also make picks on behalf of any captain. After a successful pick thecurrentPickIndex advances, the player is moved from availablePlayers to the team’s players array, and a WebSocket state broadcast is sent to all connected clients.
Request Body
Discord user ID of the player to pick. The player must have
mixton_ready: true in Firestore and not already be assigned to any team.400 if the draft is not active, if the player is already picked, or if the player is not ready. Returns 403 if the caller is not the current captain and not an admin.
Match Launch
POST /api/lobby/create-match
Creates a manual 5v5 match from two arrays of Discord IDs. Validates all players against Firestore, creates two locked voice channels, moves members to their respective channels, posts a match announcement embed with result-reporting buttons, sends individual DMs to each player, and saves the match tofaceit_active_matches.
Request Body
Array of exactly 5 Discord user ID strings for Team A.
Array of exactly 5 Discord user ID strings for Team B.
400 if either team does not have exactly 5 players, or if any player is unregistered or belongs to a different guild (for admin role).
GET /api/lobby/guilds
Returns the list of guilds accessible to the authenticated user.admin users only see their own guild; global_admin users see all guilds the bot has joined. Returns 403 for non-admin users.
Response
WebSocket
WS /api/lobby/mixton-ws
A persistent WebSocket connection that streams real-time lobby state updates to all connected clients. The upgrade is handled at the HTTP server level via thews library — it does not go through the standard Express router.
Connection URL
Filter state broadcasts to a specific guild. If omitted, the connection receives updates for the primary
DISCORD_GUILD_ID.guildId receive a fresh state_update message with the full current state.
Client Example
The WebSocket connection does not require a JWT cookie at the transport level. Authentication is enforced at the REST API level before any state-modifying action is processed. If you need to restrict WebSocket connections, you can validate the cookie during the HTTP upgrade handshake in the server configuration.