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

Your quickstart

Get from nothing to a working transcription and a working synthesis in five minutes. You'll need an API key, a short-lived access token minted from it, and about three lines of code per direction.

1. Get an API key

  1. Sign in at accounts.shunyalabs.ai.
  2. Navigate to API Keys and click Create New Key.
  3. Copy the key immediately, it's shown once.
Keep the key out of source control
Store it in a .env file or a secrets manager. Add .env to .gitignore. Rotate if leaked.

Set the environment variable

export SHUNYALABS_API_KEY="sk-your-key-here"
$env:SHUNYALABS_API_KEY = "sk-your-key-here"

2. Generate an access token

The speech APIs accept only a short-lived access token, never the API key itself. Generate one and set it as ACCESS_TOKEN — every call below uses it.

From the console (recommended). In the console, click Generate token next to your API key. It is minted and copied to your clipboard — paste it straight into Postman or a request. This is the fastest way to start.

export ACCESS_TOKEN="eyJhbGciOiJSUzI1NiIs…paste-here"
$env:ACCESS_TOKEN = "eyJhbGciOiJSUzI1NiIs…paste-here"

Or mint it from your API key. For a production integration, exchange the key at the token endpoint and refresh the token as it nears expiry — the response carries expires_in. (A copied console token stops working once it lapses, so build production on this path, not the button.)

shell
# Exchange the key -> {"token": "eyJ...", "expires_in": 900}
curl -X POST https://app.shunyalabs.ai/api/auth/token \
  -H "api-key: $SHUNYALABS_API_KEY"

# Or capture it straight into the env var:
export ACCESS_TOKEN=$(curl -s -X POST https://app.shunyalabs.ai/api/auth/token \
  -H "api-key: $SHUNYALABS_API_KEY" | jq -r .token)
python
import os, requests

auth = requests.post(
    "https://app.shunyalabs.ai/api/auth/token",
    headers={"api-key": os.environ["SHUNYALABS_API_KEY"]},
)
auth.raise_for_status()
access_token = auth.json()["token"]   # reuse until close to expiry
node
const auth = await fetch("https://app.shunyalabs.ai/api/auth/token", {
  method: "POST",
  headers: { "api-key": process.env.SHUNYALABS_API_KEY },
});
const { token: accessToken } = await auth.json();   // reuse until close to expiry

3. Transcribe an audio file

Send audio to POST /v1/audio/transcriptions with your token. The response is a JSON object with the transcript and per-segment timestamps.

shell
curl -X POST https://asrv2prod.shunyalabs.ai/v1/audio/transcriptions \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -F "file=@meeting.wav" \
  -F "model=zero-indic"
python
import os, requests

# 1. Exchange the API key for a short-lived access token. Do this once and reuse the
#    token until it is close to expiry — the response carries expires_in.
auth = requests.post(
    "https://app.shunyalabs.ai/api/auth/token",
    headers={"api-key": os.environ["SHUNYALABS_API_KEY"]},
)
auth.raise_for_status()
access_token = auth.json()["token"]

# 2. Call the API with the token. The API key is never sent to the speech service.
with open("meeting.wav", "rb") as f:
    r = requests.post(
        "https://asrv2prod.shunyalabs.ai/v1/audio/transcriptions",
        headers={"Authorization": f"Bearer {access_token}"},
        files={"file": f},
        data={"model": "zero-indic"},
    )
r.raise_for_status()
print(r.json()["text"])
node
import fs from "node:fs";

const form = new FormData();
form.append("file", new Blob([fs.readFileSync("meeting.wav")]), "meeting.wav");
form.append("model", "zero-indic");

// 1. Exchange the API key for a short-lived access token, once, on your server.
const auth = await fetch("https://app.shunyalabs.ai/api/auth/token", {
  method: "POST",
  headers: { "api-key": process.env.SHUNYALABS_API_KEY },
});
const { token: accessToken } = await auth.json();

// 2. Call the API with the token. The API key never reaches the speech service.
const r = await fetch("https://asrv2prod.shunyalabs.ai/v1/audio/transcriptions", {
  method: "POST",
  headers: { Authorization: `Bearer ${accessToken}` },
  body: form,
});
const data = await r.json();
console.log(data.text);
python
from openai import OpenAI
import os

client = OpenAI(
    # The SDK sends api_key as a Bearer token, so pass the ACCESS_TOKEN from step 2 (not the raw
    # key). Refresh it when it nears expiry.
    api_key=os.environ["ACCESS_TOKEN"],
    base_url="https://asrv2prod.shunyalabs.ai/v1",
)
r = client.audio.transcriptions.create(
    model="zero-indic",
    file=open("meeting.wav", "rb"),
)
print(r.text)

Response

{
  "success": true,
  "request_id": "b3f1a2c4-...",
  "text": "नमस्ते मोहम्मद जी, ये एक ज़रूरी कॉल है।",
  "segments": [
    { "start": 0.51, "end": 5.70, "text": "नमस्ते मोहम्मद जी..." }
  ],
  "detected_language": "Hindi",
  "audio_duration": 5.7,
  "inference_time_ms": 812.3
}

4. Generate speech

Now send text to POST /v1/audio/speech. The response body is audio bytes in your requested format.

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":"Hello, how are you today?","voice":"Varun"}' \
  --output hello.mp3
python
import os, requests

auth = requests.post(
    "https://app.shunyalabs.ai/api/auth/token",
    headers={"api-key": os.environ["SHUNYALABS_API_KEY"]},
)
auth.raise_for_status()
access_token = auth.json()["token"]

r = requests.post(
    "https://ttsv2.shunyalabs.ai/v1/audio/speech",
    headers={"Authorization": f"Bearer {access_token}"},
    json={"model": "zero-indic", "input": "Hello, how are you today?", "voice": "Varun"},
    timeout=120,
)
r.raise_for_status()
with open("hello.mp3", "wb") as f:
    f.write(r.content)
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(
            "Hello, how are you today?",
            config=TTSConfig(model="zero-indic", voice="Varun"),
        )
        result.save("hello.mp3")

asyncio.run(main())

5. Stream in real time

For voice agents and IVR, both ASR and TTS support streaming over WebSocket, see ASR streaming and TTS streaming. You get partial transcripts as speech is happening, and synthesized audio as text is generated.

Quickstart | Shunya Labs Docs