@inworld/tts Node.js SDK wraps the Inworld TTS REST API with a clean, typed interface. It handles chunking for long text, retries with exponential backoff, and connection management automatically — reducing typical integrations from 30+ lines of raw HTTP to just a few lines of code.
Quick Start
Speech Synthesis
generate(options)
Synthesize speech and return the complete audio as a Uint8Array. Text longer than 2,000 characters is automatically chunked and sent in parallel.
Returns:
Uint8Array — raw audio bytes in the requested encoding.
stream(options)
Stream audio chunks over HTTP as they are generated. Lower time-to-first-audio than generate(). Text must be 2,000 characters or fewer.
generate(), except text must be ≤2,000 characters and the default model is "inworld-tts-1.5-mini".
Yields: Uint8Array — audio chunks as they arrive.
generateWithTimestamps(options)
Same as generate() but also returns word- or character-level timing data. Useful for lip-sync, karaoke, and subtitle alignment.
generate(), plus:
Returns:
{ audio: Uint8Array, timestamps: TimestampInfo }
streamWithTimestamps(options)
Stream audio chunks, each paired with optional timestamp data. Text must be ≤2,000 characters.
stream(), plus timestampType (required). Default model is "inworld-tts-1.5-mini".
Yields: { audio: Uint8Array, timestamps?: TimestampInfo }
play(audio, options)
Play audio from a Uint8Array or file path. Encoding is auto-detected from magic bytes unless overridden.
Voice Management
listVoices(options)
List available voices, optionally filtered by language.
Returns:
VoiceInfo[]
getVoice(voice)
Get details for a single voice. Works with custom voices in your workspace (cloned or designed voices).
VoiceInfo
cloneVoice(options)
Clone a voice from one or more audio recordings — as little as 3 seconds works, and longer samples (up to 15 seconds) improve similarity.
Returns:
CloneVoiceResult — the cloned voice ID is at result.voice.voiceId.
designVoice(options)
Design a new voice from a text description — no audio recording needed.
Returns:
DesignVoiceResult — preview voices at result.previewVoices.
publishVoice(options)
Publish a designed or cloned voice preview to your library so it can be used in generate() and stream().
Returns:
VoiceInfo
migrateFromElevenLabs(options)
Migrate a voice from ElevenLabs to your Inworld workspace. Fetches the voice’s audio samples directly from ElevenLabs and clones them into Inworld. No ElevenLabs SDK required.
Returns:
{ elevenLabsVoiceId, elevenLabsName, inworldVoiceId }
Configuration
Create a client withInworldTTS() or the equivalent createClient():
Either
apiKey or token must be provided. If neither is set, a MissingApiKeyError is thrown.Browser
The SDK works in browsers (Vite, webpack 5, Rollup, esbuild) with no extra configuration. Use JWT tokens instead of API keys to keep your credentials safe.Authentication with JWT
In production, your backend generates short-lived JWT tokens and your frontend uses them to authenticate. See the JWT authentication guide and the sample Node.js JWT app for how to set up the server-side token endpoint.onTokenExpiring callback fires automatically when the current token is about to expire. It must return a fresh JWT string. The SDK uses a stale-while-revalidate strategy — requests continue with the current token while the refresh happens in the background.
Example: text-to-speech button
A minimal browser example — user clicks a button, the SDK generates audio and plays it:play() must be called inside a user event handler (click, keypress, etc.) due to browser autoplay policies.Browser encoding compatibility
Not all audio encodings are playable in all browsers. UseMP3 for the widest compatibility.
For
LINEAR16/PCM formats, use the Web Audio API directly with the Uint8Array returned by generate() instead of play().
Browser limitations
outputFile— not supported, throws an error. Use the returnedUint8Arraydirectly.play()with file paths — not supported, pass aUint8Arrayinstead.cloneVoice()with file paths — not supported, passUint8Arraybuffers for audio samples.
Development shortcut
For quick prototyping, you can use an API key directly in the browser by settingdangerouslyAllowBrowser:
Long Text
generate() and generateWithTimestamps() automatically chunk text longer than 2,000 characters and send chunks in parallel (controlled by maxConcurrentRequests). The resulting audio is seamlessly concatenated, and timestamp offsets are merged correctly.
stream() and streamWithTimestamps() require text of 2,000 characters or fewer. For longer text with streaming, split the text yourself and call stream() for each segment.
Error Handling
The SDK exports three error classes, all extendingInworldTTSError:
Next Steps
Voice Cloning
Create a personalized voice clone with as little as 3 seconds of audio.
Best Practices
Learn tips and tricks for synthesizing high-quality speech.
API Reference
View the complete TTS API specification.