01 / Build the connection
Create a player session
Sign the JWT that connects a player to their game instance.
When a player opens a game, your backend generates a JWT token containing the player's identity and current balance. The token is signed with RS256 (RSA-SHA256) using your private key - the same key pair you registered with Wildvolt.
JWT Payload
{
"iss": "674313a46a5c39392ce82995",
"sub": "player_12345",
"aud": "6818d6a417bc778023664625",
"iat": 1712401234,
"exp": 1712412034,
"data": {
"balance": 1234.56,
"name": "PlayerName",
"timestamp": 1712401234567
}
}| Claim | Description |
|---|---|
iss | Your Operator ID (received during registration) |
sub | Player ID - must match the player_id you use in webhook responses |
aud | The game to launch - either a Game Instance ID (that exact instance) or a Game ID (your instance of that game). See Choosing the target below. |
currency | Optional, top-level claim (a sibling of aud, not inside data). When aud is a Game ID and you run multiple instances of that game, selects the instance whose configured currency matches (e.g. "ETB"). |
iat | Issued at, Unix seconds |
exp | Expiry, Unix seconds. Maximum 3 hours after iat |
data.balance | Player's current balance as a float (e.g., 1234.56 not cents) |
data.name | Player display name shown in-game |
data.timestamp | Balance snapshot time, Unix milliseconds (UTC) |
Choosing the target: instance ID vs game ID
The aud claim can be either:
- A Game Instance ID - launches that exact instance (received when your game instances are configured). This is the precise, recommended form.
- A Game ID (e.g.
aviator,classic-keno) - launches your instance of that game. With a single instance it is used directly; with multiple instances (for example, one per currency) the first is chosen unless you also sendcurrency.
Selecting by currency
When aud is a Game ID and you run multiple instances of it, add the optional top-level currency claim - a sibling of aud, not inside data - to select the instance whose configured currency matches:
{
"iss": "674313a46a5c39392ce82995",
"sub": "player_12345",
"aud": "aviator",
"currency": "ETB",
"iat": 1712401234,
"exp": 1712412034,
"data": { "balance": 1234.56, "name": "PlayerName", "timestamp": 1712401234567 }
}Resolution when currency is present:
audis an instance ID whose configured currency differs → the token is rejected (CURRENCY_MISMATCH).audis a game ID with no instance in that currency → rejected (GAME_INSTANCE_NOT_FOUND).- Otherwise the matching instance is launched.
Omit currency to keep the default (first-instance) behavior. Existing tokens are unaffected.
Signing Examples
Node.js
const jwt = require('jsonwebtoken');
const fs = require('fs');
const PRIVATE_KEY = fs.readFileSync('private_key.pem');
function generateGameToken(operatorId, playerId, instanceId, balance, playerName) {
const now = Math.floor(Date.now() / 1000);
return jwt.sign({
iss: operatorId,
sub: playerId,
aud: instanceId,
iat: now,
exp: now + 3 * 3600,
data: {
balance: balance,
name: playerName,
timestamp: Date.now()
}
}, PRIVATE_KEY, { algorithm: 'RS256' });
}Python
import jwt
import time
def generate_game_token(operator_id, player_id, instance_id, balance, player_name):
now = int(time.time())
payload = {
"iss": operator_id,
"sub": player_id,
"aud": instance_id,
"iat": now,
"exp": now + 3 * 3600,
"data": {
"balance": balance,
"name": player_name,
"timestamp": int(time.time() * 1000)
}
}
with open("private_key.pem", "rb") as f:
private_key = f.read()
return jwt.encode(payload, private_key, algorithm="RS256")Using the Token
Pass the token as a query parameter when loading the game iframe. Its aud claim identifies the assigned instance:
https://games.wildvoltgames.com/{game_id}?token={jwt_token}Notes
- Generate tokens server-side only. Never expose your private key to the client.
- The
balancein the token is a snapshot. Wildvolt will call/player-balanceto get the current value during gameplay. - If the token is expired or has an invalid signature, the game will not load.