TTS quickstart
Install, authenticate, synthesize. By the end of this page you'll have an MP3 on disk and know how to switch voice, language, speed, and format.
The examples below send Authorization: Bearer $ACCESS_TOKEN. The speech APIs accept only a short-lived access token — never your API key directly.
From the console (recommended). Open the console, click Generate token next to your API key, and copy it — then set it:
export ACCESS_TOKEN="eyJhbGciOiJSUzI1NiIs…paste-here"Or mint it from your API key — the path for production, where your app refreshes the token as it nears expiry (the response carries expires_in):
export ACCESS_TOKEN=$(curl -s -X POST https://app.shunyalabs.ai/api/auth/token \
-H "api-key: $SHUNYALABS_API_KEY" | jq -r .token)1. Install the SDK (optional)
pip install "shunyalabs[TTS]" # TTS only
pip install "shunyalabs[all]" # TTS + ASR + everything
pip install "shunyalabs[extras]" # + audio playback helpers (sounddevice)You can also call the REST API directly with requests or any HTTP client, the SDK is just a thin wrapper.
2. Configure authentication
export SHUNYALABS_API_KEY="sk-your-key"Or pass it in code:
client = AsyncShunyaClient(api_key="sk-your-key")3. First synthesis
curl -X POST https://ttsv2.shunyalabs.ai/v1/audio/speech \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"model": "zero-indic", "input": "Hello, how are you today?", "voice": "Varun"}' \
--output output.mp3import asyncio
from shunyalabs import AsyncShunyaClient
from shunyalabs.tts import TTSConfig
async def main():
async with AsyncShunyaClient() as client:
result = await client.tts.synthesize(
"Hello, how are you today?",
config=TTSConfig(model="zero-indic", voice="Varun"),
)
result.save("output.mp3")
print(f"{len(result.audio_data)} bytes saved, {result.sample_rate} Hz")
asyncio.run(main())import requests
response = requests.post(
"https://ttsv2.shunyalabs.ai/v1/audio/speech",
headers={"Authorization": f"Bearer {ACCESS_TOKEN}"},
json={"model": "zero-indic", "input": "Hello!", "voice": "Varun"},
timeout=120,
)
response.raise_for_status()
with open("output.mp3", "wb") as f:
f.write(response.content)from openai import OpenAI
client = OpenAI(api_key=API_KEY, base_url="https://ttsv2.shunyalabs.ai/v1")
response = client.audio.speech.create(
model="zero-indic",
input="Hello!",
voice="Varun",
response_format="mp3",
)
response.stream_to_file("output.mp3")4. Switch voice, language, speed, format
Pick a different voice
# Hindi female
TTSConfig(model="zero-indic", voice="Sunita")
# Tamil male
TTSConfig(model="zero-indic", voice="Murugan")
# English female
TTSConfig(model="zero-indic", voice="Nisha")46 voices total. See Voices & languages for the full catalogue.
Change speed
TTSConfig(model="zero-indic", voice="Nisha", speed=1.3) # fast notifications
TTSConfig(model="zero-indic", voice="Nisha", speed=0.85) # slower dictationChange output format
TTSConfig(model="zero-indic", voice="Varun", response_format="pcm") # real-time playback
TTSConfig(model="zero-indic", voice="Varun", response_format="mulaw") # telephony
TTSConfig(model="zero-indic", voice="Varun", response_format="wav") # editingFull format list at Audio formats.
Add an expression style
await client.tts.synthesize(
"<Happy> Welcome aboard!",
config=TTSConfig(model="zero-indic", voice="Sunita"),
)11 styles: Happy, Sad, Angry, Fearful, Surprised, Disgust, News, Conversational, Narrative, Enthusiastic, Neutral. See Expression styles.
5. Stream it
For real-time use (voice agents, IVR), stream audio as it synthesizes instead of waiting for the full file:
config = TTSConfig(model="zero-indic", voice="Varun", response_format="pcm")
async for chunk in await client.tts.stream("Hello!", config=config):
# play chunk bytes as they arrive
speaker.write(chunk)Full streaming details at Streaming.
6. Handle errors
from shunyalabs.exceptions import (
AuthenticationError, RateLimitError,
SynthesisError, ServerError, ShunyalabsError,
)
try:
result = await client.tts.synthesize("Hello!", config=config)
except AuthenticationError:
print("Invalid API key")
except RateLimitError:
print("Rate limited, back off and retry")
except SynthesisError as e:
print(f"Bad input: {e}")
except ServerError:
print("Server error, safe to retry")
except ShunyalabsError as e:
print(f"SDK error: {e}")