voice_id: REST,
WebSocket and Speech-to-Speech. No reference audio is needed.
Have a recording instead?
Custom voices clone a speaker from a short audio sample.
How it works
1. Generate
Send a description, get candidate voices back in seconds.
2. Listen
Audition each candidate on a short line of Text-to-Speech.
3. Convert
Promote your pick to a permanent
voice_id.4. Use it
Text-to-Speech, streaming, and Speech-to-Speech all accept it.
seed, so if you like a candidate, convert it: re-running the request will
not bring it back. And the candidates from one request are variations on one
character. For a different character, change the description.
Access
Base URLhttps://api.gradium.ai/api, API key in the x-api-key header.
Quickstart
The steps run as one sequence, carrying ids in shell variables or Python names.1
Generate candidates
201 Created
ready: false.Every request mints new ids. Store them. To recover ids you did not store,
list your candidates with
GET /voice-generator/embeddings.2
Wait for them to be ready
200 OK
200 with an empty embeddings list, not 404, so
check the list before indexing into it. Timestamps are UTC with or without a
trailing Z.3
Listen to a candidate
Pass the candidate id as The response body is the audio, 48 kHz mono. Repeat for the other candidates.Candidates have three restrictions that converted voices do not:
voice_id on the normal Text-to-Speech endpoint. The
vox_emb_ prefix is how the API tells a candidate from a converted voice.- Text is capped at 100 characters (
400 input text too long). - REST only. The TTS WebSocket and Speech-to-Speech reject candidate ids with error
1011. - A candidate that is not ready, unknown, or from another account returns
404 Embedding not found.
4
Convert the candidate into a voice
A candidate is a draft, deleted 30 days after generation. Converting it
creates a permanent voice in your library.
201 Created
uid is your permanent voice_id. Store this one. It is the same value as
voxium_embedding_id in the request and voice_id everywhere else.- Converting is free. The voice uses one custom-voice slot, shared with voice clones. Over the allowance:
409 Custom voice limit reached. - It clears the candidate’s expiry.
- Converting the same candidate twice:
409 A voice was already created from this embedding: <voice_id>. Store the candidate-to-voice mapping yourself rather than parsing this. - Not ready or unknown:
409 Embedding is not ready yet.
5
Use the voice
voice_id works with the
Python SDK, the
TTS WebSocket and
Speech-to-Speech.6
Clean up
Candidates you do not convert are removed after 30 days. To remove one sooner:Safe at any time: a converted voice holds its own copy. An id that is already
gone returns
cURL
404.Complete example
The whole flow in one file. SetGRADIUM_API_KEY and run it. It creates a
real voice in your account.
Audio is streamed, so WAV headers carry placeholder lengths. Readers that trust the header, such as Python’s
wave, report a wrong duration. Rewrite the RIFF and data sizes after saving if that matters to you.Writing a description
The description is the only input the model has. It responds to the attributes a casting brief would carry, and naming more of them gives a tighter result.
End with the intended use. It steers delivery and register, not only the colour
of the voice.
A British female voice, 20 to 30, glossy and confident, with girly chatter, high pitch, fast pacing, high energy and bright sparkling resonance. Ideal for a friendly receptionist or assistant.
Rules of thumb
- Use the space. Up to 500 characters, all usable. Full sentences beat a list of adjectives.
- Describe the voice, not the script. Words to be spoken go in the audition line.
- Set
languageto the language the voice will speak. It shapes the accent and the delivery, not only the words. Regional accents still go in the description: “Bristolian” or “Parisian” has to be written out. - Concrete beats evaluative. “Low pitch, slow pacing, gravelly” gives the model more than “a great narrator voice”.
Examples
The descriptions as sent:
Pirate
A gruff Bristolian English male pirate voice, 45 to 60, for game and character narration: weathered low pitch, gravelly timbre with heavy vocal fry, strong projection, at a steady, unhurried pace, boisterous and commanding energy.Fionn
An Irish English male voice, 40 to 55, for customer service: calm and crisp, with mid-low pitch, steady natural pacing, medium energy and warm rounded resonance. Ideal for reassuring walkthroughs, empathic de-escalation and complex IT support.Freya
A British female voice, 20 to 30, glossy and confident, with girly chatter, high pitch, fast pacing, high energy and bright sparkling resonance. Ideal for a friendly receptionist or assistant.Desmond
An American English male voice, 55 to 65: clean, deliberate and precise, with low pitch, slow pacing and low-to-mid energy, resonant timbre and a gentle low-to-high flow. Ideal for projecting academic authority.
Iterating
Edit the attribute that is off rather than rewriting the description.Building this into a product
If you expose voice design to your own users, prefill a form over the attributes above and compose the sentence from it, with a free-text box as the escape hatch. Show the 500 character limit. Offer “keep this one” as the way to hold onto a voice, and make regenerate send a new description rather than more samples.Generation settings
Generation settings shape the voice and go injson_config on
POST /voice-generator/generate. Synthesis settings
shape each utterance and go in json_config on the TTS request. Each has a
guidance knob, and they differ: cfg_scale is how literally the voice follows
your description, cfg_coef is how closely each utterance sticks to the voice.
All generation settings are optional. The defaults are tuned, so send only the
keys you have a reason to change.
cfg_scale
5.0, the default, when exploring with 3 to 5 candidates and you want them to differ.8.0to12.0when candidates drift from the description, or when generating one candidate at a time. Conversational designers that generate one candidate per turn typically use10.0.- Above
12.0the voice follows the description ever more literally at the cost of naturalness, and candidates converge on each other.
cfg_scale cannot add an attribute the description does not name. Fix the
description first.
seed
The description is expanded before sampling and that expansion varies per
request, so the same prompt and seed still give a different voice.
utmos_score
Conditions the recording, not the speaker: the same character at a higher score
sounds captured in a cleaner room on better equipment. Go toward 4.0 for a
studio sound, lower when a rough quality is part of the character.
The json_config allow-list
Synthesis settings
Auditioning a candidate or synthesising with a converted voice is an ordinary TTS request, so everything in Voice Settings applies. Bothdefault and gradium-tts-beta accept candidates and converted voices.
Temperature (temp)
0.0 to 1.4, default 0.7.
- Audition at the default.
0.0makes a lively voice sound flatter than it will in production. 0.3to0.5for scripted, high-volume output where takes must match: IVR prompts, fixed announcements.- Default or slightly above for conversational agents and narration.
Voice similarity (cfg_coef)
1.0 to 4.0, default 2.0.
2.0for most designed voices.- Toward
3.0when the voice drifts on long or emotional passages, or a designed trait such as a strong accent softens in production. - Above
3.0artefacts become likely.
cfg_coef cannot add a trait the voice lacks. That fix is at generation time: a
sharper description or higher cfg_scale, then a new candidate.
Supported tags
The models read plain text. Two inline tags are recognised, on candidates and converted voices alike. Anything else is spoken aloud as text.
On a candidate, tags count toward the 100-character limit.
Not supported
SSML is not interpreted.<speak><prosody rate="slow">Hello there.</prosody></speak>
produces a voice saying “speak prosody rate slow, hello there, slash prosody,
slash speak”. Use these instead:
Markdown and HTML are read as text too. Strip formatting before sending.
Candidate lifecycle
Limits
Errors
Errors are{"detail": "..."}, except 422, which carries a list of field errors.
A candidate that never becomes ready is almost always a
json_config value out
of range or a key the API does not recognise. See the
allow-list.
Next steps
Manage Voices
List, update, and delete the voices you convert.
Voice Settings
Speed, temperature and other synthesis options.
Streaming Text-to-Speech
Use your new voice on the low-latency WebSocket.
API Reference
The Voice Design endpoints in full.