My first dumpling — A warm Mandarin recollection, with hesitation and a spontaneous laugh.
ElevenLabs V3 Text to Speech API
elevenlabs/tts/eleven-v3ElevenLabs V3 Text to Speech turns written scripts into expressive speech with audio tags and support for 70+ languages. Guide emotion, pauses, and delivery within your text, then adjust voice stability to suit the performance.
Input
Examples
ElevenLabs V3 Text to Speech API
Generate speech with the API
Submit a script, keep the returned task_id, and retrieve the completed audio through the task status endpoint.
Authenticate your request
Send your Vidgo API key in the Authorization header using Bearer authentication.
- Endpoint
- POST
https://api.vidgo.ai/api/generate/submit - Authentication
- Authorization: Bearer YOUR_API_KEY
Submit the script
Send model and input as JSON. The example below uses the same script and voice as the first audio sample.
REQUEST_BODY=$(cat <<'JSON'
{
"model": "elevenlabs/tts/eleven-v3",
"input": {
"text": "[whispers] Wait... that ticking is coming from inside the wall. [curious] This little brass key fits the crack. One turn, and... [excited] the whole ceiling is full of stars! [laughs] Grandpa, you built a planetarium in the attic. [exhales] All these years, it was waiting for us.",
"voice": "Charlotte",
"language_code": "en",
"stability": 0.5,
"timestamps": false,
"apply_text_normalization": "auto"
}
}
JSON
)
RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
CODE=$(printf '%s' "$RESPONSE" | jq -r '.code // empty')
if [ "$CODE" != "0" ] && [ "$CODE" != "200" ]; then
printf 'API error: %s
' "$RESPONSE" >&2
exit 1
fi
printf '%s
' "$RESPONSE"Follow the task
Query the returned task_id until status is finished or failed.
Status endpoint
GET https://api.vidgo.ai/api/generate/status/{task_id}Keep the task_id from submission. Check its status and read the generated files when it finishes.
not_startedrunningfinishedfailed{
"code": 200,
"data": {
"task_id": "LPV36KJQ0Y2SYT21",
"status": "not_started",
"created_time": "2026-09-27T10:45:57"
}
}{
"code": 200,
"data": {
"task_id": "LPV36KJQ0Y2SYT21",
"status": "finished",
"files": [
{
"file_url": "https://cdn.vidgo.ai/apis/models/elevenlabs/tts/eleven-v3/v1/01/speech.mp3",
"file_type": "audio",
"file_name": "speech.mp3"
}
],
"created_time": "2026-09-27T10:45:57",
"error_message": null,
"progress": 100
}
}Read the audio files
Use the audio file_url for playback or download. When requested, download timestamps.json from the other file entry.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "elevenlabs/tts/eleven-v3",
"input": {
"text": "[whispers] Wait... that ticking is coming from inside the wall. [curious] This little brass key fits the crack. One turn, and... [excited] the whole ceiling is full of stars! [laughs] Grandpa, you built a planetarium in the attic. [exhales] All these years, it was waiting for us.",
"voice": "Charlotte",
"language_code": "en",
"stability": 0.5,
"timestamps": false,
"apply_text_normalization": "auto"
}
}
JSON
)
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
--request POST \
--url "https://api.vidgo.ai/api/generate/submit" \
--header "Authorization: Bearer $VIDGO_API_KEY" \
--header "Content-Type: application/json" \
--data "$REQUEST_BODY")
TASK_ID=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.data.task_id // .task_id // empty')
BUSINESS_CODE=$(printf '%s' "$SUBMIT_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Submit failed:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
if [ -z "$TASK_ID" ]; then
printf 'Submit response did not include task_id:
%s
' "$SUBMIT_RESPONSE" >&2
exit 1
fi
START_TIME=$(date +%s)
POLL_DELAY=2
while true; do
if [ $(( $(date +%s) - START_TIME )) -ge 600 ]; then
printf 'Timed out after 600 seconds
' >&2
exit 1
fi
STATUS_RESPONSE=$(curl --silent --show-error --fail-with-body \
--url "https://api.vidgo.ai/api/generate/status/$TASK_ID" \
--header "Authorization: Bearer $VIDGO_API_KEY")
STATUS=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.data.status // .status // empty')
BUSINESS_CODE=$(printf '%s' "$STATUS_RESPONSE" | jq -r '.code // empty')
if [ "$BUSINESS_CODE" != "0" ] && [ "$BUSINESS_CODE" != "200" ]; then
printf 'Status request failed:
%s
' "$STATUS_RESPONSE" >&2
exit 1
fi
case "$STATUS" in
finished)
printf '%s' "$STATUS_RESPONSE" | jq -r '(.data.files // .files // [])[]?.file_url'
break
;;
failed)
printf '%s' "$STATUS_RESPONSE" | jq -r '.data.error_message // .error_message // "Generation failed"' >&2
exit 1
;;
not_started|running)
sleep "$POLL_DELAY"
if [ "$POLL_DELAY" -lt 10 ]; then POLL_DELAY=$((POLL_DELAY + 1)); fi
;;
*)
printf 'Unexpected task status: %s
' "$STATUS" >&2
exit 1
;;
esac
doneRequest parameters
Place speech controls inside input; keep model and callback_url at the top level.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| model | string | Yes | — | Use elevenlabs/tts/eleven-v3 to select this speech model. |
| input | object | Yes | — | Contains the script and speech controls listed below. |
| input.text | string | Yes | — | The script to speak, from 1 to 5,000 characters after trimming leading and trailing whitespace. Add inline audio tags such as [whispers] or [excited] to direct the delivery. |
| input.voice | string | No | Rachel | Choose one of the 21 preset voices. Audition a short passage to match the voice to your narrator or character. Available voices: Aria, Roger, Sarah, Laura, Charlie, George, Callum, River, Liam, Charlotte, Alice, Matilda, Will, Jessica, Eric, Chris, Brian, Daniel, Lily, Bill, Rachel. |
| input.stability | number | No | 0.5 | A value from 0 to 1. Lower settings encourage expressive variation; higher settings favor steadier delivery. Start at 0.5 and compare the same passage. |
| input.timestamps | boolean | No | false | Set to true to request timing data. The result includes a separate timestamps.json attachment alongside the audio. |
| input.language_code | string | No | — | Optional ISO 639-1 language code, such as en, zh, or es, to specify the spoken language. Leave empty for automatic language detection. |
| input.apply_text_normalization | string | No | auto | Choose auto for automatic text normalization, on to enable it, or off for text you have already prepared for speech. Normalization helps turn numbers and symbols into spoken words. |
| callback_url | string | No | — | Optional HTTP or HTTPS URL for task notifications. Include it at the top level of the request. |
Response fields
Submission identifies the task. Status responses report progress toward the completed audio.
| Field | Type | Description |
|---|---|---|
| code | integer | Response code. A successful response uses 200 or 0. |
| data.task_id | string | Task identifier used to query status. |
| data.status | string | Task state: not_started, running, finished, or failed. |
| data.created_time | string | Task creation time returned by the service. |
| data.files | array | Generated files. Read audio entries for speech and other entries for requested attachments. |
| data.files[].file_url | string | URL used to play or download a generated file. |
| data.files[].file_type | string | audio for speech; other for attachments such as timestamps.json. |
| data.files[].file_name | string | File name, when returned. |
| data.error_message | string | null | Error details when a task fails. |
Task lifecycle
Use the task state to decide when to check again or read the result.
not_startedThe task has been accepted and is waiting to start.
runningSpeech generation is in progress. Continue checking the same task.
finishedGeneration is complete. Read files for the audio and requested attachments.
failedGeneration failed. Read error_message before deciding whether to submit a new request.
Handle results and interruptions
- Keep the current task identifierIf a status request is interrupted, query the same task_id again to recover its latest state.
- Match each file to its purposeUse file_type to separate speech from attachments. Read the returned file_url and file_name for each download.
- Inspect a failed taskWhen status is failed, read error_message and review the script and settings before submitting another generation.
Speech specifications
| Item | Value | Description |
|---|---|---|
| Task | Text to Speech | Generate speech from a script and a selected voice. |
| Text length | 1–5,000 characters | Count after trimming leading and trailing whitespace. |
| Voices | 21 presets | Select the voice through input.voice. |
| Languages | 70+ | Automatic detection or an explicit language_code. |
| Timing data | timestamps.json | Requested with timestamps set to true. |
Explore more audio models
ElevenLabs V3 Text to Speech API frequently asked questions
What is the ElevenLabs V3 Text to Speech API?
ElevenLabs V3 Text to Speech is an ElevenLabs model for converting written scripts into emotionally expressive speech. It generates narration and character performances with audio tags and support for 70+ languages. By interpreting tags alongside punctuation and narrative context, it lets you guide delivery around a selected voice and adjust stability for the scene. You can call it programmatically or try it from the playground above.
How do audio tags work in ElevenLabs V3?
Write performance directions in square brackets inside Text, such as [excited] before a reveal or [whispers] before a quiet line. Place each tag where the delivery should change and keep the surrounding sentence natural. Begin with one clear direction, then listen and refine the wording or voice choice.
Can ElevenLabs V3 perform whispers and laughter?
Yes. Tags such as [whispers], [laughs], and [sighs] can guide quiet delivery and human reactions within a passage. Choose a voice suited to the scene and place the cue next to the relevant line, so the reaction has a clear narrative context.
Which languages does ElevenLabs V3 support?
ElevenLabs V3 supports 70+ languages, including English, Mandarin Chinese, Spanish, French, Japanese, and Korean. Enter the script in the target language and optionally set Language Code, such as en or zh. For localized versions, supply a separate translated script for each language and audition the chosen voice.
How does Stability affect ElevenLabs V3 speech?
Stability adjusts the balance between expressive variation and steadier delivery. Start at 0.5, then compare a lower value for an animated character or a higher value for measured narration, within the 0 to 1 range. Keep the script and voice fixed while comparing settings.
How should long scripts be split for ElevenLabs V3?
Keep each request within 5,000 characters, including audio tags, punctuation, and spaces inside the script. Split at paragraph or scene boundaries so each passage carries enough context for the performance. Reuse your voice and language settings, then review the transitions when assembling the audio.
How does ElevenLabs V3 read numbers aloud?
Text normalization helps turn written numbers and symbols into spoken expressions. Use Apply Text Normalization with auto for automatic handling or on to enable normalization. Test a short passage containing your dates or amounts, and write out the intended reading when a specific pronunciation is essential.
Can ElevenLabs V3 return timestamps?
Yes. Enable Timestamps to request timing data alongside the generated speech. The completed result includes a separate timestamps.json attachment, which you can download with the audio and use as a timing reference for captions or editing.















