curl --location 'https://api.inworld.ai/tts/v1/voice:synthesizeAsync' \
--header "Authorization: Basic $INWORLD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"text": "Hello, world! What a wonderful day to be a text-to-speech model!",
"voiceId": "Dennis",
"modelId": "inworld-tts-2",
"audioConfig": {
"audioEncoding": "MP3"
},
"timestampType": "WORD"
}'import requests
url = "https://api.inworld.ai/tts/v1/voice:synthesizeAsync"
headers = {
"Authorization": "Basic <api-key>",
"Content-Type": "application/json"
}
payload = {
"text": "Hello, world! What a wonderful day to be a text-to-speech model!",
"voiceId": "Dennis",
"modelId": "inworld-tts-2",
"audioConfig": {"audioEncoding": "MP3"},
"timestampType": "WORD"
}
operation = requests.post(url, json=payload, headers=headers).json()
print(operation["name"]) # poll this via GET /lro/v1alpha/{name}const url = 'https://api.inworld.ai/tts/v1/voice:synthesizeAsync';
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Basic <api-key>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: 'Hello, world! What a wonderful day to be a text-to-speech model!',
voiceId: 'Dennis',
modelId: 'inworld-tts-2',
audioConfig: { audioEncoding: 'MP3' },
timestampType: 'WORD',
}),
});
const operation = await response.json();
console.log(operation.name); // poll this via GET /lro/v1alpha/{name}{
"name": "workspaces/{workspace}/ttsAsyncJobs/8f14e45f-ceea-4673-93d8-04f724c8a1b2/operations/1784837936461-p0sEhU",
"metadata": null,
"done": false
}{
"code": 5,
"message": "Unknown voice: John not found!",
"details": []
}Synthesize speech (async)
Submit a synthesis job that runs in the background and immediately receive a long-running operation. Poll the operation via the Get operation endpoint until done is true, then download the results from the time-limited signed URLs in its response. The request body is identical to synchronous synthesis. Unlike the synchronous endpoints, a job never returns audio with requested timestamps silently missing: timestampType in a language without alignment support is rejected at submit, and an alignment failure during synthesis fails the operation.
curl --location 'https://api.inworld.ai/tts/v1/voice:synthesizeAsync' \
--header "Authorization: Basic $INWORLD_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"text": "Hello, world! What a wonderful day to be a text-to-speech model!",
"voiceId": "Dennis",
"modelId": "inworld-tts-2",
"audioConfig": {
"audioEncoding": "MP3"
},
"timestampType": "WORD"
}'import requests
url = "https://api.inworld.ai/tts/v1/voice:synthesizeAsync"
headers = {
"Authorization": "Basic <api-key>",
"Content-Type": "application/json"
}
payload = {
"text": "Hello, world! What a wonderful day to be a text-to-speech model!",
"voiceId": "Dennis",
"modelId": "inworld-tts-2",
"audioConfig": {"audioEncoding": "MP3"},
"timestampType": "WORD"
}
operation = requests.post(url, json=payload, headers=headers).json()
print(operation["name"]) # poll this via GET /lro/v1alpha/{name}const url = 'https://api.inworld.ai/tts/v1/voice:synthesizeAsync';
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'Basic <api-key>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: 'Hello, world! What a wonderful day to be a text-to-speech model!',
voiceId: 'Dennis',
modelId: 'inworld-tts-2',
audioConfig: { audioEncoding: 'MP3' },
timestampType: 'WORD',
}),
});
const operation = await response.json();
console.log(operation.name); // poll this via GET /lro/v1alpha/{name}{
"name": "workspaces/{workspace}/ttsAsyncJobs/8f14e45f-ceea-4673-93d8-04f724c8a1b2/operations/1784837936461-p0sEhU",
"metadata": null,
"done": false
}{
"code": 5,
"message": "Unknown voice: John not found!",
"details": []
}Authorizations
Your authentication credentials. For Basic authentication, please populate Basic $INWORLD_API_KEY. You can create a key in one command with the Inworld CLI: inworld workspace add-key.
Body
The text to be synthesized into speech. Maximum input of 2,000 characters.
The ID of the voice to use for synthesizing speech.
Configurations to use when synthesizing speech.
Show child attributes
Show child attributes
BCP-47 language tag (e.g., en-US, fr-FR, ja-JP) specifying the language that the given voice should speak the text in. Matching is case- and separator-insensitive for standard two-part tags (en-gb, EN_GB, and en-GB are equivalent); longer tags with extension subtags must match a catalog entry exactly. If a localized voice prompt exists for the language, it will be used. When omitted, the original voice prompt will be used and the language will be auto-detected from the input text. If an invalid language code is provided, an error will be returned.
See Languages for more details.
Only supported by inworld-tts-2. The field is ignored on other models.
Controls how varied the output is.
DELIVERY_MODE_UNSPECIFIED: Defaults toBALANCEDbehavior.STABLE: Optimizes for more consistent, predictable output.BALANCED: Balanced between stability and diversity.CREATIVE: Optimizes for increased emotional range and variation.
DELIVERY_MODE_UNSPECIFIED, STABLE, BALANCED, CREATIVE Only supported by inworld-tts-2. The field is ignored on other models.
Speaking-style instruction for this request — for example speak loudly and urgently or sound out of breath. Applies to the whole request. Write it in English, even when text is in another language. An empty string means unset.
You can also change the instruction mid-text with inline [bracket] tags. A tag applies from where it appears until you change it, so it overrides this field from that point on; [reset] removes the instruction for the rest of the text. Prefer one approach or the other rather than combining them.
See Steering for the full guide.
Ignored on inworld-tts-2. Use deliveryMode instead.
Determines the degree of randomness when sampling audio tokens to generate the response.
Defaults to 1.0. Accepts values between 0 (exclusive) and 2 (inclusive). Higher values will make the output more random and can lead to more expressive results. Lower values will make it more deterministic. If 0 is provided, the default value will be used.
For the most stable results, we recommend using the default value.
Controls timestamp metadata returned with the audio. When enabled, the response includes timing arrays, which can be useful for word-highlighting, karaoke-style captions, and lipsync.
- WORD: Output arrays under
timestampInfo.wordAlignment(words, wordStartTimeSeconds, wordEndTimeSeconds). - CHARACTER: Output arrays under
timestampInfo.characterAlignment(characters, characterStartTimeSeconds, characterEndTimeSeconds). - TIMESTAMP_TYPE_UNSPECIFIED: Do not compute alignment; timestamp arrays will be empty or omitted.
Phonetic details: phoneticDetails is currently only returned for WORD alignment (not CHARACTER).
Latency note: Alignment adds additional computation. Enabling alignment can increase latency.
TIMESTAMP_TYPE_UNSPECIFIED, WORD, CHARACTER When enabled, text normalization automatically expands and standardizes things like numbers, dates, times, and abbreviations before converting them to speech. For example, Dr. Smith becomes Doctor Smith, and 3/10/25 is spoken as March tenth, twenty twenty-five. Turning this off may reduce latency, but the speech output will read the text exactly as written. Defaults to automatically deciding whether to apply text normalization.
APPLY_TEXT_NORMALIZATION_UNSPECIFIED, ON, OFF When true, applies denoising to the synthesized audio to reduce background noise and artifacts, improving the overall audio quality of the generation. Defaults to false (no denoising).
Context for the current synthesis request. Supplying the text of earlier requests from the same session or conversation gives the model additional context and can improve the quality of the generation, especially for short or ambiguous input text.
Show child attributes
Show child attributes
Response
The job was accepted. The returned operation is not yet done; poll it to track progress.
A google.longrunning.Operation tracking an asynchronous or batch synthesis job.
Server-assigned operation resource name, in the format workspaces/{workspace}/ttsAsyncJobs/{job}/operations/{operation} for async jobs or workspaces/{workspace}/ttsBatchJobs/{batch}/operations/{operation} for batch jobs. Pass it verbatim as the path of the Get operation endpoint to poll for completion.
"workspaces/{workspace}/ttsAsyncJobs/8f14e45f-ceea-4673-93d8-04f724c8a1b2/operations/1784837936461-p0sEhU"
Service-specific metadata associated with the operation. Not populated for TTS jobs yet; job metadata is planned for a later release, so do not write code that depends on this field staying absent.
Show child attributes
Show child attributes
If false, the job is still running. If true, the job has finished and exactly one of error or response is set.
Show child attributes
Show child attributes
Set when the job succeeded. Its @type identifies which kind: an async job carries SynthesizeSpeechAsyncResponse, a batch job SynthesizeSpeechBatchResponse.
- Option 1
- Option 2
Show child attributes
Show child attributes
Was this page helpful?