Create Custom Voice
June 5, 2026
Table of contents
Create a custom voice (also called a user voice) on a Google Flow account. A custom voice is a saved Text-to-Speech (TTS) clip built on top of one of the 30 system voice presets (Achernar, Achird, Algenib, …) with your own dialog text and voicePerformance description.
Once created, the voice can be:
- Used in POST /videos via
referenceAudio_1..5 - Attached to a POST /characters at create time (
voicebody param) - Played back via GET /voices/
ref(returns a fresh signedaudioUrl)
Captcha: required. See Captcha Parameters.
https://api.useapi.net/v1/google-flow/voices
Request Headers
Authorization: Bearer {API token}
Content-Type: application/json
Request Body
{
"email": "[email protected]",
"voice": "Achernar",
"dialog": "Hello, this is a test voice.",
"voicePerformance": "Cheerful, energetic delivery",
"displayName": "Cheerful Narrator"
}
emailis required, the Google Flow account to create the voice on.-
voiceis required, one of the 30 system voice presets. The custom voice inherits the timbre of this base voice. Case-sensitive. Valid values:Achernar, Achird, Algenib, Algieba, Alnilam, Aoede, Autonoe, Callirrhoe, Charon, Despina, Enceladus, Erinome, Fenrir, Gacrux, Iapetus, Kore, Laomedeia, Leda, Orus, Puck, Pulcherrima, Rasalgethi, Sadachbia, Sadaltager, Schedar, Sulafat, Umbriel, Vindemiatrix, Zephyr, Zubenelgenubi displayNameis required, user-facing label for the voice. Range: 1-200 chars. Shown in GET /voices and used to distinguish multiple voices in your list.dialogis required, the text the voice will say. Range: 1-120 chars. Used as the audio preview sample.voicePerformanceis required, short description of delivery style (e.g. “Cheerful, energetic delivery”, “Deep, brooding villain tone”). Range: 1-120 chars.captchaToken,captchaRetry,captchaOrderare optional, mutually exclusive captcha parameters. See Captcha Parameters for details.
Responses
-
Voice created.
{ "voice": "user:12345-email:6a6f...-voice:d990a2f9-...-mid:d55b6d59-...", "source": "user", "workflowId": "d990a2f9-...", "mediaId": "d55b6d59-...", "displayName": "Cheerful Narrator", "baseVoice": "Achernar", "dialog": "Hello, this is a test voice.", "voicePerformance": "Cheerful, energetic delivery", "audioUrl": "https://flow-content.google/audio/d55b6d59-...?Expires=...&KeyName=labs-flow-prod-cdn-key&Signature=..." }Use the
voicefield as the value forreferenceAudio_1..referenceAudio_5on POST /videos, or as thevoicebody param when creating a character via POST /characters. It’s also the path segment for GET /voices/refand DELETE /voices/ref. -
Validation error (missing required field, invalid voice name, dialog/voicePerformance > 120 chars, etc).
{ "error": "Parameter voice is required (must be one of Achernar,Achird,Algenib,…)" } -
Invalid API token.
{ "error": "Unauthorized" } -
Request rejected by Google — the reCAPTCHA token was outright rejected (not just scored low). After internal retries with fresh tokens, the worker returns this. The top-level
errorfield carries acaptcha_quality:prefix so tooling can detect this failure class. IncreasecaptchaRetry(default 3) in the request body to 5 or higher, and configure additional providers via POST /accounts/captcha-providers socaptchaOrdercan cycle across them. If issues persist, contact your reCAPTCHA provider(s) support. -
Account not configured.
{ "error": "Google Flow account [email protected] not found" } -
Google returns several
RESOURCE_EXHAUSTED429 variants. Check thereasonfield and respond accordingly:Reason Meaning Scope What to do Cooldown PUBLIC_ERROR_USER_REQUESTS_THROTTLEDPer-user concurrency limit (the token was fine) All models on the account Run fewer parallel requests, retry later ~30 min PUBLIC_ERROR_USER_QUOTA_REACHEDAccount’s overall Flow quota cap All models on the account Add accounts, or omit emailto load-balance~30 min PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHEDPer-model daily quota Only that model, on that account Switch model, or wait Next UTC midnight PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFICCaptcha-provider issue — low reCAPTCHA score (worker already auto-retried) Per request Add more captcha providers + captchaOrder, or raisecaptchaRetry60s Every
429returns the cooldown two ways — an HTTPRetry-After: <seconds>header and a bodyretryAfter: <ISO timestamp>field. Honor it before retrying.When
emailis omitted, the first three reasons quarantine the account and the load balancer routes around it. If every account is quarantined for the model you get429witherror: "no_eligible_account". Routing details: GET /jobs › Load Balancing Algorithm.Captcha-quality failures prefix the top-level
errorwithcaptcha_quality:(e.g."captcha_quality: PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC after 3 attempts") so you can detect them without parsing the nested body. -
503has two distinct causes — check the response body to tell them apart.A transient Google-side outage. Wait 5-10 seconds and retry.
{ "error": { "code": 503, "message": "Service temporarily unavailable.", "status": "UNAVAILABLE" } }A captcha-provider failure — the top-level
erroris prefixedCaptcha service failed:. The problem is your captcha provider (check its API key and balance), not Google. Don’t retry until the provider is back.{ "error": "Captcha service failed: ERROR_ZERO_BALANCE", "code": 503 }
Model
{
voice: string // reference-id used in subsequent calls
source: 'user'
workflowId: string
mediaId: string
displayName: string
baseVoice: string // one of the 30 system voice presets
dialog: string
voicePerformance: string
audioUrl?: string // signed playback URL (~6h TTL); occasionally absent on transient resolution failure
}
Examples
-
curl -X POST \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "email": "[email protected]", "voice": "Achernar", "dialog": "Welcome to the demo.", "voicePerformance": "Cheerful, energetic delivery", "displayName": "Cheerful Narrator" }' \ "https://api.useapi.net/v1/google-flow/voices" -
const response = await fetch('https://api.useapi.net/v1/google-flow/voices', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ email: '[email protected]', voice: 'Achernar', dialog: 'Welcome to the demo.', voicePerformance: 'Cheerful, energetic delivery', displayName: 'Cheerful Narrator' }) }) const result = await response.json() console.log('voice ref:', result.voice) -
import requests r = requests.post( 'https://api.useapi.net/v1/google-flow/voices', headers={'Authorization': f'Bearer {token}'}, json={ 'email': '[email protected]', 'voice': 'Achernar', 'dialog': 'Welcome to the demo.', 'voicePerformance': 'Cheerful, energetic delivery', 'displayName': 'Cheerful Narrator', }, ) print('voice ref:', r.json()['voice'])