Mandarin course narration — A short Mandarin e-learning narration with a friendly teaching style.
Gemini 3.8 Flash Lite TTS Text to Speech API
google/gemini-3.8-flash-lite/text-to-speechGemini 3.8 Flash Lite TTS Text to Speech turns scripts and two-speaker dialogues into WAV speech across 101 languages at 6 credits per 1,000 characters. It keeps the 30 preset voices, style instructions and dialogue format of Gemini 3.8 Flash TTS, so high-volume read-aloud work stays simple to scale.
Input
Examples
Gemini 3.8 Flash Lite TTS 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 or dialogue
Send model and input as JSON. The example below uses the first audio sample on this page.
REQUEST_BODY=$(cat <<'JSON'
{
"model": "google/gemini-3.8-flash-lite/text-to-speech",
"input": {
"text": "City crews will begin repaving Harbor Street on Monday. The work is expected to last two weeks, and buses on routes 4 and 9 will use Elm Avenue during that time.",
"voice": "Kore",
"style_instructions": "Clear, neutral news delivery at a steady pace.",
"enable_safety_checker": true
}
}
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": "IK592ONF5J9OUQMH",
"status": "not_started",
"created_time": "2026-11-05T07:14:06"
}
}{
"code": 200,
"data": {
"task_id": "IK592ONF5J9OUQMH",
"status": "finished",
"files": [
{
"file_url": "https://cdn.vidgo.ai/apis/models/google/gemini-3.8-flash-lite/text-to-speech/v2/01/speech-01.wav",
"file_type": "audio",
"file_name": "speech-01.wav"
}
],
"created_time": "2026-11-05T07:14:06",
"error_message": null,
"progress": 100
}
}Read the audio files
Use the audio file_url to play or download the WAV file.
set -euo pipefail
: "${VIDGO_API_KEY:?Set VIDGO_API_KEY in your environment}"
REQUEST_BODY=$(cat <<'JSON'
{
"model": "google/gemini-3.8-flash-lite/text-to-speech",
"input": {
"text": "City crews will begin repaving Harbor Street on Monday. The work is expected to last two weeks, and buses on routes 4 and 9 will use Elm Avenue during that time.",
"voice": "Kore",
"style_instructions": "Clear, neutral news delivery at a steady pace.",
"enable_safety_checker": true
}
}
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 google/gemini-3.8-flash-lite/text-to-speech to select this speech model. |
| input | object | Yes | — | Use text and voice for one speaker, or speakers and turns for a dialogue, plus the optional fields below. |
| input.text | string | Single speaker | — | Single speaker: the script to speak. Write the words as they should be heard; place acting directions in Style Instructions. |
| input.voice | string | Optional | Kore | Single speaker: one of the 30 preset voices. Default Kore. Voices: Achernar, Achird, Algenib, Algieba, Alnilam, Aoede, Autonoe, Callirrhoe, Charon, Despina, Enceladus, Erinome, Fenrir, Gacrux, Iapetus, Kore, Laomedeia, Leda, Orus, Pulcherrima, Puck, Rasalgethi, Sadachbia, Sadaltager, Schedar, Sulafat, Umbriel, Vindemiatrix, Zephyr, Zubenelgenubi. |
| input.speakers | array | Dialogue | — | Dialogue: exactly two speakers, each with a unique speaker_id and one of the 30 preset voices. |
| input.speakers[].speaker_id | string | Per item | — | A unique, non-empty name for the speaker, such as Host. |
| input.speakers[].voice | string | Per item | — | The speaker's preset voice. Voices: Achernar, Achird, Algenib, Algieba, Alnilam, Aoede, Autonoe, Callirrhoe, Charon, Despina, Enceladus, Erinome, Fenrir, Gacrux, Iapetus, Kore, Laomedeia, Leda, Orus, Pulcherrima, Puck, Rasalgethi, Sadachbia, Sadaltager, Schedar, Sulafat, Umbriel, Vindemiatrix, Zephyr, Zubenelgenubi. |
| input.turns | array | Dialogue | — | Dialogue: the lines in order. Each turn names a speaker_id from Speakers, its text, and optional style_instructions for that line. |
| input.turns[].speaker_id | string | Per item | — | The speaker_id of the speaker who says this line. |
| input.turns[].text | string | Per item | — | The words of this line, not blank. |
| input.turns[].style_instructions | string | Optional | — | Optional direction for this line only. |
| input.style_instructions | string | Optional | — | Optional delivery direction for the whole request, such as tone, pace or setting. Its characters count toward billing. |
| input.enable_safety_checker | boolean | Optional | true | Runs the upstream safety checker on the request. Default true. |
| 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; the audio entry holds the WAV speech. |
| data.files[].file_url | string | URL used to play or download a generated file. |
| data.files[].file_type | string | audio for the generated speech. |
| 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 WAV audio.
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 purposeRead the audio entry in files and use its file_url and file_name for 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 | Single-speaker speech or a two-speaker dialogue. |
| Voices | 30 presets | Kore by default; one voice per speaker in dialogue. |
| Speakers | 1 or 2 | Dialogue uses exactly two speakers and one or more turns. |
| Languages | 101 | Detected automatically from the transcript. |
| Output | WAV | One audio file per task. |
| Price | $0.030 / 1K characters | 6 credits per 1,000 billable characters. |
Explore more speech models
Gemini 3.8 Flash Lite TTS Text to Speech API frequently asked questions
What is the Gemini 3.8 Flash Lite TTS Text to Speech API?
Gemini 3.8 Flash Lite TTS Text to Speech is a Google model for fast, cost-efficient speech generation. It produces single-voice speech or two-speaker dialogue in 101 languages with the same 30 preset voices and style instructions as Gemini 3.8 Flash TTS. Google designed the Flash Lite tier for high-throughput production while keeping the transcript read exactly as written. You can call it programmatically or try it from the playground above.
How do I create a two-speaker dialogue with Gemini 3.8 Flash Lite TTS?
Choose Dialogue and send exactly two speakers, each with a speaker_id and a preset voice, plus a turns list. Every turn names one speaker_id, its text and an optional style_instructions. Top-level text and voice are left out in this form.
Where should acting directions go in Gemini 3.8 Flash Lite TTS?
Put them in style_instructions, either for the whole request or for a single turn. Google notes that Gemini 3.8 TTS reads the transcript literally, so directions written inside the text may be spoken aloud.
Which voices does Gemini 3.8 Flash Lite TTS offer?
There are 30 presets: Achernar, Achird, Algenib, Algieba, Alnilam, Aoede, Autonoe, Callirrhoe, Charon, Despina, Enceladus, Erinome, Fenrir, Gacrux, Iapetus, Kore, Laomedeia, Leda, Orus, Pulcherrima, Puck, Rasalgethi, Sadachbia, Sadaltager, Schedar, Sulafat, Umbriel, Vindemiatrix, Zephyr, Zubenelgenubi. Kore is the default for a single speaker.
How does Gemini 3.8 Flash Lite TTS handle languages?
Gemini 3.8 Flash Lite TTS detects the language from the transcript across 101 languages. Write each script in its target language; there is no separate language setting.
How does Gemini 3.8 Flash Lite TTS compare with Gemini 3.8 Flash TTS?
Both accept the same fields, 30 voices and two-speaker dialogue. Flash Lite covers 101 languages at 6 credits ($0.03) per 1,000 characters, while Gemini 3.8 Flash TTS covers 130 languages at 9 credits and is Google's tier for richer acting nuance. Test your dialogue scripts on both before a large run.
What audio format does Gemini 3.8 Flash Lite TTS return?
Each finished task returns a WAV file in files. Convert it to MP3 or Opus in your audio tool if your player or platform needs a compressed format.
How are Gemini 3.8 Flash Lite TTS characters counted for billing?
Billing counts Text, Style Instructions, and in dialogue every turn's text and style instructions, at 6 credits ($0.030) per 1,000 characters. Speaker IDs are not counted.


