PlayableLabs Docs
Developers

Authentication

JWT session flow, API token authentication, token scopes, and code examples for PlayableLabs API

Authentication Methods

PlayableLabs supports two authentication methods:

  1. JWT sessions -- For browser-based access via the web app
  2. API tokens -- For server-to-server and automation workflows

Both methods use the Authorization: Bearer <token> header.

JWT Session Authentication

The web application uses NextAuth v5 for session management. This flow is handled automatically when you sign in through the browser.

How It Works

  1. User signs in via email/password or Google OAuth
  2. NextAuth issues a JWT session token (7-day lifetime)
  3. The token is stored in an HTTP-only cookie
  4. All subsequent requests include the token automatically
  5. Tokens are auto-refreshed before expiry

JWT sessions are intended for browser use only. For programmatic access, use API tokens.

API Token Authentication

API tokens are the recommended method for scripts, CI/CD pipelines, and external integrations.

Creating a Token

Create tokens from Developers > Tokens. Each token is scoped to one organization and has specific permission scopes.

Using a Token

Include the token in the Authorization header:

curl -X GET \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  https://api.playablelabs.studio/api/games

TypeScript Example

const API_BASE = 'https://api.playablelabs.studio/api'

async function listGames(token: string): Promise<unknown> {
  const response = await fetch(`${API_BASE}/games`, {
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
  })

  if (!response.ok) {
    throw new Error(`API error: ${response.status}`)
  }

  return response.json()
}

const games = await listGames('YOUR_TOKEN')

cURL Examples

List games:

curl -H "Authorization: Bearer YOUR_TOKEN" \
  https://api.playablelabs.studio/api/games

Create a game:

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "My Game", "organizationId": "YOUR_ORG_ID"}' \
  https://api.playablelabs.studio/api/games

Trigger an export:

curl -X POST \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"variantId": "VARIANT_ID", "network": "unity"}' \
  https://api.playablelabs.studio/api/export

Token Scopes

Each API token has a set of permission scopes that control what it can access. See the API Tokens page for the full scope reference.

A request that exceeds the token's scopes returns:

{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Insufficient permissions. Required: games:write"
}

Error Responses

StatusMeaningCommon Cause
401UnauthorizedMissing, expired, or invalid token
403ForbiddenToken lacks required permission scope

Handling 401 Errors

async function safeRequest(url: string, token: string) {
  const res = await fetch(url, {
    headers: { 'Authorization': `Bearer ${token}` },
  })

  if (res.status === 401) {
    // Token expired or invalid -- re-authenticate
    console.error('Authentication failed. Check your token.')
    return null
  }

  return res.json()
}

Security Recommendations

  • Store tokens in environment variables, never in source code
  • Use HTTPS for all API requests (enforced by default)
  • Rotate tokens every 90 days
  • Revoke unused tokens promptly
  • Grant the minimum scopes needed for each integration

Next Steps

On this page