Shunya Labs DocsShunya Labs Docs
🌐 International
🇺🇸 English
🇯🇵 Japanese
🇨🇳 Chinese (Simplified)
🇹🇼 Chinese (Traditional)
🇸🇦 Arabic
🇩🇪 German
🇫🇷 French
🇪🇸 Spanish
🇧🇷 Portuguese
🇷🇺 Russian
🇰🇷 Korean
🇹🇷 Turkish
🇻🇳 Vietnamese
🇮🇩 Indonesian
🇮🇳 Hindi Belt
हिन्दी — Hindi
भोजपुरी — Bhojpuri
मैथिली — Maithili
राजस्थानी — Rajasthani
🇮🇳 South India
தமிழ் — Tamil
తెలుగు — Telugu
ಕನ್ನಡ — Kannada
മലയാളം — Malayalam
🇮🇳 West India
मराठी — Marathi
ગુજરાતી — Gujarati
कोंकणी — Konkani
🇮🇳 East India
বাংলা — Bengali
ଓଡ଼ିଆ — Odia
অসমীয়া — Assamese
🇮🇳 North-East India
মেইতেই — Meitei
नेपाली — Nepali
🇮🇳 North India
ਪੰਜਾਬੀ — Punjabi
اردو — Urdu
کٲشُر — Kashmiri
डोगरी — Dogri
سنڌي — Sindhi

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.

First: get an access token

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 "shunyalabsai[TTS]"         # TTS only
pip install "shunyalabsai[all]"         # TTS + ASR + everything
pip install "shunyalabsai[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

shell
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": "नमस्ते, आप कैसे हैं?", "voice": "Varun", "language": "hi"}' \
  --output output.mp3
python
import asyncio
from shunyalabs import AsyncShunyaClient
from shunyalabs.tts import TTSConfig

async def main():
    async with AsyncShunyaClient() as client:
        result = await client.tts.synthesize(
            "नमस्ते, आप कैसे हैं?",
            config=TTSConfig(model="zero-indic", voice="Varun", language="hi"),
        )
        result.save("output.mp3")
        print(f"{len(result.audio_data)} bytes saved, {result.sample_rate} Hz")

asyncio.run(main())
python
import requests

response = requests.post(
    "https://ttsv2.shunyalabs.ai/v1/audio/speech",
    headers={"Authorization": f"Bearer {ACCESS_TOKEN}"},
    json={"model": "zero-indic", "input": "नमस्ते, आप कैसे हैं?", "voice": "Varun", "language": "hi"},
    timeout=120,
)
response.raise_for_status()
with open("output.mp3", "wb") as f:
    f.write(response.content)
python
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="नमस्ते, आप कैसे हैं?",
    voice="Varun",
    response_format="mp3",
    # OpenAI's client has no native language field — pass it through extra_body
    extra_body={"language": "hi"},
)
response.stream_to_file("output.mp3")
Always pass language
The language field selects the correct language and pronunciation for your text. It's required for non-English text and for languages that share a script — for example Hindi and Marathi are both written in Devanagari, so without language the service can't tell them apart. Use the ISO 639 code (hi, en, mr, ta, …).

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 dictation

Change 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")    # editing

Full 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}")
You're done
You now have text → audio working. Next, skim voices and audio formats to pick the right ones for your use case.
TTS quickstart | Shunya Labs Docs