Realtime TTS-2 is live. Built for realtime conversation that feels human. Learn more

Authentication

Session tokens

Deprecated multi-use JWTs — use one-time tokens wherever possible.

Session tokens are deprecated. Use one-time tokens wherever possible — today that is everything except Realtime sessions, which still require a session token. Multi-use minting is planned as an extension of the tokens endpoint.

A session token is a JWT minted from your API key. Unlike a one-time token, it is multi-use: the client can open connections and make requests with it repeatedly until it expires, a few hours after minting. Use it where a client holds a longer session — a browser tab running the TTS SDK, or a Realtime voice session — and mint it on your backend, so the API key itself never reaches the client.

A session token carries the full permissions of the API key that minted it — every API the key reaches, for the token's whole lifetime, any number of times. That makes key permission management important: mint from the narrowest key that fits, such as a Realtime-only key for Realtime sessions, with write toggles off unless needed. Wherever one connection per credential fits, prefer a one-time token instead.

Mint a session token

POST https://api.inworld.ai/v1/sessionTokens/token:generate

Requests to this endpoint are authenticated with a signature computed from your API key — not by sending the key in the header directly — so the key itself never travels on the wire. Our SDKs and the Node.js JWT sample app implement the signing; run one of them on your backend rather than hand-rolling it.

The request body:

json
{
  "api_key": "<your key id>",
  "resources": ["workspaces/my-workspace"]
}
  • api_key — the key ID the request is signed with.
  • resources (optional) — a single workspaces/{workspace} name to scope the token to. Omitted, the token is scoped to the key's own workspace. Another workspace is allowed when the key's workspace collection contains it, or when it is public.

The response:

json
{
  "token": "eyJhbGciOiJSUzI1NiIs...",
  "type": "Bearer",
  "expirationTime": "2026-09-01T16:00:00Z",
  "sessionId": "my-workspace:1f0d8e9a-..."
}

Use it

Send the token as a Bearer credential from the client:

Authorization: Bearer <token>

It works across Inworld APIs, including WebSocket and Realtime connections. The TTS SDK refreshes tokens for you — pass a fetcher and it re-mints shortly before expiry:

javascript
const tts = InworldTTS({
  token: await fetchToken(),        // your backend endpoint that mints the token
  onTokenExpiring: fetchToken,      // called automatically before expiry
});

Lifetime and revocation

  • Tokens expire a few hours after minting — always read expirationTime rather than assuming a duration, and refresh before it passes.
  • A session token is valid until it expires: there is no per-token revocation. Deleting the parent API key invalidates every token minted from it immediately.

For clients that open exactly one connection per credential, prefer one-time tokens — shorter-lived, and dead after first use. See Security best practices for choosing between the two.