Skip to main content
The game server has no login of its own. Your backend vouches for each player with a session token: an HS256 JWT signed with your SESSION_SECRET. The element asks your backend for one when it connects and again before the token expires. The browser never signs or changes a token.

The session endpoint

Add POST /api/game-session to your backend, behind your own player login. It reads the player your login authenticated, signs a token and answers it as plain text with cache-control: no-store. To anyone who is not signed in, it answers HTTP 401. The path is your choice; the dashboard’s code and these docs use /api/game-session. The element posts a JSON body. Its first call is {}; later calls carry the player’s device key as {"publicKey": "<43-character base64url key>"}.
session-token.mjs
game-session.mjs
Any JWT library works if it produces HS256 with the claims below.

On the Integration page

The Sign session tokens step on Integration shows the claims your tokens carry, with your casino ID, your session issuer and your currencies filled in, under Session token claims. If your session issuer is not set, the step shows Set your session issuer in Settings. Your tokens carry it as iss. with Open settings: set it under Players and sessions. The page itself shows no signer and no endpoint. The Instructions for your coding agent at the top of the page include a Node signer with your casino ID and issuer filled in. See Use an AI agent.

Claims

The game server answers unauthorized to a token that fails any of these rules, with no detail about which one. Session token reference lists every check in order.

Currencies

A token names one currency. A player who plays in two currencies has two balances and needs a token for each: sign the token for the currency the page shows. The game server’s catalog and limits follow the token’s currency.

Device keys

The element signs every bet and action with an Ed25519 key that it keeps in the player’s browser. That signature lets the player prove later that they placed the bet.
  • With cnf. When your token carries the device key the element sent you, the session may sign only with that key, and the game server enrolls the key for the player the first time it signs. A player can then continue on a second device, after clearing site data or in a private window, and can cash out a round opened elsewhere.
  • Without cnf. The first key that signs for a player enrolls on first use. Any other key later fails with player_key_changed, and the player stays locked out until you attest a new key with cnf.
Put cnf on every token you sign. Attest only a key that the player you authenticated for this request sent you, and pass it through unchanged: the game server refuses any other cnf shape as unauthorized. Enrollment only adds keys. It never changes an earlier proof: each bet keeps the key that signed it.

Lifetime and renewal

  • Sign tokens for a few minutes; the examples use 15. The element asks for a new token shortly before the current one expires, and moves its connection to the new token without a disconnect.
  • The element asks for one token at a time and reuses it until renewal. A token request that takes longer than 10 seconds fails and is retried with backoff.
  • If your endpoint answers the same token again, the element asks again later. Answer a fresh token each time.
  • Never cache tokens in the browser yourself, and never sign them in the browser.
The element’s first call carries no device key. The element reads the player and currency from that first token, then asks again with its device key before it opens its connection. A browser that cannot keep a device key uses the first token.