Text to Speech Guide
Text-to-speech turns written text into spoken audio for assistants, narration, accessibility, training content, and voice responses. AvalAI exposes TTS through the OpenAI-compatible /v1/audio/speech endpoint plus provider-specific model choices.
Related docs: Audio API, Building conversational audio apps, Audio processing
Choose a Model
| Model family | Best for | Notes |
|---|---|---|
gpt-audio-1.5 | Premium voice quality and controllable tone, pace, and style | Current recommended OpenAI-compatible speech model. |
gpt-audio | Balanced audio input/output applications | General-purpose OpenAI-compatible audio. |
gpt-audio-mini | Development and high-volume voice features | Cost-efficient OpenAI-compatible speech. |
gemini-3.8-flash-tts | Creative quality, expressive acting, regional accents, long-form dialogue | Recommended creative TTS; text in, audio out. |
gemini-3.8-flash-lite-tts | High throughput, low latency, everyday read-aloud speech | Recommended throughput TTS; same native structured schema as Flash. |
gemini-2.5-pro-tts / gemini-2.5-flash-tts | Existing Vertex integrations | Preserve legacy /v1/text:synthesize requests; migrate new work to the supported 3.8 routes. |
eleven_v3, eleven_multilingual_v2, eleven_turbo_v2_5, eleven_flash_v2_5 | ElevenLabs voices | Choose for expressive or multilingual voice products. |
Deprecated:
gpt-4o-mini-tts,tts-1, andtts-1-hdare deprecated and no longer available. Migrate togpt-audio-1.5or a Gemini TTS model. See Major Model Deprecations and Migration Guide.
Basic Speech Generation
curl https://api.avalai.ir/v1/audio/speech \
-H "Authorization: Bearer $AVALAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-audio-1.5",
"voice": "coral",
"input": "Today is a wonderful day to build something people love.",
"response_format": "mp3"
}' \
--output speech.mp3import os
from pathlib import Path
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
with client.audio.speech.with_streaming_response.create(
model="gpt-audio-1.5",
voice="coral",
input="Today is a wonderful day to build something people love.",
response_format="mp3",
) as response:
response.stream_to_file(Path("speech.mp3"))import fs from "node:fs/promises";
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AVALAI_API_KEY,
baseURL: "https://api.avalai.ir/v1",
});
const speech = await client.audio.speech.create({
model: "gpt-audio-1.5",
voice: "coral",
input: "Today is a wonderful day to build something people love.",
response_format: "mp3",
});
await fs.writeFile("speech.mp3", Buffer.from(await speech.arrayBuffer()));Gemini 3.8 TTS
curl --fail-with-body -sS https://api.avalai.ir/v1/audio/speech \
-H "Authorization: Bearer $AVALAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash-tts",
"voice": {"name": "Zephyr", "languageCode": "en-US"},
"input": "Welcome to AvalAI. This voice was generated by AI.",
"response_format": "mp3"
}' \
--output speech.mp3The English input matches languageCode: "en-US". response_format: "mp3" is explicit because the output is saved as MP3. To optimize throughput, change only model to gemini-3.8-flash-lite-tts. For per-turn speaker/style control and MIME-aware native decoding, see the native TTS example.
Migrate to Gemini 3.8 TTS
For new text-to-speech workloads, choose gemini-3.8-flash-tts for creative quality, expressive acting, regional accents, and stable long-form dialogue; choose gemini-3.8-flash-lite-tts for high throughput, low latency, and everyday read-aloud speech. Both accept text input and produce audio output. They are not transcription, audio-input conversation, Live API, or reasoning models.
AvalAI supports these TTS models only through native /v1beta/models methods, /v1/chat/completions, and /v1/audio/speech. Do not send them to /v1/responses, /v1/messages, or legacy /v1/text:synthesize. Use a separate conversational or reasoning model to write the answer before passing final text to TTS.
- When moving from
gemini-3.1-flash-tts-preview, prefer Flash-Lite for throughput or Flash for creative quality. For new work replacinggemini-2.5-flash-tts/gemini-2.5-pro-tts, select the same way, but migrate the request schema and endpoint rather than only changing a Vertex model ID. Existing/v1/text:synthesizecalls retain their legacy models and schema. - Treat every input text as a verbatim transcript. Instructions such as
Say cheerfully:and speaker prefixes such asSpeaker 1:may be read aloud. On native GenerateContent requests, putspeechMetadata: {"speaker": "Host", "style": "Warm and welcoming."}on each text part. Every multi-speaker part must identify a configured speaker. Keep sustained delivery directions instyle; reserve inline tags such as<laugh>,<sigh>, and<short pause>for momentary vocal events. - Native unary 3.8 responses default to WAV (
audio/wav) with a RIFF header. InspectinlineData.mimeType: save decoded WAV bytes directly; wrap onlyaudio/L16headerless PCM16 at 24000 Hz, mono. Never add a second WAV header. The native example handles both types. - Chat Completions uses
audio.format, not Speech'sresponse_format. Requestpcm16, decodechoices[0].message.audio.data, and convert raw PCM withffmpeg -f s16le -ar 24000 -ac 1 -i speech.pcm speech.wav. Do not decodemessage.contentas audio or remove arbitrary prefixes from Base64. gemini-3.1-flash-tts-previewsupports only PCM16 output: on/v1/audio/speech, requestresponse_format: "pcm", save a raw file, and convert it. Saving those bytes asspeech.mp3does not make an MP3 file.
curl --fail-with-body -sS https://api.avalai.ir/v1/audio/speech \
-H "Authorization: Bearer $AVALAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.1-flash-tts-preview",
"voice": "Zephyr",
"input": "Have a wonderful day!",
"response_format": "pcm"
}' \
--output legacy-speech.pcm
ffmpeg -f s16le -ar 24000 -ac 1 -i legacy-speech.pcm legacy-speech.mp3Voice and Style
- OpenAI-compatible voices include
alloy,ash,ballad,coral,echo,fable,nova,onyx,sage,shimmer,verse,marin, andcedar; availability can vary by model. - For OpenAI-compatible TTS quality reviews, start with
marinorcedar, then test alternatives for brand fit, language, and latency. gpt-audio-1.5,gpt-audio, andgpt-audio-miniare the current OpenAI-compatible speech models; the deprecatedtts-1,tts-1-hd, andgpt-4o-mini-ttsare no longer available.- Provider-specific voices, such as ElevenLabs, Gemini, and PlayAI voices, may have different names and limits. Check provider docs when a voice fails.
- Disclose to end users when a voice is AI-generated.
Language and Pronunciation Checks
OpenAI-compatible TTS can speak many languages, but built-in voices may be optimized differently by provider and language. Before shipping a voice workflow:
- Test the exact target languages, including Persian, with real product phrases and user names.
- Keep pronunciation hints, glossary terms, numbers, and abbreviations consistent across chunks.
- Prefer
wavorpcmfor low-latency playback tests; prefermp3when storage and broad playback compatibility matter. - Review generated speech with native speakers for brand tone, pronunciation, pacing, and accessibility.
- Log model, voice, language, style instructions, response format, and latency so regressions are traceable.
Custom Voice Availability
OpenAI documents consent-backed custom voices for eligible OpenAI customers, including separate consent and sample recordings. AvalAI does not expose those voice creation endpoints as a general public feature today. Use built-in voices or provider-specific voice IDs unless AvalAI announces custom voice support for your account. If you record or clone voices through any provider, keep explicit consent, disclosure, and audit records with the generated audio workflow.
Output Formats
| Format | Use for |
|---|---|
mp3 | Default, compact, broad compatibility. |
opus | Internet streaming and low-latency communication. |
aac | Mobile and media-platform compatibility. |
flac | Lossless archive workflows. |
wav | Low-latency playback without compressed decoding. |
pcm | Raw audio pipelines and realtime playback systems. |
Use wav or pcm when playback should start quickly. Use mp3 when storage size matters.
Streaming Playback
The speech endpoint can stream response bytes so your app does not need to wait for the full file before playback or forwarding to a client.
OpenAI-compatible speech generation also exposes stream_format for supported models. Use the default binary audio stream for simple playback or file writes; use stream_format: "sse" only when your route supports event-style streaming and you want to process audio events as they arrive.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
with client.audio.speech.with_streaming_response.create(
model="gpt-audio-1.5",
voice="alloy",
input="This response can be played as it is generated.",
response_format="wav",
) as response:
response.stream_to_file("stream.wav")import fs from "node:fs";
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.AVALAI_API_KEY,
baseURL: "https://api.avalai.ir/v1",
});
const response = await client.audio.speech.create({
model: "gpt-audio-1.5",
voice: "alloy",
input: "This response can be played as it is generated.",
response_format: "wav",
});
const output = fs.createWriteStream("stream.wav");
output.write(Buffer.from(await response.arrayBuffer()));
output.end();Long Text
- OpenAI-compatible TTS accepts up to 4,096 characters per
input; provider-specific models may set lower or higher practical limits. - Split long scripts into sections by paragraph, slide, or scene.
- Keep speaker names, pronunciation hints, and style instructions consistent across chunks.
- Add short pauses or sound design in your application rather than forcing them into one huge request.
- Store generated chunk filenames with ordering metadata so you can reassemble or retry safely.
Pair TTS with Responses
Use /v1/responses to write, transform, summarize, or tool-check text first, then send response.output_text to /v1/audio/speech.
import os
from pathlib import Path
from openai import OpenAI
client = OpenAI(
api_key=os.environ["AVALAI_API_KEY"],
base_url="https://api.avalai.ir/v1",
)
script = client.responses.create(
model="gpt-5.6-luna",
instructions="Write a concise spoken product update.",
input="Explain that AvalAI supports OpenAI-compatible SDKs and many providers.",
)
with client.audio.speech.with_streaming_response.create(
model="gpt-audio-1.5",
voice="coral",
input=script.output_text,
) as speech:
speech.stream_to_file(Path("update.mp3"))Chat Completions Audio
If you need one model call to return text and audio together, use an audio-capable chat model such as gpt-audio-mini, gpt-audio, or gpt-audio-1.5 with /v1/chat/completions. If your workflow mostly needs text reasoning, tools, or state, use Responses first and TTS second.
Best Practices
- Use
gpt-audio-1.5when voice quality and style control matter; usegpt-audio-minifor high-volume or cost-sensitive workloads. - Use
speedcarefully for narration and accessibility. OpenAI-compatible Speech accepts0.25to4.0, but user comprehension often degrades before technical limits are reached. - Choose provider-specific voices only after testing language, pronunciation, latency, and licensing requirements.
- Log model, voice, format, input length, latency, and output size.
- Cache static narration so repeated playback does not regenerate the same audio.
- Never commit API keys; read
AVALAI_API_KEYfrom the environment.