Error Codes
When an error occurs, the server sends a JSON message with acode and message field before closing the WebSocket.
| Code | Cause | Resolution |
|---|---|---|
AUTH_TIMEOUT | Token not sent within 10 seconds of connecting | Send the token immediately after the WebSocket opens |
INVALID_AUTH | First message is missing the token field | Ensure the first message is { "token": "..." } |
AUTH_FAILED | Token is invalid or expired | Request a fresh token and reconnect |
SESSION_SETUP_FAILED | Server couldn’t initialize the voice session | Retry after a short delay |
WebSocket Close Codes
| Code | Meaning |
|---|---|
| 4001 | Authentication timeout — token not sent in time |
| 4002 | Token required — first message was not valid JSON with a token |
| 4003 | Authentication failed — invalid or expired token |
| 4500 | Session setup failed — server-side issue |
| 1000 | Normal close — agent disconnected or session ended |
Common Issues
Token Expired
Session tokens are valid for 5 minutes. If you seeAUTH_FAILED, your token has likely expired. Always request a fresh token immediately before connecting.
Audio Format Mismatch
The server expects exactly PCM s16le, 16kHz, mono. If the AI agent can’t understand you, verify your audio encoding matches this spec. Common mistakes:- Sending Float32 samples instead of Int16
- Wrong sample rate (e.g., 44.1kHz or 48kHz without downsampling)
- Stereo audio instead of mono
Microphone Not Working (Web)
Browsers require a user gesture (click/tap) before granting mic access. Also check:- The page is served over HTTPS (or localhost)
AudioContextis resumed after creation — browsers auto-suspend it- The
ScriptProcessoroutput is connected toctx.destination(required to fire)
Microphone Not Working (Flutter)
Ensure runtime permissions are granted before starting the recorder:- Android:
RECORD_AUDIOpermission in manifest + runtime request - iOS:
NSMicrophoneUsageDescriptionin Info.plist - Check
AudioRecorder.hasPermission()before callingstartStream()
WebSocket Connection Refused
Verify the WebSocket URL uses the correct protocol (wss:// for production, ws:// for local development). Use the heartbeat endpoint to confirm the API is reachable.