SDK

Player accounts and tokens

Players can play every game as guests. Players with a Smaz Games account get account saves and can be identified by your own servers. Your game never sees a player's email address, sign-in details, session cookie, exact age, uploaded picture or friends. It sees only whether the player is under 18.

Player details

const player = await OpenArcade.getUser();
if (player) {
  label.textContent = player.name;   // or player.username
}

getUser() resolves to null for guests, or:

FieldMeaning
playerIdStable ID for this player in your game only. The same person has a different playerId in every game, so games cannot match players with each other
usernamePublic handle: 3 to 24 lowercase letters, numbers or _. Players can change it
nameDisplay name. Players can change it
avatarThe preset avatar the player picked (rocket, ghost, cat, bolt, planet, controller), or custom for an uploaded picture. Uploaded pictures are not shared with games
minortrue unless the account belongs to an adult

Use playerId as the key in your own database. Never use username or name as an identifier: they change. Show the current name or username each time the game starts.

The values from getUser() come from the player's browser, so a modified browser could change them. To trust who a player is on your server, use a token.

Asking players to sign in

signInButton.onclick = async () => {
  await saveProgressNow();
  await OpenArcade.promptSignIn();   // opens the site's sign-in dialog
};

After signing in, the game frame reloads with the player's account, and init() reports the player. Call promptSignIn() only from a button the player pressed, such as Sign in to save online. Never block play behind sign-in, and do not build your own sign-in screens that ask for Smaz Games details.

Player tokens

getPlayerToken() gives your game a signed token that proves who the player is to your own server, such as a multiplayer server or leaderboard.

const { token } = await OpenArcade.getPlayerToken();
const socket = new WebSocket('wss://play.example.com/join');
socket.onopen = () => socket.send(JSON.stringify({ type: 'hello', token }));
  • The token is a JWT signed with ES256. It is valid for 10 minutes.
  • Request a fresh token for each connection. Do not store tokens.
  • Guests get a 401 error. Offer guest play without online features, or ask the player to sign in.
  • List your server under Outside addresses on the upload form, or the browser blocks the connection.

Token contents

{
  "iss": "https://smazgames.com",
  "aud": "smaz:3f6c2a6e-0b7d-4f4e-9d0a-5d1d1f5f7a21",
  "sub": "Zq3V8f1mQe2y0x9Kp4bA7w",
  "game": "3f6c2a6e-0b7d-4f4e-9d0a-5d1d1f5f7a21",
  "username": "pixel_fox",
  "name": "Pixel Fox",
  "minor": false,
  "iat": 1761200000,
  "nbf": 1761199995,
  "exp": 1761200600,
  "jti": "8d1e2b0a-6a9a-4b67-9d3e-4c0f0b3c7e11"
}
ClaimMeaning
issAlways https://smazgames.com
audsmaz: followed by your game ID. Your game ID is shown on each game in the developer dashboard
subThe player's playerId for your game
gameYour game ID
username, nameThe player's current public names
minortrue unless the account belongs to an adult. Apply the chat rules
iat, nbf, expIssued, not-before and expiry times, in seconds
jtiUnique token ID. Store recent IDs if you want to reject replays

Verifying tokens

The public keys are published as a JSON Web Key Set at:

https://smazgames.com/api/sdk/jwks.json

Verify the signature, the issuer, the audience and the expiry on your server. With Node.js and the jose library:

import { createRemoteJWKSet, jwtVerify } from 'jose';

const JWKS = createRemoteJWKSet(new URL('https://smazgames.com/api/sdk/jwks.json'));
const GAME_ID = '3f6c2a6e-0b7d-4f4e-9d0a-5d1d1f5f7a21';

export async function verifyPlayer(token) {
  const { payload } = await jwtVerify(token, JWKS, {
    issuer: 'https://smazgames.com',
    audience: 'smaz:' + GAME_ID,
    algorithms: ['ES256'],
    clockTolerance: 30
  });
  return { playerId: payload.sub, name: payload.name, minor: payload.minor };
}

In Python with PyJWT:

import jwt

jwks = jwt.PyJWKClient("https://smazgames.com/api/sdk/jwks.json")

def verify_player(token, game_id):
    key = jwks.get_signing_key_from_jwt(token)
    payload = jwt.decode(token, key.key, algorithms=["ES256"],
                         audience="smaz:" + game_id, issuer="https://smazgames.com", leeway=30)
    return payload["sub"], payload["name"], payload["minor"]
  • Cache the key set; the libraries above do this for you. Keys are identified by kid. If a token has an unknown kid, fetch the key set again.
  • Reject tokens with a different aud. A token for another game must not work on your server.
  • Use a token only to check who the player is. Do not send tokens to anyone else, sell them, log them, store them after checking them or put them in URLs your server records.

Testing

In local test mode, ?smazUser=test signs in a test player and getPlayerToken() returns the string local-test-token, which does not verify. Accept it only in your own development builds. In private previews, tokens are real and use your game ID, so you can test your server before release.

Player data rules

  • Collect only what your game needs. Do not ask for email addresses, phone numbers, real names or locations.
  • Do not try to match players across games or sites, or to find out who a player is outside your game. playerId is different in every game on purpose.
  • If your game stores player data on your servers, declare it on the upload form (Collects personal data on its own servers), publish a privacy policy that covers it and follow the privacy laws that apply to you and your players.
  • Never ask for a player's Smaz Games password, and never show a login form that looks like the site's.