Drop in to existing OpenAI code
Already using the OpenAI Python SDK? Keep your code. Point base_url to Shunya and you instantly gain 23 Indic languages, 46 voices, and on-prem deployment, no rewrites, no new client library.
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)Your journey
Step 1: The two-line swap
Take any working OpenAI TTS call. Change two lines, the base_url and the voice: and you're calling Shunya:
Before: vanilla OpenAI
from openai import OpenAI
client = OpenAI(api_key="sk-openai-...")
response = client.audio.speech.create(
model="tts-1",
input="Hello, how are you today?",
voice="alloy",
response_format="mp3",
)
response.stream_to_file("output.mp3")After: same SDK, Shunya backend
from openai import OpenAI
import os, requests
# swap 0 (auth): the speech APIs take a short-lived token, not the raw key — mint one, pass as api_key
token = requests.post("https://app.shunyalabs.ai/api/auth/token",
headers={"api-key": os.environ["SHUNYALABS_API_KEY"]}).json()["token"]
client = OpenAI(
api_key=token, # ← swap 0 (a minted token, refresh as it expires)
base_url="https://ttsv2.shunyalabs.ai/v1", # ← swap 1
)
response = client.audio.speech.create(
model="zero-indic", # ← swap 2 (model)
input="Hello, how are you today?",
voice="Varun", # ← swap 3 (voice)
response_format="mp3",
)
response.stream_to_file("output.mp3")Step 2: What stays the same
- Client class,
OpenAI/AsyncOpenAIfrom the officialopenaipackage. - Method shape,
client.audio.speech.create(...), same fields. - Response shape,
response.stream_to_file(),response.read(),response.iter_bytes()all work as in OpenAI. - Auth pattern, Bearer token via
api_key; the SDK sets theAuthorizationheader for you. - response_format,
mp3,wav,pcm,flac,ogg_opusall map across. - Error handling,
openai.AuthenticationError,openai.RateLimitError,openai.APIErrorbehave as expected.
Step 3: What changes
| Field | OpenAI value | Shunya value |
|---|---|---|
base_url | https://api.openai.com/v1 | https://ttsv2.shunyalabs.ai/v1 |
model | tts-1 / tts-1-hd | zero-indic |
voice | alloy, echo, nova, ... | Varun, Sunita, Murugan, ... (46 voices) |
api_key | sk-openai-... | A minted access token (from your Shunya key — see above) |
Step 4: Voice mapping cheatsheet
OpenAI ships generic English voices. Shunya gives you native Indic voices that can also speak English (cross-lingual). Pick by language and gender:
| Language | Male | Female |
|---|---|---|
| English | Varun | Nisha |
| Hindi | Rajesh | Sunita |
| Tamil | Murugan | Thangam |
| Telugu | Vishnu | Lakshmi |
| Bengali | Arjun | Priyanka |
| Marathi | Siddharth | Ananya |
| Gujarati | Rakesh | Pooja |
| Kannada | Kiran | Shreya |
| Malayalam | Krishnan | Deepa |
| Punjabi | Gurpreet | Simran |
See the full voice list for all 23 languages × 2 genders = 46 voices, plus details on cross-lingual synthesis (any voice, any language).
Step 5: Async + streaming with the OpenAI SDK
from openai import AsyncOpenAI
client = AsyncOpenAI(
api_key=os.environ["ACCESS_TOKEN"],
base_url="https://ttsv2.shunyalabs.ai/v1",
)
async with client.audio.speech.with_streaming_response.create(
model="zero-indic",
input="Hello, how are you today?",
voice="Sunita",
response_format="pcm",
) as response:
async for chunk in response.iter_bytes():
play(chunk) # bytes arrive as the model generates themStep 6: Pipeline: GPT-4 → Shunya TTS
Use one OpenAI client for the LLM, a second OpenAI client (pointed at Shunya) for TTS. Stream tokens, flush at sentence boundaries:
from openai import AsyncOpenAI
oai = AsyncOpenAI() # default OpenAI base_url
shunya = AsyncOpenAI(base_url="https://ttsv2.shunyalabs.ai/v1",
api_key=os.environ["ACCESS_TOKEN"])
buffer = ""
stream = await oai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Tell me a story"}],
stream=True,
)
async for chunk in stream:
token = chunk.choices[0].delta.content or ""
buffer += token
if token in (".", "!", "?", ";") and len(buffer) > 15:
async with shunya.audio.speech.with_streaming_response.create(
model="zero-indic", input=buffer, voice="Sunita", response_format="pcm",
) as resp:
async for audio in resp.iter_bytes():
play(audio)
buffer = ""Step 7: Why teams choose this path
If your codebase already uses the OpenAI SDK, the swap is two lines. No new dependencies, no rewrites, no team retraining.
Same SDK ergonomics, but with 23 Indic languages, on-prem deployment, and HIPAA / DPDP / GDPR compliance baked in.
Keep OpenAI for English-only paths, route Indic and regulated traffic to Shunya, both via the same client class.
Predictable per-minute pricing vs. variable token billing. CPU-only inference for air-gapped environments.
reference_wav), background audio mixing, word-level timestamps, that aren't in the OpenAI surface.