Docs/Player Authentication
Features

Player Authentication

TurnKit now separates player auth into a policy plus one or more enabled methods. NO_AUTH is the default and fastest option, while AUTH_REQUIRED protects client endpoints with a player JWT.

Relay, leaderboards, and other client APIs all follow the same pattern: finish player auth first when required, then call the normal client endpoints with that player JWT. Relay itself still upgrades to a short-lived relayToken for the WebSocket step after queue join succeeds.

Quick Comparison

ModeBest forWhat you needPlayer verification
NO_AUTHQuick testing and prototypesNothingUse X-Player-Id
EMAIL_OTPSimple email login without building a backendSMTP settings (host, port, username, password, from address)Email + OTP -> player JWT
YOUR_BACKENDGames with existing player authenticationYour own backend + secret keySigned proof exchange -> player JWT
UGSUnity games already using Unity AuthenticationUnity Authentication id token + backend UGS verifier configUnity JWT exchange -> player JWT

NO_AUTH Policy

No authentication is required. Players only need your client key and use X-Player-Id on runtime requests.

For Relay specifically, that means the queue join call stays on the lightweight path: client key plus X-Player-Id, then use the returned relayToken on the WebSocket connection.

This is the fastest way to start testing, public demos, or games where you prefer zero login friction.

Note: Do not use NO_AUTH with auto-upgrade billing. Malicious users could create many fake players and consume your free 20 CCU limit.

EMAIL_OTP Method

TurnKit manages player login using email + OTP. Enable this method when you want TurnKit to send codes through your SMTP provider.

How to implement

  1. Set policy to AUTH_REQUIRED in the dashboard.
  2. Enable the EMAIL_OTP method.
  3. Configure your SMTP settings. A quick option is setting up Brevo as your email provider.
  4. Client calls /v1/client/auth/email-otp/request and /v1/client/auth/email-otp/verify.
  5. Use the returned player JWT in Authorization: Bearer <player-jwt> for normal client calls.
  6. That includes POST /v1/client/relay/queue before opening the relay WebSocket.

In Unity, the matching client-side calls are documented in the Unity Client API reference.

OTP endpoints expect Content-Type: application/json. Default backend limits are currently 5 requests per 10 minutes for /v1/client/auth/email-otp/request and 10 requests per 10 minutes for /v1/client/auth/email-otp/verify, typically scoped by game, email, and client IP.

YOUR_BACKEND Method

Your backend signs player identities.

How to implement

  1. Set policy to AUTH_REQUIRED in the dashboard.
  2. Enable the YOUR_BACKEND method.
  3. Store secret key only on your backend.
  4. Backend computes HMAC-SHA256 over playerId + "\n" + timestamp + "\n" + nonce and returns playerId, timestamp, nonce, and signature to the client.
  5. timestamp is Unix epoch seconds encoded as a string.
  6. nonce must be a random URL-safe string, not a time-based value. The server currently requires [A-Za-z0-9_-]{16,128}.
  7. Client calls POST /v1/client/auth/your-backend/exchange with that payload. TurnKit verifies signature, replay protection, and freshness before issuing a player JWT.
  8. Use that player JWT in Authorization: Bearer <player-jwt> for normal client calls.
  9. Queue Relay with that player JWT, then switch to the returned relayToken for the WebSocket itself.

NO_AUTH is the only policy that still sends X-Player-Id directly on client requests.

UGS Method

TurnKit can verify a Unity Authentication JWT through Unity JWKS and issue a normal TurnKit player JWT that works with leaderboards, queue, relay, and the rest of the runtime API.

How to implement

  1. Set policy to AUTH_REQUIRED in the dashboard.
  2. Enable the UGS method.
  3. Configure backend UGS verification with your Unity project ID and optional environment ID.
  4. Sign the player in with Unity Authentication and obtain the Unity id token on the client.
  5. Client calls POST /v1/client/auth/ugs/exchange with Authorization: Bearer <client-key> and JSON containing idToken plus optional serverProof.
  6. Use the returned TurnKit token exactly like any other player JWT in Authorization: Bearer <player-jwt> for normal client calls.
  7. Queue Relay with that player JWT, then open the WebSocket with the returned relayToken.

The backend verifies the Unity JWT signature through JWKS, checks issuer, project ID, optional environment ID, and time-based claims, then maps the Unity sub to the TurnKit player ID.

Methods remain saved even if you temporarily switch the policy back to NO_AUTH, and you can enable YOUR_BACKEND, EMAIL_OTP, and UGS in any combination that fits your game.

Player Authentication - TurnKit Docs