TTS Stream
curl --request POST \
--url https://api.vachana.ai/api/v1/tts/sse \
--header 'Content-Type: application/json' \
--header 'X-API-Key-ID: <api-key>' \
--data '
{
"text": "नमस्ते, आप कैसे हैं?",
"model": "timbre-v2.5",
"audio_config": {
"encoding": "linear_pcm",
"container": "wav",
"num_channels": 1,
"sample_rate": 48000,
"sample_width": 2
}
}
'import requests
url = "https://api.vachana.ai/api/v1/tts/sse"
payload = {
"text": "नमस्ते, आप कैसे हैं?",
"model": "timbre-v2.5",
"audio_config": {
"encoding": "linear_pcm",
"container": "wav",
"num_channels": 1,
"sample_rate": 48000,
"sample_width": 2
}
}
headers = {
"X-API-Key-ID": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key-ID': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
text: 'नमस्ते, आप कैसे हैं?',
model: 'timbre-v2.5',
audio_config: {
encoding: 'linear_pcm',
container: 'wav',
num_channels: 1,
sample_rate: 48000,
sample_width: 2
}
})
};
fetch('https://api.vachana.ai/api/v1/tts/sse', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));"event: start\ndata: {\"status\": \"streaming_started\", \"text\": \"Hello\"}\n\nevent: chunk\ndata: {\"chunk_index\": 1, \"audio\": \"<base64>\", \"is_final\": false}\n\nevent: complete\ndata: {\"chunk_index\": 2, \"audio\": \"\", \"is_final\": true}"{
"success": false,
"error": {
"type": "INVALID_REQUEST_ERROR",
"message": "Invalid text or audio configuration."
}
}{
"success": false,
"error": {
"type": "FORBIDDEN",
"message": "You do not have permission to access this resource. Check your API key, organization status, or available credits."
}
}{
"success": false,
"error": {
"type": "RATE_LIMIT_ERROR",
"message": "Rate limit exceeded. Please try again later."
}
}{
"success": false,
"error": {
"type": "API_ERROR",
"message": "An unexpected error occurred while processing."
}
}{
"success": false,
"error": {
"type": "SERVICE_UNAVAILABLE",
"message": "Text-to-speech service is temporarily unavailable."
}
}Text-to-Speech
Text-to-Speech (Streaming)
Stream audio in chunks as it’s generated via Server-Sent Events.
POST
/
api
/
v1
/
tts
/
sse
TTS Stream
curl --request POST \
--url https://api.vachana.ai/api/v1/tts/sse \
--header 'Content-Type: application/json' \
--header 'X-API-Key-ID: <api-key>' \
--data '
{
"text": "नमस्ते, आप कैसे हैं?",
"model": "timbre-v2.5",
"audio_config": {
"encoding": "linear_pcm",
"container": "wav",
"num_channels": 1,
"sample_rate": 48000,
"sample_width": 2
}
}
'import requests
url = "https://api.vachana.ai/api/v1/tts/sse"
payload = {
"text": "नमस्ते, आप कैसे हैं?",
"model": "timbre-v2.5",
"audio_config": {
"encoding": "linear_pcm",
"container": "wav",
"num_channels": 1,
"sample_rate": 48000,
"sample_width": 2
}
}
headers = {
"X-API-Key-ID": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key-ID': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
text: 'नमस्ते, आप कैसे हैं?',
model: 'timbre-v2.5',
audio_config: {
encoding: 'linear_pcm',
container: 'wav',
num_channels: 1,
sample_rate: 48000,
sample_width: 2
}
})
};
fetch('https://api.vachana.ai/api/v1/tts/sse', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));"event: start\ndata: {\"status\": \"streaming_started\", \"text\": \"Hello\"}\n\nevent: chunk\ndata: {\"chunk_index\": 1, \"audio\": \"<base64>\", \"is_final\": false}\n\nevent: complete\ndata: {\"chunk_index\": 2, \"audio\": \"\", \"is_final\": true}"{
"success": false,
"error": {
"type": "INVALID_REQUEST_ERROR",
"message": "Invalid text or audio configuration."
}
}{
"success": false,
"error": {
"type": "FORBIDDEN",
"message": "You do not have permission to access this resource. Check your API key, organization status, or available credits."
}
}{
"success": false,
"error": {
"type": "RATE_LIMIT_ERROR",
"message": "Rate limit exceeded. Please try again later."
}
}{
"success": false,
"error": {
"type": "API_ERROR",
"message": "An unexpected error occurred while processing."
}
}{
"success": false,
"error": {
"type": "SERVICE_UNAVAILABLE",
"message": "Text-to-speech service is temporarily unavailable."
}
}Overview
Receive audio in chunks as it’s generated, allowing playback to start immediately. Reduces latency compared to TTS REST. For the lowest latency, see TTS Realtime.Passing numbers, IDs, dates, or currency as raw strings causes mispronunciations. See the Input Formatting Guide for correct formatting of phone numbers, account numbers, PINs, Aadhaar, vehicle registration numbers, GSTIN, currency, and more.
Models
| Model | model value | Languages | Extra parameters |
|---|---|---|---|
| Timbre v2.5 | timbre-v2.5 | 10 Indian languages | language, speed |
Timbre v2.5 is now the recommended TTS model. Migrate from Timbre v2.0 to continue receiving the latest improvements. Timbre v2.0 will be deprecated soon.
Endpoint
POST https://api.vachana.ai/api/v1/tts/sse
Authentication
| Header | Required | Description |
|---|---|---|
X-API-Key-ID | Yes | Your Gnani API key |
Request Parameters
{
"text": "नमस्ते, आप कैसे हैं?",
"voice": "Nalini",
"model": "timbre-v2.5",
"language": "hi-IN",
"speed": 1.0,
"audio_config": {
"sample_rate": 48000,
"num_channels": 1,
"sample_width": 2,
"encoding": "linear_pcm",
"container": "wav"
}
}
string
required
The text to synthesize into speech. Pass numbers, dates, and currency as spoken words to avoid mispronunciations — see Input Formatting Guide.
string
required
Set to
timbre-v2.5.string
required
Voice name from the Timbre v2.5 catalog. See the Voice Catalog for preferred voices by language. Example:
Nalini, Kaveri, Deepak.string
required
Language of the input text. Controls text normalization and routing.
| Value | Language |
|---|---|
auto | Auto-detect from script (recommended for mixed content) |
hi-IN | Hindi |
en-IN | English |
ta-IN | Tamil |
te-IN | Telugu |
kn-IN | Kannada |
ml-IN | Malayalam |
mr-IN | Marathi |
pa-IN | Punjabi |
bn-IN | Bengali |
gu-IN | Gujarati |
hi-en | Hinglish (code-mixed Hindi–English) |
number | string
default:"1.0"
Playback speed multiplier. Numeric range:
0.85 (slowest) to 1.15 (fastest). String shortcuts: "slow" = 0.85, "medium" = 1.0, "fast" = 1.15.object
Controls the format of the returned audio.
Show audio_config fields
Show audio_config fields
integer
default:"48000"
Sample rate in Hz. Supported:
8000, 16000, 22050, 24000, 44100, 48000.integer
default:"1"
Number of audio channels.
1 for mono.integer
default:"2"
Sample width in bytes.
2 for 16-bit audio.string
default:"linear_pcm"
Audio encoding format. Options:
linear_pcm, pcm_s16le, pcm_mulaw, pcm_alaw, oggopus. For telephony, prefer container=mulaw or container=alaw over this field — both produce the same output. Use oggopus (or container=ogg) for a playable OGG Opus file. Not required when container is mp3.string
default:"wav"
Output container format. Options:
wav, raw, mp3, ogg, mulaw, alaw. Use ogg for OGG Opus. Use mulaw or alaw for G.711 telephony (forces 8000 Hz).string
default:"128k"
MP3 bitrate. Only used when
container is mp3. Supported: 32k, 64k, 96k, 128k, 192k.Audio Format Reference
container | encoding | Output | sample_rate | bitrate | Content-Type |
|---|---|---|---|---|---|
wav | linear_pcm | WAV file (with header) | 8000–48000 Hz | — | audio/wav |
raw | linear_pcm | Raw 16-bit PCM | 8000–48000 Hz | — | application/octet-stream |
mp3 | — | MP3 file | 8000–48000 Hz | 32k–192k | audio/mpeg |
ogg | — | OGG Opus file | 8000–48000 Hz | — | audio/ogg |
mulaw | — | Raw G.711 µ-law | forced 8000 Hz | — | audio/basic |
alaw | — | Raw G.711 A-law | forced 8000 Hz | — | audio/alaw |
container rows above:
container | encoding | Equivalent to |
|---|---|---|
raw | pcm_mulaw | container=mulaw |
raw | pcm_alaw | container=alaw |
raw or ogg | oggopus | container=ogg |
bitrate only applies when container=mp3. container=mulaw/alaw override sample_rate to 8000 Hz.
When
container=ogg or encoding=oggopus is requested, all audio chunks are encoded into a single OGG Opus file delivered as one chunk — streaming delivery is not possible for OGG.Response
The server streams audio via Server-Sent Events. Eachchunk event carries base64-encoded audio in the audio field. A final complete event signals that synthesis is finished.
event: start
data: {"status": "streaming_started", "text": "नमस्ते, आप कैसे हैं?"}
event: chunk
data: {"chunk_index": 1, "audio": "<base64-encoded audio>", "is_final": false}
event: chunk
data: {"chunk_index": 2, "audio": "<base64-encoded audio>", "is_final": false}
event: complete
data: {"chunk_index": 3, "audio": "", "is_final": true}
| Event | Description |
|---|---|
start | Synthesis has begun. |
chunk | An audio fragment. Decode audio from base64 and append to your buffer in order. |
complete | All audio has been sent. is_final: true, audio is empty. |
error | Synthesis failed. Contains error details when returned by the server. |
Code Example
curl -X POST https://api.vachana.ai/api/v1/tts/sse \
-H "Content-Type: application/json" \
-H "X-API-Key-ID: <your-api-key>" \
-d '{
"text": "नमस्ते, आप कैसे हैं?",
"voice": "Nalini",
"model": "timbre-v2.5",
"language": "hi-IN",
"speed": 1.0,
"audio_config": {
"sample_rate": 48000,
"encoding": "linear_pcm",
"container": "wav"
}
}'
const response = await fetch("https://api.vachana.ai/api/v1/tts/sse", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key-ID": "<your-api-key>",
},
body: JSON.stringify({
text: "नमस्ते, आप कैसे हैं?",
voice: "Nalini",
model: "timbre-v2.5",
language: "hi-IN",
speed: 1.0,
audio_config: {
sample_rate: 48000,
encoding: "linear_pcm",
container: "wav",
},
}),
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
console.log(decoder.decode(value));
}
import requests, base64
response = requests.post(
"https://api.vachana.ai/api/v1/tts/sse",
headers={
"Content-Type": "application/json",
"X-API-Key-ID": "<your-api-key>",
},
json={
"text": "नमस्ते, आप कैसे हैं?",
"voice": "Nalini",
"model": "timbre-v2.5",
"language": "hi-IN",
"speed": 1.0,
"audio_config": {
"sample_rate": 48000,
"encoding": "linear_pcm",
"container": "wav",
},
},
stream=True,
)
for line in response.iter_lines():
if line:
print(line.decode("utf-8"))
Available Voices
42 voices across 10 Indian languages, English, and Hinglish. See the full Voice Catalog for preferred voices by language, gender, persona, and description. Popular examples:Nalini (Hindi), Kaveri (English), Deepak (Hindi), Poorvi (Hinglish).
Python SDK
The SDK’s streaming client handles SSE parsing and chunk reassembly for you — you just iterate and write.Installation
pip install gnani-vachana
Authentication
from gnani.tts import GnaniTTSStreamClient
client = GnaniTTSStreamClient(api_key="your-api-key")
export GNANI_API_KEY="your-api-key"
from gnani.tts import GnaniTTSStreamClient
client = GnaniTTSStreamClient()
Stream Audio to a File
synthesize_stream yields audio chunks as they arrive. Playback or writing can begin before the full response is complete.
from gnani.tts import GnaniTTSStreamClient
client = GnaniTTSStreamClient(api_key="your-api-key")
with open("output.wav", "wb") as f:
for chunk in client.synthesize_stream(
"नमस्ते, आप कैसे हैं?",
voice="Nalini",
model="timbre-v2.5",
language="hi-IN",
):
f.write(chunk)
With Custom Audio Config
from gnani.tts import GnaniTTSStreamClient, AudioConfig
client = GnaniTTSStreamClient(api_key="your-api-key")
with open("output.wav", "wb") as f:
for chunk in client.synthesize_stream(
"नमस्ते, आप कैसे हैं?",
voice="Nalini",
model="timbre-v2.5",
language="hi-IN",
audio_config=AudioConfig(
sample_rate=48000,
encoding="linear_pcm",
container="wav",
),
):
f.write(chunk)
Authorizations
Headers
Body
application/json
Request body for TTS inference.
TTS model. Use timbre-v2.5. Timbre v2.0 is deprecated and will be removed soon.
Available options:
timbre-v2.5 Audio output configuration.
Show child attributes
Show child attributes
Voice name from the Timbre catalog.
Language code. Use auto, hi-IN, en-IN, hi-en, ta-IN, te-IN, kn-IN, ml-IN, mr-IN, pa-IN, bn-IN, or gu-IN.
Playback speed multiplier. Range: 0.85–1.15.
Response
Successful Server-Sent Events stream
The response is of type string.
Was this page helpful?