Authentication
Slotty Labs uses API keys and SSO tokens to authenticate operators and players.
API Key Format
| Environment | Prefix | Example |
|---|---|---|
| Sandbox | sk_sandbox_ | sk_sandbox_abc123def456... |
| Production | sk_live_ | sk_live_xyz789ghi012... |
DANGER
Sandbox and production keys are NOT interchangeable. A sandbox key will be rejected in production, and vice versa.
Integration Modes
Slotty Labs supports two integration modes:
Transfer Mode
The platform manages player authentication entirely. Slotty Labs creates and manages player accounts internally.
- Simpler to integrate
- Less control over player lifecycle
- Suitable for smaller operators
Seamless Mode (Recommended for B2B)
The operator manages player authentication via SSO. The operator's backend creates launch tokens that map to existing player accounts.
- Full control over player identity
- Single sign-on experience
- Recommended for B2B integrations
SSO Token Flow
The SSO flow consists of 5 steps:
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Operator │ │ Slotty Labs │ │ Game Client │
│ Backend │ │ API │ │ (iframe) │
└────┬─────┘ └──────┬───────┘ └──────┬────────┘
│ │ │
│ 1. POST /auth/sso/create-token │
│ (API key + HMAC)│ │
│─────────────────>│ │
│ │ │
│ 2. JWT launch │ │
│ token (30s) │ │
│<─────────────────│ │
│ │ │
│ 3. Token in URL │ │
│──────────────────┼───────────────────>│
│ │ │
│ │ 4. POST /auth/sso/exchange
│ │<───────────────────│
│ │ │
│ │ 5. Session token │
│ │───────────────────>│
│ │ │- Operator backend calls
POST /api/v1/auth/sso/create-tokenwith API key and HMAC signature - Slotty Labs API returns a single-use JWT launch token with a 30-second TTL
- Operator passes the token to the game iframe via URL parameter
- Game client exchanges the token for a session via
POST /api/v1/auth/sso/exchange - Subsequent API calls use the session token from the exchange response
HMAC Request Signing
All API requests must include HMAC signatures for authentication:
X-Slotty-Timestamp: <unix seconds>
X-Slotty-Signature: sha256=<HMAC-SHA256 of "timestamp.METHOD.path.body">Signing Algorithm
import crypto from 'crypto';
function signRequest(
secret: string,
timestamp: number,
method: string,
path: string,
body: string,
): string {
const payload = `${timestamp}.${method}.${path}.${body}`;
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
return `sha256=${hmac.digest('hex')}`;
}Timestamp Tolerance
The server accepts timestamps within ±5 minutes (300 seconds) of the current time. All comparisons use timing-safe equality to prevent timing attacks.
SSO Token Claims
The JWT launch token contains these claims:
| Claim | Description | Example |
|---|---|---|
sub | Player external ID | "player-123" |
tid | Tenant (operator) ID | "tenant-abc" |
cur | Currency code | "USD" |
jur | Jurisdiction code | "CW" |
loc | Locale | "en" |
pid | Internal player ID | "pl_abc123" |
gid | Target game ID (optional) | "slotty-slots" |
demo | Demo mode flag | false |
uname | Display username | "Player123" |
jti | Unique token ID | "tok_xyz789" |
Single-Use Enforcement
Each SSO token can only be used once. After exchange, the token's jti is stored in Redis:
Key: {tenantId}:sso:used:{jti}
TTL: 120 secondsAny attempt to reuse an exchanged token will return a SSO_TOKEN_ALREADY_USED error.
SSO Exchange Response
A successful token exchange returns:
interface SSOExchangeResponse {
accessToken: string; // JWT for API calls (15min TTL)
refreshToken: string; // Refresh token (7d TTL)
sessionId: string; // Unique session identifier
player: {
id: string; // Internal player ID
externalId: string; // Operator's player ID
username: string; // Display name
currency: string; // Player currency
jurisdiction: string; // Jurisdiction code
};
}Session Information
Active sessions expose the following data:
interface SessionInfo {
sessionId: string;
playerId: string;
tenantId: string;
jurisdiction: string;
activeGameId: string | null;
sessionDuration: number; // seconds elapsed
maxSessionMinutes: number; // jurisdiction limit
nextRealityCheckAt: string; // ISO 8601 timestamp
}REST API Example
Create SSO Token
// POST /api/v1/auth/sso/create-token
const response = await fetch('https://api.slottylabs.com/api/v1/auth/sso/create-token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer sk_live_abc123...',
'X-Slotty-Timestamp': timestamp.toString(),
'X-Slotty-Signature': signature,
},
body: JSON.stringify({
externalPlayerId: 'player-123',
currency: 'USD',
jurisdiction: 'CW',
locale: 'en',
username: 'Player123',
gameId: 'slotty-slots',
demoMode: false,
}),
});
const { data } = await response.json();
// data.launchToken — single-use JWT, 30s TTL