Skip to main content
The Inworld Realtime API is wire-compatible with the OpenAI Realtime spec — clients written against OpenAI’s session, audio, and response events work against Inworld unchanged. On top of that baseline, Inworld layers production-grade extensions that improve quality, latency, and conversational naturalness:
  • STT tuning — voice profile signals, language hints, explicit end-of-turn and VAD overrides
  • TTS segmentation, steering, and alignment — pick how the LLM token stream is chunked into TTS calls, the synthesis language, the TTS-2 delivery preset, (for TTS-2) a shared multi-turn context, and opt into word/character-level timestamp alignment for lip-sync or captions
  • Automatic conversation memory — periodic summarization and fact extraction that keep long sessions inside the context window
  • Back-channel — short interjections ("uh-huh", "I see") emitted while the user is still speaking, so the agent feels like an active listener
  • Responsiveness fillers — short filler audio ("let me think") spoken in the gap after a user turn if the main LLM is slow to produce its first delta
Everything Inworld adds beyond the OpenAI spec is exposed through a single field on the session object: providerData. Send it inside any session.update and the server merges it with current state. Most fields hot-swap mid-session and take effect on the next audio chunk or turn; the locked-at-session-open exceptions are called out in the hot-swap reference at the bottom of this page. This page is the field-by-field reference for the full providerData surface. For task-driven walkthroughs (language switching, conversation management, etc.) and for the event-handling client code that pairs with back-channel and responsiveness, see the linked guides under each branch.

Branch overview

providerData is a flat object with five branches. Each branch is independent — send only the ones you want to configure.
Partial updates are supported on every branch — omit a field to keep its current value. providerData also accepts a top-level behavior flag, auto_tool_response, plus the user_id and metadata fields. These aren’t configuration branches. See Tool continuation and Session metadata below.

Tool continuation

providerData.auto_tool_response controls who starts the next response after the client adds a function_call_output item. Setting it to false is useful if you are migrating from OpenAI, or you want consecutive tool calls followed by only one response. We recommend keeping this value at its default, since it ensures your tool calls are responded to as soon as possible. Set it to false only when necessary (e.g., when a third-party integration requires compatibility).
The field is hot-swappable. Omitting it from a later partial update preserves its current value.

STT (providerData.stt)

Inworld extensions to the OpenAI-standard STT config. Every field here is hot-swappable; the STT stream is restarted automatically so the next chunk of audio uses the new value.
For the eagerness preset that these fields override, see semantic_vad.

Voice profile payload

When providerData.stt.voice_profile is true, every conversation.item.input_audio_transcription.delta and conversation.item.input_audio_transcription.completed event carries a providerData.voiceProfile object alongside the transcript text:
Each top-level key is an array of { label, confidence } objects sorted by descending confidence. Keys are omitted when the STT backend does not produce labels for that category, so always null-check before reading. Confidence values are in [0.0, 1.0]. Voice profile is computed by the realtime service regardless of the STT backend, so voice_profile: true works across all supported STT models.

TTS (providerData.tts)

Controls how the LLM text stream is segmented and forwarded to the TTS backend, the language and delivery preset used for synthesis, (for TTS-2) whether a shared upstream context is preserved across turns, and opt-in timestamp alignment for lip-sync or captions. Available on inworld-tts-1.5-mini and inworld-tts-2.

Conversational TTS

Setting providerData.tts.conversational = true opts TTS-2 into a multi-turn shared context: the upstream TurnContext sees every user and assistant turn for the lifetime of the WebSocket. This lets the model condition its delivery on the audio history of the conversation. The trade-off is a longer-lived state on the TTS backend and slightly higher per-turn cost. In conversational mode, segmenter_strategy is internally locked to full_turn semantics. Per-sentence and per-segment-context strategies are coerced (with a server-side WARN) because they would either fragment the upstream history or open a fresh context per segment, both of which defeat the multi-turn TurnContext.
With conversational: true, TTS conditions each response on the audio of previous turns — higher per-turn cost in exchange for potentially more natural output. Off by default.

Segmenter strategies

TTS timestamps and alignment

Setting timestamp_type opts into timing data on response.output_audio.delta events. This is useful for lip-sync animation (viseme blending), word-level highlighting, or karaoke-style captions.

Choosing sync vs async

Output shape — response.output_audio.delta

