Skip to content

Launching games

There's no client SDK for the operator side of the launch call — you sign the request yourself, server-side, in whatever stack you're running. See Signing & authentication for the HMAC construction and a self-contained signRequest example.

Sign and call the launch endpoint

signRequest below is the function documented in Signing & authentication.

ts
const path = '/v1/operator/games/launch'
const body = JSON.stringify({
  playerRef,          // your internal player identifier
  gameId,              // which game to launch
  currency,             // e.g. "USD"
  mode: 'REAL',        // 'REAL' | 'DEMO'
  language: 'zh-TW',  // optional — BCP-47 tag, e.g. "en", "zh-TW"
  lobbyUrl: 'https://your-site.example/lobby', // optional — see "Returning to the lobby" below
})

const headers = signRequest('POST', path, operatorSecret, body, operatorId)

const res = await fetch(`${platformUrl}${path}`, {
  method: 'POST',
  headers: { ...headers, 'Content-Type': 'application/json' },
  body,
})
if (!res.ok) {
  // 400/401/403/429 — see the Operator API reference's error list
  throw new Error(`launch failed: ${res.status} ${await res.text()}`)
}
const { launchUrl, sessionToken } = await res.json()
// launchUrl: the game's URL, with the session token already appended —
//   embed this directly in an iframe.
// sessionToken: also returned standalone; the provider's game client
//   presents this on its own wallet calls (you don't use it directly).

Every field maps 1:1 onto the request body the platform expects — see the Operator API reference for the exact shapes and every error case, including the 403 a risk-control block returns.

Choosing a currency

currency is required and must be one of the target game's provider's configured currencies — the platform team configures that set once per provider, and every game that provider owns shares it (there's no per-game currency configuration). Check it via the currencies field on GameSummary (see "Listing your game catalog" below), or visually on your tenant's portal's Catalog page. Requesting a currency outside that set fails the launch call with 400.

Requesting a language

language is optional — omit it and the game falls back to its own default (typically "en"). When you do pass one, it must be in the target game's provider's supported-languages set. Check it the same two ways as currency: the supportedLanguages field on GameSummary, or your tenant's portal Catalog page. Requesting a language outside that set fails the launch call with 400.

Returning to the lobby

lobbyUrl is optional. When you pass it, the game's "back to lobby" control navigates the whole top-level window directly to that URL — a plain redirect, which works even if you embed the game in a bare iframe with no shell listening for bridge messages. It must be an absolute http or https URL; anything else fails the launch call with 400.

If you omit lobbyUrl, the game falls back to its existing behavior: it asks your embedding shell to close it via the EXIT_GAME bridge message (see Shell bridge) — the game can't close the iframe it's running in by itself, so your shell decides where "back" goes.

REAL vs DEMO mode

  • REAL (default) — launches against a real session backed by your actual operator wallet integration — see Implementing the wallet callback for what that integration needs to do. Also gated by the risk-control launch check (blocklist / self-exclusion) — a blocked player's launch call fails with 403.
  • DEMO — mints a session backed by a temporary fake balance instead of a real wallet session; your wallet callback API is never called. Useful for demoing a game to a player (or yourself) without touching real funds, or for verifying your shell integration end-to-end before your wallet backend is ready — see Testing. Unlike REAL, DEMO launches skip the catalog-visibility check (so you can demo a game before the platform team has made it visible to your tenant), but the risk-control check still applies — a self-excluded player can't play in DEMO mode either.

Listing your game catalog

ts
// GET /v1/operator/games, signed the same way (empty body)

Returns the games visible to your operator tenant — see GameSummary in the reference for the exact shape (game ID, display name, provider, supported currencies, supported languages, launch base URL, and replay base URL if the game supports round replay).

Embed the game

Once you have launchUrl, load it into an iframe on your page:

html
<iframe src="{launchUrl}" allow="..."></iframe>

Then attach the shell-side bridge listener to receive the game's lifecycle events — see Shell bridge.