Four ways to make your avatar speak. Pick the one that matches your use case — the rest of the API stays the same.
Set mode once in your config:
The default. Bidirectional voice over WebSocket. Your user speaks, the avatar listens, thinks, and responds — all in real time, with native acoustic echo cancellation so the avatar doesn't hear itself.
How it works: the SDK captures the user's microphone and streams it to the server. The server understands what was said, generates a reply, and sends back the spoken audio along with the timing data that drives lip-sync. Echo cancellation is built in, so the avatar doesn't hear its own voice during the call.
call mode asks for microphone permission when start() is called. Handle the MIC_PERMISSION_DENIED error for users who decline — see Permissions.
Best for: Mobile support agents, AI companions, interactive tutors.
Inside call mode, a second choice: who decides a turn is over.
Push-to-talk suits noisy or shared spaces, where an endpointer would keep triggering on background speech. It is forgiving at both ends: 200 ms of already-captured audio is released on press, and 250 ms of real audio is still sent after release, so nothing is clipped. A hold longer than two minutes is treated as a stuck control and the turn is closed.
Wire it with startTalking() / stopTalking() from
useAvatar, or let the built-in
controls render the hold-to-talk button.
The turnTaking.spacebar option exists on the shared config type but has no
meaning on mobile — there is no spacebar to bind.
call mode can also let the avatar see, if you opt in with
perception: { camera: true }. The camera stays closed until the avatar
actually needs to look at something. See
Camera perception for what is captured, and
Permissions for the native setup.
Send text programmatically — the avatar speaks it. No microphone, no voice input.
The server processes the text, generates audio, and returns it with alignment data for lip-sync.
Best for: Announcements, notifications, narration, scripted onboarding flows.
You already have audio (from another TTS provider or a pre-recorded clip). Send it to the avatar to lip-sync and play.
Accepted input types: ArrayBuffer, Float32Array, or Blob. The audio must be raw PCM (16 kHz, mono) — if you have a compressed file like MP3 or AAC, decode it first.
Best for: Custom TTS pipelines (ElevenLabs, Play.ai, etc.), pre-recorded content with dynamic delivery.
No server, no WebSocket. You provide pre-rendered audio chunks and alignment data — the SDK plays them locally.
Best for: Onboarding screens, product demos, cached responses, zero-latency playback experiences.
| Prop | Type | Default | Description |
|---|---|---|---|
WebSocket connectionOptional | call / tts / audio | No default | These three modes open a server connection. player runs entirely on-device. |
Microphone requiredOptional | call only | No default | Only call mode captures user audio. |
Server-side AIOptional | call only | No default | Only call mode uses the AI language model for responses. |
speakText()Optional | tts only | No default | Send a string for the avatar to speak. |
speakAudio()Optional | audio only | No default | Send raw PCM audio (16 kHz mono) for lip-sync playback. |
play()Optional | player only | No default | Play a pre-rendered AvatarSpeech job locally. |