Skip to main content

Error handling

Use isRetryable() to decide whether to retry or show a fatal error, and treat billing.* codes as a prompt to top up. The full recipe is in Error handling.

Timing

  • Use audioContext.currentTime for audio timing (not Date.now())
  • Use performance.now() for UI timestamps
  • Schedule audio with 10-50ms lead time to avoid glitches

Interruptions

If you play audio yourself, clear your queue when the user interrupts, and only then: listening while the agent talks is a tentative barge-in (Handling Interruptions). The SDK’s own audio managers already do this.

Latency

  • Stream and play chunks as they arrive; do not wait for the full response.
  • Reuse connections where you can: each new WebSocket costs a handshake.
  • Leave speculative replies on for voice agents unless token cost matters more than about 255 ms per reply.
  • steps cannot be tuned: the current model always runs 4.
Measured figures and more detail are in Latency.

Reconnection

After a dropped connection the SDK reconnects by itself with exponential backoff (2s, 4s, 8s, capped at 10s, max 5 attempts). Each reconnection is a new server session. A session the server ended on purpose is not reconnected: the ended event fires.

Audio

  • Pre-warm AudioContext inside a user gesture (button click), not when the first chunk arrives
  • Guard against odd-length PCM buffers: trim the last byte if length % 2 !== 0
  • Limit transcript history to avoid memory leaks

Security

  • Keep API keys on your server, in environment variables. Never put one in browser or mobile code.
  • Give browsers short-lived tickets with the SDK’s auth option (Secure browser setup).
  • Put your ticket route behind your own login.