Realtime STT-1 Speech to text
Streams the transcript with each speaker's emotion, age and accent. Speaker diarization is new on the STT API.












One connection listens, reasons and talks back.











Ask your agent to add Inworld.
One connection carries the whole conversation.
Connect one WebSocket or WebRTC, pick a voice and a model, and add your tools.
They speak naturally. The session hears when they're done, and how they said it.
It reasons, calls your tools and answers out loud in a few hundred milliseconds, under a second with a tool call.
Talk over it and it stops, keeping only what the user heard.
Hey, um, can you move my dinner at Luca tonight from seven to eight thirty?
Sure, your window table at Luca is all set for eight thirty.
The user started talking at 7.91 s, so playback stopped and the reply was truncated to what they heard.Oh, wait. Sorry, there will be five of us.
No problem, you're all set for a corner booth.
The agent called your app's move_reservation tool, then spoke the result.speech_startedcommittedmove_reservation {"new_time": "20: 30", "restaurant": "Luca"}{"table": "window table"}truncatecommittedmove_reservation {"party_size": 5, "restaurant": "Luca"}{"table": "corner booth"}Your users talk, your app answers out loud. One connection listens, reasons, calls your tools and talks back.

Sends PCM16 at 24 kHz, or G.711 at 8 kHz from a phone call.
WebSocket or WebRTCThe final transcript carries the speaker's emotion, age, accent and vocal style.
64 ms last word to transcriptYou pick the model, and you can change it mid-session.
159 ms to first tokenOn Realtime TTS-2, it follows a direction the LLM writes in plain words at the start of each reply.
58 ms to first audio on Realtime TTS-2 FlashPlayback stops the moment the user talks over it.
History keeps what they heardSemantic VAD reads the transcript to decide when the user has finished, and you set how eager it is.
When the user talks over a reply, the audio stops and the history keeps only what they heard.
Declare functions at the start or add them mid-session, and the agent speaks the result in the same turn.
A session.update changes the LLM, the voice or the tools, and the next reply uses the new setting.
Events and session config match the OpenAI Realtime API, so moving over means a new endpoint and key.
Connect over WebSocket or WebRTC, and take phone audio as G.711 at 8 kHz from Twilio.
Streams the transcript with each speaker's emotion, age and accent. Speaker diarization is new on the STT API.
Runs the open models that write each reply and call your tools. Gemma 4, GLM 5.3, DeepSeek V4 and Qwen3.8 all ran in live sessions.
Speaks with direction in about 500 languages and dialects. Speech Reasoning is in beta in the playground, and language tags switch language mid-sentence.
Each part of the session bills at its own rate, with no speech-to-speech fee on top. Paid plans cut the TTS rate in half.
// npm install ws
// INWORLD_API_KEY=<your key> node client.mjs
import WebSocket from 'ws';
import fs from 'node:fs';
const ws = new WebSocket(
`wss://api.inworld.ai/api/v1/realtime/session?key=demo-${Date.now()}&protocol=realtime`,
{ headers: { Authorization: `Basic ${process.env.INWORLD_API_KEY}` } }
);
const audio = [];
ws.on('message', (data) => {
const event = JSON.parse(data);
if (event.type === 'session.created') {
ws.send(JSON.stringify({
type: 'session.update',
session: {
type: 'realtime',
model: 'inworld/models/gemma-4-31b-it',
instructions: 'You are a friendly voice assistant. Reply in one short spoken sentence.',
output_modalities: ['audio'],
audio: {
input: { transcription: { model: 'inworld/inworld-stt-1' } },
output: { model: 'inworld-tts-2', voice: 'Sarah' },
},
},
}));
ws.send(JSON.stringify({
type: 'conversation.item.create',
item: {
type: 'message',
role: 'user',
content: [{ type: 'input_text', text: 'Suggest a name for a small orange cat.' }],
},
}));
ws.send(JSON.stringify({ type: 'response.create' }));
}
if (event.type === 'response.output_audio.delta') audio.push(Buffer.from(event.delta, 'base64'));
if (event.type === 'response.output_audio_transcript.done') console.log('Agent:', event.transcript);
if (event.type === 'error') console.error(event.error);
if (event.type === 'response.done') {
const pcm = Buffer.concat(audio); // PCM16, 24 kHz, mono
fs.writeFileSync('reply.wav', Buffer.concat([wavHeader(pcm.length), pcm]));
console.log(`Saved reply.wav (${(pcm.length / 48000).toFixed(1)} s)`);
ws.close();
}
});
function wavHeader(bytes, rate = 24000) {
const h = Buffer.alloc(44);
h.write('RIFF', 0); h.writeUInt32LE(36 + bytes, 4); h.write('WAVE', 8);
h.write('fmt ', 12); h.writeUInt32LE(16, 16); h.writeUInt16LE(1, 20); h.writeUInt16LE(1, 22);
h.writeUInt32LE(rate, 24); h.writeUInt32LE(rate * 2, 28); h.writeUInt16LE(2, 32); h.writeUInt16LE(16, 34);
h.write('data', 36); h.writeUInt32LE(bytes, 40);
return h;
}Set INWORLD_API_KEY to your key from platform.inworld.ai.
Speech to speech built for people runs on Inworld. Who are you building for?
Inworld AI speech to speech takes the user's speech and answers in speech over one WebSocket or WebRTC connection. It listens to the user, reasons with the LLM you choose and calls your tools, and talks back in any Realtime TTS-2 voice, including voices you clone or design, with turn detection and interruptions handled inside the session. It follows the OpenAI Realtime protocol. Phone calls work through Twilio Media Streams, in G.711 μ-law or A-law at 8 kHz.
First audio from Inworld AI speech to speech arrived as little as 204 ms after the turn closed, the fastest of 37 turns, with a median of 462 ms over 17 measured turns. The wait for the turn to close depends on the turn-detection setting you choose; with semantic VAD on high eagerness it was a median 954 ms after the user's last word.
Semantic VAD in Inworld AI speech to speech decides from the STT stream when the user has finished, at low, medium or high eagerness. Server VAD uses silence instead, and you can override the end-of-turn silences. With interrupt_response on, the server stops the reply as soon as the user starts talking, and conversation.item.truncate keeps only what they heard.
You set the LLM for Inworld AI speech to speech in session.model, such as inworld/models/gemma-4-31b-it, and can change it mid-session with session.update. The next reply uses the new model. Hosted open models including Gemma 4, GLM 5.3 Flash and DeepSeek V4 Flash all work in live sessions. Set the model on every session, since an unset model falls back to a default.
Yes, Inworld AI speech to speech supports function calling, so a voice agent can call your tools in the middle of a conversation. Declare tools in session.update, at the start or later in the session. Calls arrive as response.function_call_arguments.done; return a function_call_output item and the session starts the spoken follow-up itself. Set providerData.auto_tool_response to false for OpenAI behaviour.
Yes, Inworld AI speech to speech uses the same event types, session config and event shapes as the OpenAI Realtime API, so a client moves over with few changes. Change the endpoint to wss://api.inworld.ai/api/v1/realtime/session with a session ID and protocol=realtime, use your Inworld key, and add providerData only if you want Inworld extensions such as voice profiles, backchannels or memory.
There is no separate fee for Inworld AI speech to speech, so you pay for each part at your plan's rates. At about 1,000 characters a minute of speech, Realtime TTS-2 is 2.5¢ a minute on demand and Realtime TTS-2 Flash 1.5¢, Realtime STT-1 is 0.25¢ a minute, and LLM tokens are billed at the model's rate. Paid plans lower the rates, and on the Growth plan Realtime TTS-2 Flash falls to $7 per million characters, about 0.7¢ a minute.
Ultravox is now part of Inworld AI, acquired to advance realtime voice AI, including speech to speech. Ultravox brings experience in speech understanding, reasoning and task completion, and in managing turn-taking and interruptions. Speech to speech today is one connection that listens, reasons and talks, with the LLM you choose. Built-in Inworld voices on Ultravox now run on Realtime TTS-2.