Live API
Client secrets
A client secret lets a browser open one Live session without your API key. Create it on your server, then pass its value to the browser.
Create a client secret
- POST
https://api.dotwave.ai/v1/live/client_secretsAuthenticate with your API key.
curl https://api.dotwave.ai/v1/live/client_secrets \
-H "Authorization: Bearer $DOTWAVE_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"expires_after": {"anchor": "created_at", "seconds": 60},
"session": {
"type": "live",
"model": "nemotron-voicechat",
"audio": {
"input": {"format": {"type": "audio/pcm", "rate": 24000}},
"output": {
"format": {"type": "audio/pcm", "rate": 24000},
"encoding": "base64"
}
}
}
}'expires_after.seconds- How long the secret stays valid: 60 by default, 600 at most.
expires_after.anchoriscreated_at. session.typelive.session.model- The model the session opens, such as
nemotron-voicechat. session.audio- The audio formats, 24 kHz PCM16 in and out, and the output encoding,
base64orbinary. metadata- Your own string keys, kept with the session’s record: up to 16, and 512 bytes in all.
The response
{"value": "…", "expires_at": 1790000000,
"session": {"id": "sess_…", "type": "live", "model": "nemotron-voicechat",
"live_url": "wss://api.dotwave.ai/v1/live/sessions"}}value- The secret. Give only this to the browser.
expires_at- When the secret expires, in Unix seconds.
session.id- The session the secret opens. Look it up later with
GET /v1/sessions/{session_id}. session.live_url- The socket to open.
Connect from a browser
Browsers cannot set headers on a WebSocket, so pass the secret as the token query parameter. The browser still sends session.start first. A client that can set headers sends Authorization: Bearer <value> instead.
// `secret` is the `value` and `liveUrl` the `session.live_url`
// your server received.
const ws = new WebSocket(`${liveUrl}?token=${encodeURIComponent(secret)}`);
ws.onopen = () => {
// session.start must be the first event, or the socket refuses it.
ws.send(JSON.stringify({
type: 'session.start',
session: { model: 'nemotron-voicechat' },
}));
};
ws.onmessage = ({ data }) => {
const event = JSON.parse(data);
if (event.type === 'session.output_audio.delta') play(event.delta);
};A secret opens one session. An unused secret counts toward your concurrency limit until it expires, so create it just before the browser connects.
Errors
Refusals use the error envelope. A field the model does not support, such as custom instructions or tools, is refused with 400 invalid_parameter. At zero credit, the call returns 403 insufficient_credit. Past your project’s limits it returns 429, and when the model is at capacity 503, both with Retry-After.