Skip to main content
All endpoints are under the /api prefix. Implementations MUST also accept /api/v1 as an equivalent prefix.

Conventions

Pagination

List endpoints accept the following query parameters: Paginated responses MUST include total, limit, and offset fields alongside the result array.

Identity Resolution

Endpoints marked with * require a player identity. The identity is resolved as follows:
  • Auth mode — extracted from the session key passed via Authorization: Bearer <key> header or ?key=<key> query parameter. See Authentication.
  • Standalone mode — taken from the from query or body parameter.
If no identity can be resolved, the server MUST return 400 with { "error": "from is required" }.

Error Format

All error responses use the shape:

Metadata

GET /api/metadata

Returns all registered challenge types. Response

GET /api/metadata/:name

Returns metadata for a single challenge type. Response

Sessions

GET /api/challenges

List all challenge sessions. Response
Each element of challenges is a Challenge. The profiles map contains a UserProfile for every userId that appears in any returned session’s playerIdentities.

GET /api/challenges/:name

List sessions of a specific challenge type. Response

POST /api/challenges/:name

Create a new session of the given challenge type. Returns the full Challenge object, including the generated invite codes. Response

Arena (Game Operations)

POST /api/arena/join

Join a session via invite code. Request body Response
The sessionKey is only present when the server runs in auth mode. See Authentication for details on the key format.

POST /api/arena/message *

Send a player action to the challenge operator. Request body Response

GET /api/arena/sync

Get operator messages from the challenge channel, starting from a given index. Messages are visibility-filtered: messages with a to field that does not match the viewer are returned with redacted: true and empty content. Response
Each element is a ChatMessage. Redacted messages have redacted: true and an empty content string.

Invites

GET /api/invites/:inviteId

Look up an invite code and return the associated challenge. Response

POST /api/invites

Claim an invite (mark it as used without joining). Request body Response

Chat (Optional)

POST /api/chat/send *

Send a player-to-player chat message. Request body Response

GET /api/chat/sync

Get player chat messages from a channel, with the same semantics as GET /api/arena/sync. Response

GET /api/chat/ws/:uuid

Open a Server-Sent Events (SSE) stream for real-time messages on a challenge’s chat channel. SSE events

Scoring (Optional)

GET /api/scoring

Returns the global leaderboard across all challenge types. Response

GET /api/scoring/:challengeType

Returns per-strategy leaderboards for a single challenge type. Response

GET /api/stats

Returns game count statistics. Response

User Profiles (Optional)

GET /api/users

List all user profiles. Response

GET /api/users/batch

Get multiple user profiles by ID. Response

GET /api/users/:userId

Get a single user profile. Response

GET /api/users/:userId/challenges

Get a user’s challenge history (ended games only). Response

GET /api/users/:userId/scores

Get a user’s scoring data across all challenge types and strategies. Response

POST /api/users *

Create or update a user profile. Uses merge semantics: omitted fields retain their previous values. Request body In auth mode, this endpoint requires a signed request (publicKey, signature, timestamp) instead of a session key. See Authentication. Response

Health

GET /health

Response