Client authentication

Browser clients cannot store long-lived API keys safely and cannot set Authorization headers on WebSocket connections. To support browser-based realtime transcription, Mistral provides short-lived realtime tokens (rt_*) that your server mints on behalf of the client.

How it works

How it works

  1. Your backend calls POST /v1/client/sessions using your API key to mint a short-lived token scoped to a specific model.
  2. Your backend passes the token to the browser, for example in a REST response.
  3. The browser opens the WebSocket connection using the token in the Sec-WebSocket-Protocol header.
Client authentication flow: the browser asks your server for a token, your server mints an rt_* token with the Mistral API, returns it to the browser, and the browser opens the realtime transcription WebSocket using Sec-WebSocket-Protocol.
Step 1: Mint a token (server-side)

Step 1: Mint a token (server-side)

Call POST /v1/client/sessions from your backend with your API key. Pass the model the client will use.

curl https://api.mistral.ai/v1/client/sessions \
  -X POST \
  -H "Authorization: Bearer $MISTRAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "purpose": "realtime",
    "model": "voxtral-mini-transcribe-realtime-2602"
  }'

201 response

{
  "object": "client.session",
  "purpose": "realtime",
  "expires_at": "2026-07-03T10:01:00Z",
  "client_secret": {
    "value": "rt_...",
    "expires_at": "2026-07-03T10:01:00Z"
  }
}

Return client_secret.value to the browser. Do not expose your API key.

Note

Tokens expire after approximately 60 seconds. Mint a fresh token close to when the client needs to connect, not on page load.

Step 2: Connect from the browser (client-side)

Step 2: Connect from the browser (client-side)

Open the WebSocket using the token in Sec-WebSocket-Protocol. Browsers cannot set Authorization headers on WebSocket connections, so this header is the only supported transport for rt_* tokens.

const token = await fetchTokenFromYourBackend(); // "rt_..."
const model = "voxtral-mini-transcribe-realtime-2602";

const ws = new WebSocket(
  `wss://api.mistral.ai/v1/audio/transcriptions/realtime?model=${model}`,
  ["realtime", token] // passed as Sec-WebSocket-Protocol
);
Token properties

Token properties

PropertyValue
Prefixrt_
Lifetime~60 seconds (configurable)
ScopeSingle model (specified at mint time)
ReusableYes, until expiry

A token minted for model A is rejected if used with model B.