Skip to main content
Back-channel responses are short audio interjections — "uh-huh", "right", "I see" — that the server emits while the user is still speaking. They sit out-of-band from the main response stream and give the agent the cadence of an active listener without interrupting the user’s turn.

Enabling back-channel

Sending providerData.backchannel: {} (empty object) clears all overrides; the server falls back to its compiled-in defaults.

Handling back-channel audio

Use backchannel_id as the playback bucket key so chunks of one interjection don’t collide with the active assistant response item.

Client integration: preserve audio during user speech

A natural-feeling back-channel is audible to the user while they are still talking. The default audio-ducking behavior in many client integrations attenuates all output channels when VAD reports user activity — this also silences the back-channel, defeating its purpose. When you wire back-channel into your client, exempt the back-channel playback bucket (keyed by backchannel_id) from the duck-on-user-speech rule so interjections remain audible while the user holds the floor.

Event reference

Example response.backchannel.skipped payload:
See the WebSocket API reference for the full schemas.

Example: Spanish back-channel with rule decider

For a low-cost, deterministic back-channel — no small-LLM call per evaluation, just a random pick from a fixed Spanish phrase bank — use decider_kind: "rule" with a populated allowed_phrases and a per-tick fire probability tuned for natural cadence. The TTS voice and language come from your normal audio.output and providerData.tts.language settings, so the phrases get spoken in the Spanish accent you’ve already configured.
What this does:
  • No LLM in the hot path. Every evaluation tick is a coin flip against rule_fire_probability; if it fires, the server picks a random phrase from allowed_phrases. Latency is effectively just TTS synthesis.
  • rule_fire_probability: 0.3 keeps the cadence natural — at the default 800 ms eval_interval_ms, that’s roughly one fire every ~2.7 ticks once the gating thresholds pass. Tune up for more eager back-channels, down for sparser.
  • allowed_phrases replaces the compiled-in English bank with Spanish utterances. With the LLM decider you’d instead append a language directive to prompt_template; with the rule decider, the phrase bank is the only thing controlling what gets said, so list them explicitly.
  • providerData.tts.language: 'es-ES' anchors the TTS accent. Without it, TTS-2 may infer a different accent from the audio or text context.

Tuning tips

  • Start with the server defaults (just { enabled: true }). Adjust min_speech_ms and min_gap_ms first if back-channels feel too eager or too sparse.
  • Pair with turn_detection.eagerness: 'low' so the main response model gives the user space to continue — back-channel fills the perceived silence.
  • If back-channels feel louder than the main assistant response, lower volume_gain (default 0.6); if they feel inaudible, raise it toward 1.0. Setting volume_gain: 0.0 mutes back-channels entirely without disabling synthesis — useful for A/B tests of the decider in isolation.
  • For multilingual sessions, append a language directive to prompt_template. The compiled-in default lists English example phrases; without a language hint the small model echoes them in English regardless of the conversation language.
  • For load tests, switch decider_kind to rule with rule_fire_probability: 0.3 to remove the LLM call from the hot path while still exercising the audio pipeline.