Skip to main content
PlayFlow’s lobby system is the bridge between “my players want to play together” and “here’s your dedicated game server.” It handles everything in between: creating rooms, sharing invite codes, queueing for matchmaking, forming matches, and launching game servers.
This is V3, PlayFlow’s primary lobby API. It’s a clean, player-centric REST API with SSE for real-time updates. If you’re migrating from the older NestJS lobby system at api.scale.computeflow.cloud, that system continues to work — V3 is the new recommended path.

Core Concepts

Lobbies

A lobby is a virtual room where players gather before a game starts. Every lobby has:
  • A host — the player who created it (has admin powers: kick, settings, start game)
  • A list of players with their individual state (ready, team, loadout, MMR, etc.)
  • Settings — game-specific data (map, mode, difficulty) that gets passed to the game server
  • A status: waiting, in_queue, in_game, etc.
  • Optional invite code for sharing with friends

Lobby Configs

A lobby config is a reusable template for lobbies. You define it once (in the dashboard or via API) and reference it by name in your code:
  • casual — 8 players, quick play, no MMR
  • ranked_2v2 — 4 players, MMR-based matchmaking, 2 teams of 2
  • monster_hunt — asymmetric, 1 monster vs 5 hunters
Each config specifies server size, build, matchmaking modes, rules, and more.
No dashboard config needed to get started. Any config name in the URL path works — PlayFlow falls back to sensible defaults (2 players, 5-minute timeout, small server size, “default” build) when no matching config exists.

Matchmaking

Matchmaking is when players queue up and the system finds them opponents. A matchmaking game is just a group of lobbies grouped together pointing to the same game server. When two (or more) lobbies enter the queue and match:
  1. They all transition from in_queue to in_game
  2. One dedicated game server is launched
  3. All matched lobbies get the same matchId and server connection info
  4. Players connect to the server and play
Matchmaking supports:
  • Traditional teams — 2v2, 5v5, 100-player FFA, 50-duo battle royale
  • Asymmetric roles — 1 boss vs 5 hunters, custom team compositions
  • Skill-based — MMR difference rules that automatically relax as wait time grows
  • Region-aware — weighted voting across player region preferences
  • Backfill — new players can join matches already in progress

The Two Core Flows

Most games use one of these patterns. Pick the one that fits your game.
“Just put me in a game.” The player presses a button, gets connected to a server within seconds.
1

Player creates a lobby

POST /v3/lobbies/ranked — instant, even with no friends.
2

Host starts matchmaking

POST /v3/lobbies/ranked/me/matchmaking with a mode name.
3

System finds opponents

Another queueing lobby matches within seconds.
4

Game server launches

All matched lobbies get server.ip and server.ports[]. Connect your game client.
Best for: Ranked ladders, competitive play, quick play modes, Counter-Strike/League of Legends-style matchmaking.
You can combine both. A lobby can host friends, then optionally queue for matchmaking to find more players.

Authentication

Every request has two headers:
HeaderPurposeExample
api-keyYour project’s API keypfclient_abc123...
x-player-idUnique identifier for the playerplayer_12345 or any string
x-player-id is not authenticated — it’s just an identifier. PlayFlow trusts whatever value you send. For competitive games, you should verify player identity on your own backend before calling the PlayFlow API (e.g. with a JWT from your auth provider). For Phase 0 / prototyping, a random UUID per session is fine.
No player auth is required to start using lobbies. Ship an MVP with random player IDs, add real auth later when you need it.

Response Shape

Every lobby endpoint returns the same consistent shape:
{
  "id": "a1b2c3d4-...",
  "code": "MEOW-42",
  "config": "ranked",
  "status": "waiting",
  "host": "player1",
  "maxPlayers": 8,
  "currentPlayers": 2,
  "region": "us-east",
  "isPrivate": false,
  "allowLateJoin": true,
  "settings": { "map": "forest" },
  "players": [
    { "id": "player1", "state": { "ready": true }, "isHost": true },
    { "id": "player2", "state": { "ready": false }, "isHost": false }
  ],
  "server": null,
  "matchmaking": null,
  "matchId": null,
  "createdAt": "2026-04-01T00:00:00Z",
  "updatedAt": "2026-04-01T00:00:01Z"
}
When matchmaking is active, matchmaking populates with { mode, startedAt, queueStats }. When a game server is running, server populates with { instanceId, status, region, ports[] }.

What’s Next

Quickstart

Get a working lobby in 5 minutes with copy-paste curl commands.

Lobby Lifecycle

Create, join, update state, kick, transfer host, start games.

Matchmaking

Configure modes, skill-based rules, asymmetric teams, expanding buckets.

Real-time Events

Subscribe to SSE for live lobby updates and queue stats.

API Reference

Every endpoint with request/response schemas and try-it-out.