🎮 Beta Gamer

Chess — Create a session

Sessions are created server-side using your secret API key. Never call this from the browser — your API key would be exposed. The response contains a short-lived JWT sessionToken that is safe to pass to the client.

Endpoint

POSThttps://api.beta-gamer.com/v1/sessions

Request

const res = await fetch('https://api.beta-gamer.com/v1/sessions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer bg_live_xxxx',   // secret API key — server-side only
    'Content-Type':  'application/json',
  },
  body: JSON.stringify({
    game:              'chess',
    matchType:         'matchmaking',   // see matchType options below
    players:           [{ id: 'user_123', displayName: 'Alex' }],
    afkTimeoutEnabled: true,
  }),
});

const { sessionToken, sessionId, expiresAt } = await res.json();
// Pass sessionToken to your client — never the raw API key

Body parameters

ParameterTypeRequiredDefaultDescription
game"chess"YesMust be "chess".
matchType"matchmaking" | "bot" | "private"YesHow the match is created. See matchType details below.
playersPlayer[]Yes{ id, displayName }[]. id is your tenant's userId — it appears in game:over.winner for result identification. displayName is shown in the UI. One entry for matchmaking/bot, two for private.
botDifficulty"easy" | "medium" | "hard"No"medium"Bot strength. Only applies when matchType is "bot".
afkTimeoutEnabledbooleanNotrueWhether the 90-second AFK forfeit rule is active.
themeThemeOverrideNoOverride dashboard theme tokens for this session only. See Theming.

matchType details

matchmaking

Player is placed in a queue. The server pairs them with the next available opponent. Pass one player.

{ game: 'chess', matchType: 'matchmaking', players: [{ id: 'u1', displayName: 'Alex' }] }
bot

Player is immediately matched against an AI. Use botDifficulty to set strength. Pass one player.

{ game: 'chess', matchType: 'bot', botDifficulty: 'hard', players: [{ id: 'u1', displayName: 'Alex' }] }
private

A private room is created. Pass two players — both receive the same sessionToken and connect to the same room.

{ game: 'chess', matchType: 'private', players: [{ id: 'u1', displayName: 'Alex' }, { id: 'u2', displayName: 'Sam' }] }

Response

FieldTypeDescription
sessionIdstringUnique session identifier. Store this server-side to look up results later.
sessionTokenstringShort-lived JWT. Pass to the client and use as the token prop on BetaGamerProvider.
expiresAtstringISO 8601 timestamp. Token is valid until this time (typically 1 hour).
{
  "sessionId":    "sess_01j9abc123",
  "sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uSWQiOiJzZXNzXzAxajlhYmMxMjMiLCJnYW1lIjoiY2hlc3MiLCJtYXRjaFR5cGUiOiJib3QiLCJwbGF5ZXJzIjpbeyJpZCI6InVzZXJfMTIzIiwiZGlzcGxheU5hbWUiOiJBbGV4In1dLCJ0aGVtZSI6e30sImlhdCI6MTc0MjA4MDAwMCwiZXhwIjoxNzQyMDgzNjAwfQ.signature",
  "expiresAt":    "2026-03-16T02:00:00.000Z"
}

Ended sessions

If a player refreshes the page after a game ends, the token is still valid but the session is marked ended. Validate the token before rendering the game UI:

// GET /api/v1/sessions/validate?token=<sessionToken>
const res = await fetch(`/api/v1/sessions/validate?token=${sessionToken}`);
const { status, game, result } = await res.json();

if (status === 'ended') {
  // show final result screen — result: { winner, reason, duration, pgn, fen }
} else {
  // render BetaGamerProvider with the token
}
💡 The session token encodes the game type, players, and theme. The SDK decodes it client-side — no extra API call is needed to start the game after you have the token.
userId vs displayName

players[].id is your tenant's user ID — this is what game:over.winner contains. Always compare winner against players[0].id, never against displayName. Display names can change; user IDs are stable identifiers you control.

Beta Gamer GaaS API — questions? support@beta-gamer.com