Voice design lets you create a brand-new, persistent vocal persona from a
natural-language description using the Gemini API Voices endpoint
(POST /v1beta/voices). Instead of being limited to prebuilt voices or
recording reference audio, you can describe a character's age, vocal timbre,
accent, and baseline delivery, and receive a reusable voice_... ID saved to
your project.
The fastest way to design, audition, and iterate on custom voices is with the
interactive Voice Design studio in
Google AI Studio. You can
generate custom personas from text prompts, test them with sample scripts, and
copy the resulting voice_... ID directly into your application code.
Both Gemini 3.8 Flash TTS
(gemini-3.8-flash-tts) and
Gemini 3.8 Flash-Lite TTS
(gemini-3.8-flash-lite-tts) support Voice design.
Create a designed voice
Use the Google GenAI SDK (google-genai 2.25.0+ / @google/genai 2.24.0+) or REST API
to create a custom voice from a text description. For "prompted" voices, both
voices.create (CreateVoice) and voices.get (GetVoice) return an
output-only sample_audio field (mime_type: "audio/wav", base64-encoded
data) so you can immediately audition the generated voice:
Python
import base64
from google import genai
client = genai.Client()
# 1. Design a custom voice persona from natural language
created_voice = client.voices.create(
store=True,
voice={
"model": "gemini-3.8-flash-tts",
"type": "prompted",
"display_name": "Warm British Astronomer",
"gender": "male",
"language_code": "en-GB",
"prompted": {
"input": (
"A warm, thoughtful astronomer in his late 60s with a gentle"
" British accent, speaking with quiet wonder."
)
},
},
)
print(f"Created voice ID: {created_voice.id}")
# Save the generated sample_audio preview (audio/wav) returned by CreateVoice
if created_voice.sample_audio and created_voice.sample_audio.data:
with open("voice_preview.wav", "wb") as f:
f.write(base64.b64decode(created_voice.sample_audio.data))
JavaScript
import * as fs from "node:fs";
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI();
// 1. Design a custom voice persona from natural language
const createdVoice = await ai.voices.create({
store: true,
voice: {
model: "gemini-3.8-flash-tts",
type: "prompted",
display_name: "Warm British Astronomer",
gender: "male",
language_code: "en-GB",
prompted: {
input:
"A warm, thoughtful astronomer in his late 60s with a gentle British accent, speaking with quiet wonder.",
},
},
});
console.log(`Created voice ID: ${createdVoice.id}`);
// Save the generated sample_audio preview (audio/wav) returned by CreateVoice
if (createdVoice.sample_audio?.data) {
fs.writeFileSync(
"voice_preview.wav",
Buffer.from(createdVoice.sample_audio.data, "base64")
);
}
REST
curl "https://generativelanguage.googleapis.com/v1beta/voices" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"store": true,
"voice": {
"model": "gemini-3.8-flash-tts",
"type": "prompted",
"display_name": "Warm British Astronomer",
"gender": "male",
"language_code": "en-GB",
"prompted": {
"input": "A warm, thoughtful astronomer in his late 60s with a gentle British accent, speaking with quiet wonder."
}
}
}' | tee created_voice.json | jq -r '.sample_audio.data' | base64 --decode > voice_preview.wav
How Voice design works
- Create a prompted voice: Call
voices.create(POST /v1beta/voices) withtype="prompted"andstore=True. - Receive a persistent
voice_idandsample_audiopreview: The API generates the vocal identity, stores it in your project, and returns a permanent ID (for example,voice_abc123...) along withsample_audio(mime_type: "audio/wav", base64-encodeddata) containing the generated preview audio for the voice. - Synthesize speech: Pass the
voice_idinspeechConfig.voiceConfig.voicewhen callinggenerateContent.
Synthesize speech with your designed voice
Pass the returned id (voice_...) in voiceConfig.voice when calling
generateContent:
Python
from google import genai
client = genai.Client()
response = client.models.generate_content(
model="gemini-3.8-flash-tts",
contents=[{
"role": "user",
"parts": [{
"text": (
"Look out past the rings of Saturn. Those faint photons left"
" their source millions of years ago."
),
"speech_metadata": {"style": "reflective and awe-inspired"},
}],
}],
config={
"response_modalities": ["AUDIO"],
"speech_config": {
"voice_config": {"voice": created_voice.id}
},
},
)
audio_bytes = response.candidates[0].content.parts[0].inline_data.data
with open("designed_voice.wav", "wb") as f:
f.write(audio_bytes)
JavaScript
import * as fs from "node:fs";
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI();
const response = await ai.models.generateContent({
model: "gemini-3.8-flash-tts",
contents: [{
role: "user",
parts: [{
text: "Look out past the rings of Saturn. Those faint photons left their source millions of years ago.",
speechMetadata: { style: "reflective and awe-inspired" },
}],
}],
config: {
responseModalities: ["AUDIO"],
speechConfig: {
voiceConfig: { voice: createdVoice.id },
},
},
});
const data = response.candidates?.[0]?.content?.parts?.[0]?.inlineData?.data;
if (data) {
fs.writeFileSync("designed_voice.wav", Buffer.from(data, "base64"));
}
REST
curl "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.8-flash-tts:generateContent" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-X POST \
-d '{
"contents": [{
"role": "user",
"parts": [{
"text": "Look out past the rings of Saturn. Those faint photons left their source millions of years ago.",
"speech_metadata": {
"style": "reflective and awe-inspired"
}
}]
}],
"generationConfig": {
"responseModalities": ["AUDIO"],
"speechConfig": {
"voiceConfig": {
"voice": "voice_YOUR_DESIGNED_VOICE_ID"
}
}
}
}'
Manage your voices
You can list, filter, inspect, and delete your stored voices at any time using the Voices API (see Extended Voice Library and filtering for all filter parameters).
- Storage limits and TTL: Stateful voices (
store=True, shared across prompted and replicated voices) have a limit of 200 voices per project and a 1-year TTL (time-to-live). sample_audioavailability:voices.create()(CreateVoice) andvoices.get()(GetVoice) populatesample_audio(mime_type: "audio/wav", base64-encodeddata) for"prompted"voices. To keep listing lightweight,voices.list()(ListVoices) omitssample_audio(andsample_audiois unset for"replicated"and"prebuilt"voices).
Python
from google import genai
client = genai.Client()
# List stored prompted voices in your project filtered by language
response = client.voices.list(
type_=["prompted"],
language_code=["en-US", "en-GB"],
)
for voice in response.voices or []:
print(voice.id, voice.display_name, voice.type)
# Retrieve a specific voice by ID
voice_details = client.voices.get(id=created_voice.id)
# Delete a stored custom voice
client.voices.delete(id=created_voice.id)
JavaScript
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI();
// List stored prompted voices in your project filtered by language
const response = await ai.voices.list({
type: ["prompted"],
language_code: ["en-US", "en-GB"],
});
for (const voice of response.voices ?? []) {
console.log(voice.id, voice.display_name, voice.type);
}
// Retrieve a specific voice by ID
const voiceDetails = await ai.voices.get(createdVoice.id);
// Delete a stored custom voice
await ai.voices.delete(createdVoice.id);
REST
# List stored prompted voices filtered by language
curl -G "https://generativelanguage.googleapis.com/v1beta/voices" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
--data-urlencode "type=prompted" \
--data-urlencode "language_code=en-US" \
--data-urlencode "language_code=en-GB"
# Retrieve a specific voice by ID
curl "https://generativelanguage.googleapis.com/v1beta/voices/voice_YOUR_DESIGNED_VOICE_ID" \
-H "x-goog-api-key: $GEMINI_API_KEY"
# Delete a stored custom voice
curl -X DELETE "https://generativelanguage.googleapis.com/v1beta/voices/voice_YOUR_DESIGNED_VOICE_ID" \
-H "x-goog-api-key: $GEMINI_API_KEY"
Prompting best practices for Voice design
- Put permanent vocal traits in Voice design, not
style: Define immutable characteristics—such as age, gender, timbre, vocal texture, and regional accent—when creating the voice invoices.create. - Reserve
speech_metadata.stylefor situational emotion: Once your custom voice is created, use shortstyleprompts (for example,"whispered urgently"or"cheerful and energetic") to steer turn-by-turn acting without altering the speaker's core identity. - Be specific and concise: A clear 1–2 sentence description (such as "A crisp, energetic sports announcer in her 30s with a slight Midwestern accent") produces cleaner, more consistent results than contradictory or overly long paragraphs.
What's next
- Learn how to replicate an existing speaker's voice in Voice replication.
- Explore turn-level styling, inline tags, and multi-speaker dialogue in the Text-to-speech guide.