Realtime TTS-2 is live. Built for realtime conversation that feels human. Learn more

Build with Realtime TTS

OpenAI Compatibility

Call Realtime TTS from the OpenAI SDKs by pointing them at Inworld and choosing an Inworld model and voice

Realtime TTS serves OpenAI's text-to-speech endpoint, POST /v1/audio/speech, in OpenAI's own request and response format. If your app already uses OpenAI's text-to-speech, point the SDK at Inworld with your Inworld API key, then set model and voice to Inworld IDs. The SDK calls themselves stay the same.

Endpoint

https://api.inworld.ai/v1

Change your SDK base URL from https://api.openai.com/v1 to https://api.inworld.ai/v1. In the US region, the same base URL also serves the Inworld Router, so one client configuration covers both LLM and TTS.

For regional deployments, use https://api.eu.inworld.ai/v1 or https://api.in.inworld.ai/v1 with an API key created in that region's Portal. Regional endpoints are provisioned per organization on Enterprise plans, and keys from the US region do not authenticate against them. The Inworld Router is not available in regional deployments.

Quickstart

Use your Inworld API key as the SDK's API key. The OpenAI SDKs send it as Authorization: Bearer <key>; the endpoint also accepts Authorization: Basic <key>. Keep the key on your server.

Python
from openai import OpenAI

client = OpenAI(
    base_url="https://api.inworld.ai/v1",
    api_key="YOUR_INWORLD_API_KEY",
)

with client.audio.speech.with_streaming_response.create(
    model="inworld-tts-2",
    voice="Dennis",
    input="Welcome back! Your order shipped this morning and should arrive by Thursday.",
) as response:
    response.stream_to_file("speech.mp3")

Request parameters

The API reference has the full request and response schema.

ParameterRequiredDescription
modelYesAn Inworld model ID, such as inworld-tts-2 or inworld-tts-2-flash. See Models. OpenAI model names such as tts-1 return 400.
inputYesThe text to synthesize, up to 4,000 characters. Inline markup works as it does in the Streaming API, including steering tags, pause controls, and custom pronunciation.
voiceYesAn Inworld voice ID, such as Dennis, or the ID of one of your custom voices. Voice IDs are case-sensitive. OpenAI voice names such as alloy return 404. List available voices with List voices.
response_formatNomp3 (default), opus, flac, wav, or pcm. aac is not supported.
speedNoSpeaking rate from 0.5 to 1.5. Default 1.0. Values outside this range return 400.
instructionsNoA natural-language steering instruction for the whole request. Supported on inworld-tts-2 only; other models ignore it.
stream_formatNoaudio (default) returns raw audio bytes. sse returns server-sent events.

The language is detected from the input text.

Audio formats

All formats are mono.

response_formatEncodingSample rate
mp3MP3 at 128 kbps48 kHz
opusOpus in an Ogg container48 kHz
flac16-bit FLAC48 kHz
wav16-bit PCM in a WAV container48 kHz
pcmRaw 16-bit signed little-endian samples, no header24 kHz

Audio streams as it is generated, so a wav response starts before its length is known. Its RIFF and data chunk size fields are set to 0xFFFFFFFF, a standard marker for streamed WAV. Most players and decoders read it; if a strict parser rejects the file, rewrite the size fields from the file length.

Streaming

With the default stream_format, audio bytes arrive as they are generated, so you can play them before synthesis finishes. Read the response incrementally instead of waiting for the whole body — for example with with_streaming_response in Python, or by reading response.body in Node.

With stream_format set to sse, the response is a stream of server-sent events. Each speech.audio.delta event carries a base64-encoded audio chunk in audio, and the stream ends with a speech.audio.done event:

data: {"type":"speech.audio.delta","audio":"SUQzBAAAAAAAI1RTU0UAAAAPAAAD..."}

data: {"type":"speech.audio.done"}

Errors

Errors use OpenAI's error format, so the OpenAI SDKs raise their usual exception types:

json
{
  "error": {
    "message": "speed must be between 0.5 and 1.5",
    "type": "invalid_request_error",
    "param": "speed",
    "code": null
  }
}
StatustypeCause
400invalid_request_errorA missing or invalid parameter. param names the parameter when the request failed validation.
401authentication_errorA missing API key, or an invalid key sent as Bearer.
402insufficient_quotaNo credits remain on the account.
403permission_errorAn invalid key sent as Basic, or a key without access to the request.
404invalid_request_errorThe voice was not found.
429rate_limit_errorA rate limit or concurrency limit was exceeded.
5xxapi_errorA server error. Retry with backoff.

Billing and limits

Requests are billed per character and share rate limits and concurrency limits with the Streaming API.

Features that need the native API

The OpenAI format has no fields for some Realtime TTS features. Use the native TTS API for:

  • Timestamps for captions and lipsync
  • Sample rate, bit rate, and other audio encoding settings
  • Synthesis context from earlier conversation turns
  • Explicit language selection, delivery mode, temperature, and text normalization settings
  • Async and batch jobs