When timestamps are enabled, the response.output_audio.delta event carries an optional timestamp_info field. Exactly one of word_alignment or character_alignment is populated, matching the requested timestamp_type.
word_alignment (when timestamp_type = "WORD"): Each entry in phonetic_details: character_alignment (when timestamp_type = "CHARACTER"):
For the full viseme symbol table and per-language timestamp support, see TTS timestamps.

WebRTC

Over WebRTC, audio travels on the RTP media track (not as base64). Alignment data is delivered on the data channel in the same response.output_audio.delta event shape, but the delta field is always an empty string (the audio is already on the media track).

Memory (providerData.memory)

Automatic conversation memory and summarization. When enabled, the server periodically asks the LLM to extract durable facts and a rolling summary, prepends them to the system prompt, and trims the transcript so context stays bounded.
After each generation cycle the server populates providerData.memory.state (read-only) and emits a session.updated event so clients can observe the rolling summary, fact list, and bookkeeping counters.

Back-channel (providerData.backchannel)

Short audio interjections — "uh-huh", "right", "I see" — emitted while the user is still speaking. Opt-in per session and gated by server prerequisites; contact your account team to confirm prerequisites for your deployment. For event handling (the response.backchannel.audio.delta / .done / .skipped events), client integration tips, and tuning guidance, see the dedicated Back-channel guide.
Sending providerData.backchannel: {} (empty object) clears all overrides; the server falls back to its compiled-in defaults.

Responsiveness (providerData.responsiveness)

Short filler audio ("let me think", "one moment") spoken after the user’s turn ends if the main LLM is slow to produce its first delta. Opt-in per session and gated by two server prerequisites (a small filler model and an Unleash flag); contact your account team to confirm both are in place. For how the filler races the main LLM, TTS pipeline details, and tuning guidance, see the dedicated Responsiveness guide.

Text generation config (text_generation_config)

Fine-grained LLM generation parameters sent as a top-level field on the session object (alongside model, temperature, providerData, etc.). The same object is also accepted under providerData.text_generation_config for compatibility — both paths are merged into the same state.

Reasoning

Controls chain-of-thought reasoning on models that support it. The server forwards this as extra_body.reasoning to the LLM Router.
Parameter support varies by model. Some models do not support reasoning at all, while others support only a subset of effort levels (e.g. gemini-3.1-pro does not support MINIMAL). If the upstream model rejects the requested effort, the LLM Router returns a 400 error.
When reasoning is omitted entirely, the server uses the model’s default reasoning behaviour. For reasoning-capable models this default may not be NONE — meaning reasoning tokens (and their latency) are added implicitly. If you need minimal latency on a reasoning-capable model, explicitly set effort: "NONE" to disable reasoning. Reasoning token usage is reported in response.done under usage.output_token_details.reasoning_tokens.

Other fields

All fields are optional and hot-swappable.

Prompt caching (providerData.caching)

Opt a session into explicit prompt caching for the stable, every-turn-resent blocks — the system instructions and the tool definitions. When enabled, the server attaches an ephemeral cache_control breakpoint to those blocks so providers that support explicit caching (Anthropic, Google) can serve them from cache, cutting input-token cost on every turn after the first. Providers with implicit caching (OpenAI, Gemini 2.5, DeepSeek) cache automatically and ignore the breakpoint, so leaving this off does not disable their caching.
Explicit caching only pays off for large blocks — providers apply a minimum cacheable size (around 1024 tokens). Below that, Anthropic silently skips the cache, while Google may reject the request. Enable caching only when the instructions and/or tool definitions are substantial. For the cache_control protocol, TTL prolongation, and the full list of supported providers, see Prompt caching.
Cache usage is reported on response.done under usage.input_token_details: cached_tokens (tokens served from a cache hit) and cache_write_tokens (tokens written when establishing a new cache entry). All fields are hot-swappable.

Session metadata

Two optional fields sit alongside the five branches at the top of providerData. They don’t configure STT, TTS, or memory — they tag the session so it can be traced, correlated, and routed downstream.
Both fields are optional and hot-swappable.

Hot-swap reference

Most providerData fields take effect on the next audio chunk or turn after the session.update is acknowledged. The exceptions — locked once at session open and ignored afterwards — are:
  • providerData.tts.conversational
  • providerData.tts.user_turn_mode
If you need to change either of these, open a new WebSocket session.

See also