Skip to main content
This guide gets you a working lobby in under 5 minutes. No dashboard setup. No player auth. Just curl. By the end, you’ll have created a lobby, joined it with a second player, updated player state, and torn it all down.

Prerequisites

  • A PlayFlow project (free tier works — sign up here)
  • Your Client API Key (from Project Settings → starts with pfclient_)
Use the client key (pfclient_*) for anything a game client can do. Use the server key (pf_*) only for trusted backend services or admin operations.

1. Create a Lobby

A lobby is created by a “host” player. The host is whoever sends the x-player-id header on the create request.
curl -X POST "https://api.computeflow.cloud/api/v3/lobbies/default" \
  -H "api-key: pfclient_YOUR_KEY" \
  -H "x-player-id: player1" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My First Lobby",
    "maxPlayers": 4
  }'
Response:
{
  "id": "a1b2c3d4-...",
  "code": "MEOW-42",
  "config": "default",
  "status": "waiting",
  "host": "player1",
  "currentPlayers": 1,
  "maxPlayers": 4,
  "players": [
    { "id": "player1", "state": null, "isHost": true }
  ],
  ...
}
You just made a lobby. No dashboard config was needed — PlayFlow used defaults. Note the code field: that’s the invite code your players share.

About {config}

The default in the URL is a lobby config name. If no config with that name exists in your dashboard, PlayFlow uses sensible defaults:
  • maxPlayers: 2
  • timeout: 300s
  • serverSize: small
  • Build: latest default
For production games, you’ll create named configs in the dashboard (casual, ranked_2v2, etc.) with custom matchmaking rules and server overrides. But you don’t need to yet.

2. Join as a Second Player

Share the invite code MEOW-42 with your friend. They call:
curl -X POST "https://api.computeflow.cloud/api/v3/lobbies/default/join" \
  -H "api-key: pfclient_YOUR_KEY" \
  -H "x-player-id: player2" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "MEOW-42",
    "state": { "team": "blue", "ready": false }
  }'
They could also join by lobby ID if they have it:
curl -X POST "https://api.computeflow.cloud/api/v3/lobbies/default/join" \
  -H "api-key: pfclient_YOUR_KEY" \
  -H "x-player-id: player2" \
  -H "Content-Type: application/json" \
  -d '{
    "lobbyId": "a1b2c3d4-..."
  }'
The response is the full lobby, now with 2 players:
{
  "id": "a1b2c3d4-...",
  "currentPlayers": 2,
  "players": [
    { "id": "player1", "state": null, "isHost": true },
    { "id": "player2", "state": { "team": "blue", "ready": false }, "isHost": false }
  ],
  ...
}

3. Check Your Current Lobby

Any player can check which lobby they’re in using /me:
curl "https://api.computeflow.cloud/api/v3/lobbies/default/me" \
  -H "api-key: pfclient_YOUR_KEY" \
  -H "x-player-id: player2"
Returns the full lobby state. If you’re not in a lobby, returns 404.
/me is the player-centric primitive throughout the API. Instead of tracking lobby IDs in your game, just use /me endpoints — PlayFlow finds your lobby automatically from the x-player-id header.

4. Update Player State

Ready up, pick a character, set your MMR — anything goes in player state. The server merges your updates into existing state.
curl -X PATCH "https://api.computeflow.cloud/api/v3/lobbies/default/me" \
  -H "api-key: pfclient_YOUR_KEY" \
  -H "x-player-id: player2" \
  -H "Content-Type: application/json" \
  -d '{
    "state": {
      "ready": true,
      "loadout": "sniper",
      "mmr": 1500
    }
  }'
The response shows player2’s updated state:
{
  "players": [
    { "id": "player1", "state": null, "isHost": true },
    {
      "id": "player2",
      "state": {
        "team": "blue",
        "ready": true,
        "loadout": "sniper",
        "mmr": 1500
      },
      "isHost": false
    }
  ],
  ...
}
State updates merge — existing keys are preserved unless overwritten. Setting ready: true doesn’t wipe out team: blue.

5. Start the Game

When ready, the host launches a game server directly:
curl -X POST "https://api.computeflow.cloud/api/v3/lobbies/default/me/start" \
  -H "api-key: pfclient_YOUR_KEY" \
  -H "x-player-id: player1"
The response now has server populated:
{
  "status": "in_game",
  "server": {
    "instanceId": "srv-abc123",
    "status": "launching",
    "region": "us-east",
    "ports": [
      {
        "name": "game",
        "host": "203.0.113.42",
        "port": 7770,
        "protocol": "udp"
      }
    ]
  },
  ...
}
Use server.ports[0].host and server.ports[0].port to connect your game client. The server transitions from launchingrunning in ~10-30 seconds (or ~5s with pool servers).
Only the host can start the game. If a non-host tries, they get a 403 Not host.

6. Leave (Cleanup)

Every player leaves with:
curl -X DELETE "https://api.computeflow.cloud/api/v3/lobbies/default/me" \
  -H "api-key: pfclient_YOUR_KEY" \
  -H "x-player-id: player2"
When the last player leaves, the lobby auto-deletes. The response is {"status": "lobby_deleted"}. If the host leaves while others remain, host transfers to the next player automatically.

That’s It

You’ve now exercised the full lobby lifecycle using just 6 API calls. The full API adds matchmaking, host-only actions (kick, settings), invite code joining, lobby browsing, real-time SSE updates, and more — but this is the 80% of what most games need.

Lobby Lifecycle

Host-only actions (kick, settings, transfer host), leaving behavior, error handling.

Matchmaking

Skip the manual “start” — let PlayFlow find opponents automatically.

Real-time Events

Stop polling. Subscribe to live events with SSE.

API Reference

Every endpoint with full schemas and try-it-out.