Why You Need This
If you’re building a web app, you have a problem:connect() needs an API key, but anything you ship to the browser is public.
Bundle it in your JS, and anyone can open DevTools and grab it.
Client credentials fix this by splitting the connection into two steps:
- Your server uses the API key to mint a short-lived token.
- Your client connects with that token. No API key required.
Quick Start
Step 1: Mint credentials on your server
Step 2: Connect from the browser
Cross-SDK Serialization
Both SDKs produce the same JSON format. You can mint credentials on a Python backend and consume them in JavaScript on the frontend (or the other way around).The
session_id in the dict is informational.
On deserialization, it gets re-derived from the JWT to prevent tampering.Session Lifecycle and Token Expiration
When you callcreateClientCredentials(), Odyssey provisions a session and returns a session_token (a JWT) that’s valid for expires_in seconds (currently 600s).
Your client needs to call connectWithCredentials() before that window closes.
Once the client is connected and streaming, the token expiration doesn’t interrupt an active stream.
The connection stays alive as long as the WebRTC session is open.
Token expiration only matters for the initial connection.
Here’s what happens when a session ends:
- Client disconnects cleanly: The session is dropped immediately and your concurrency slot is freed.
- Client loses connection (crash, network drop): The session is dropped once the token expires.
- Client never connects: Unused sessions are automatically cleaned up after 15 minutes of idle time.
If a client tries to connect after the token has expired, the connection will be rejected.
The unused session is cleaned up automatically, but your concurrency slot may stay occupied for a few minutes until that happens.
createClientCredentials() call provisions a new session.
You can’t reuse a credential for a different session.
There’s no token refresh. If a token expires before the client connects, mint a new one from your server.
Error Handling
Client Credentials vs Broadcast
Both patterns let end users watch Odyssey streams without an API key. The difference is whether each user gets their own world or everyone shares one.
Use client credentials when each user needs their own session to interact with.
Use Broadcast when you want many people watching the same stream.
The Broadcast guide covers
spectator_token and connectToStream().
Full Example
A minimal Express server with a vanilla HTML frontend:SDK Reference
JavaScript SDK
createClientCredentials() and connectWithCredentials() reference.Python SDK
create_client_credentials() and connect_with_credentials() reference.