Developers · Beta
Put Indian-language voice in your product
Text to speech, speech to text, translation and voice conversion through one simple HTTP API — the same engine and the same credits as the SynVoice AI app.
Quickstart
- 1. Get a key. Sign in, open API keys, give it a name, choose what it may do, and copy it. It is shown once.
- 2. Note the address. Requests go to
https://YOUR-API-HOST/api/v1. The hosted address is shared with beta participants; until then, use the address your Synvertix contact gave you. - 3. Make a request.
curl https://YOUR-API-HOST/api/v1/tts \
-H "Authorization: Bearer $SYNVOICE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "నమస్కారం, SynVoice కి స్వాగతం", "language": "te"}'The response contains the audio as a base64 data URL. Generated audio carries the provenance_id in its file metadata so it can be traced; please keep it, and tell your audience when audio is AI-generated.
{
"status": "ok",
"provider": "sarvam",
"text": "నమస్కారం, SynVoice కి స్వాగతం",
"language": "te",
"voice": "default",
"provenance_id": "ffaba8c22f304ddca4f15d5555710200",
"audio_url": "data:audio/wav;base64,UklGRn...",
"usage": { "unit": "characters", "amount": 29 }
}SDKs
Small, dependency-free clients for Python (3.9+) and JavaScript (Node 18+), tested on Python 3.13 and Node 24. They handle authentication, decoding audio, error types and retrying when you are rate limited. The SDKs are in the sdk/ folder of the project; they are not on PyPI or npm yet, so install them from that folder for now.
from synvoice import SynVoice
client = SynVoice() # reads SYNVOICE_API_KEY and SYNVOICE_BASE_URL
client.tts("नमस्ते, SynVoice में आपका स्वागत है", language="hi").save("hello.wav")
print(client.transcribe("hello.wav").text)
print(client.translate("Good morning", "hi-IN").text)
print("credits left:", client.balance())import { SynVoice } from "synvoice";
import { writeFile } from "node:fs/promises";
const client = new SynVoice(); // reads SYNVOICE_API_KEY and SYNVOICE_BASE_URL
const speech = await client.tts("வணக்கம், SynVoice க்கு வரவேற்கிறோம்", "ta");
await writeFile("hello.wav", speech.toBuffer());
console.log((await client.translate("Good morning", "hi-IN")).text);
console.log("credits left:", await client.balance());Authentication
Send your key as a bearer token on every request: Authorization: Bearer sk_synvoice_live_…
- Keep it on your server. Anyone with the key can spend your credits. Never put it in a web page, mobile app or public repository.
- Scopes. Each key is limited to the endpoints you choose when you create it (Text to Speech, Speech to Text, Translation, Voice Conversion).
- Whose credits. A key spends either your personal credits or — if you are a workspace owner or admin — a workspace's shared pool. Usage is shown per key on the API keys page.
- Rotate and revoke. Replace a key if it may have leaked; revoking takes effect immediately. Keys can be set to expire.
- We store a fingerprint, not your key. We cannot show it again or recover it.
Endpoints
All paths are relative to https://YOUR-API-HOST/api/v1. Requests and responses are JSON.
| Endpoint | Key permission | What it does | Cost |
|---|---|---|---|
| GET/balance | any key | Credits left on the account this key spends from | Free |
| GET/tts/voices | tts | List the available voices | Free |
| POST/tts | tts | Turn text into speech (WAV audio) | 1 credit per character |
| POST/tts/multi-speaker | tts | Several speakers in one audio file | 1 credit per character |
| POST/stt | stt | Transcribe audio to text | 3 credits per second of audio |
| POST/translate | translate | Translate text between Indian languages and English | 1 credit per character |
| GET/voice-conversion/voices | voice-conversion | List the voices audio can be converted into | Free |
| POST/voice-conversion | voice-conversion | Change who a recording sounds like | 64 credits per second of audio |
POST /tts
text (required, up to 2,500 characters), language (te hi en ta kn ml mr bn gu pa od), voice (an id from /tts/voices, default "default"), speed (0.5–2.0), expressiveness (0.01–1.0). Returns audio_url, a base64 WAV data URL.
POST /stt
audio_base64 (required; WAV, MP3, OGG, WebM and other common formats), language_code (optional; unknown auto-detects). Best for clips up to about 30 seconds. Returns transcript, language_code and usage.amount in seconds.
POST /translate
text (up to 2,000 characters), target_language_code such as hi-IN, optional source_language_code (default auto) and mode (formal, modern-colloquial, classic-colloquial, code-mixed). Returns translated_text.
POST /voice-conversion
audio_base64 (up to about 15 MB and 5 minutes) and target_voice_id (from /voice-conversion/voices). Returns the converted audio_url.
POST /tts/multi-speaker
segments: a list of up to 10 { text, language, voice } items (each up to 2,500 characters), plus optional speed and expressiveness. Returns one merged audio_url and the individual segments.
Credits
The API bills the same credits as the app — see the cost column above and the pricing page. Credits are only deducted after a request succeeds; a failed or rate-limited request costs nothing. Call GET /balance to check what is left.
Errors
Errors use normal HTTP status codes and a JSON body with a human-readable message and, where it helps, a machine-readable code.
{
"message": "Not enough credits for this request. Please top up or upgrade your plan.",
"code": "INSUFFICIENT_CREDITS",
"balance": 12,
"required": 29
}| HTTP | Code | Meaning |
|---|---|---|
| 401 | INVALID_API_KEY | The key is missing, wrong, revoked, expired or its owner is suspended. We deliberately don't say which. |
| 402 | INSUFFICIENT_CREDITS | Not enough credits. Top up on the Billing page, then retry. |
| 403 | API_KEY_SCOPE_DENIED | The key isn't allowed to use this endpoint. The response names the scope it needs. |
| 403 | WORKSPACE_FORBIDDEN | A workspace key whose creator is no longer a member of that workspace. |
| 422 | — | The request was invalid (missing field, text too long…). The message says which. |
| 429 | RATE_LIMITED | Too many requests. Wait for the Retry-After seconds. Nothing was charged. |
| 503 | PROVIDER_UNAVAILABLE | The speech provider is temporarily unavailable. Nothing was charged; retry shortly. |
Rate limits
Each key can make 60 requests per minute. Every response carries X-RateLimit-Limit and X-RateLimit-Remaining; when you run out you get a 429 with a Retry-After header (seconds). Repeated requests with invalid keys from one address are throttled too. Need more? Contact us.
What the API doesn't do yet
We'd rather tell you now than have you find out later. This is a beta.
- Only live keys — there is no free sandbox or test key. Use small requests while integrating.
- Audio travels inside JSON as base64 (no separate file upload, streaming or download URLs).
- Requests are synchronous: no background jobs or webhooks. Long recordings should be split.
- Voice cloning and dubbing are available in the app but not through the API.
- No official SDK packages on PyPI/npm yet, and no OpenAPI file — this page is the reference.
Questions or something not working? Write to support@synvoiceai.com.