Agent-readable docs index: /llms.txt. Download /docs.zip to grep all markdown files locally.

Python SDK

The official Python SDK (vakyamai) wraps the public TTS API: listing voices, synthesizing speech, HTTP streaming, and realtime WebSocket synthesis.

Install

pip install vakyamai
Requires Python 3.10+. The websockets package is installed automatically and is used for realtime synthesis.

Create a client

The client reads VAKYAM_API_KEY from the environment by default:
from vakyamai import VakyamAI client = VakyamAI()
You can also pass the key explicitly:
client = VakyamAI(api_key="vak_live_...")
Precedence: an api_key= argument overrides VAKYAM_API_KEY.
The client supports use as a context manager:
with VakyamAI() as client: ...
For streaming and realtime WebSocket synthesis, an async client AsyncVakyamAI is also available — use it with async with and await:
from vakyamai import AsyncVakyamAI async with AsyncVakyamAI() as client: ...

List voices

voices = client.voices.list(group_by="language") # or group_by="voice"

Generate speech

response = client.tts.generate( text="வணக்கம், நான் வாக்யம் AI பேசுகிறேன்.", model_id="raaga-v1", voice="Archana", language="ta-IN", output_format="mp3", # mp3 | wav | pcm | mulaw, default mp3 sample_rate=24000, # 8000 | 16000 | 24000 | 48000, default 24000 speed=1.0, # 0.5 - 2.0, default 1.0 ) response.save("speech.mp3") print(response.duration_seconds, response.characters_used)
All arguments are keyword-only. output_format, sample_rate, and speed are optional and are also accepted by stream, stream_to_bytes, and websocket.
voice accepts a preset name (e.g. "Archana") or a custom voice ID beginning with vc_ (e.g. voice="vc_01EXAMPLE").
The returned SpeechResponse exposes:
AttributeTypeDescription
audiobytesDecoded audio bytes.
audio_base64strThe raw base64 field from the API.
formatstrOutput format of the audio.
duration_secondsfloatDuration of the audio.
characters_usedintCredits consumed.
save(path)methodWrite audio to a file.

HTTP streaming

Iterate over raw byte chunks:
with open("speech.pcm", "wb") as file: for chunk in client.tts.stream( text="வணக்கம்.", model_id="raaga-v1", voice="Archana", language="ta-IN", output_format="pcm", ): file.write(chunk)
Or collect the full stream plus metadata in one call:
streamed = client.tts.stream_to_bytes( text="வணக்கம்.", model_id="raaga-v1", voice="Archana", language="ta-IN", ) streamed.save("speech.pcm") print(streamed.metadata.characters_used)

WebSocket

The session config (model, voice, language, format, speed) is sent before any text — websocket(...) opens the connection and sends the config message on entry, so every synthesize call after it uses that config.
# Opens the connection and sends the config message first with client.tts.websocket( model_id="raaga-v1", voice="Archana", language="ta-IN", output_format="pcm", ) as ws: # Then send text — one complete sentence per call result = ws.synthesize("நான் சரியாக இருக்கிறேன்.") result.save("sentence.pcm")
Send one complete sentence per synthesize call. See the realtime guide.
synthesize returns a WebSocketSpeechResult with audio (bytes), characters_used, duration_seconds, truncated, truncation_reason, cancelled, and a save(path) method.

Interrupting an utterance (barge-in)

Call ws.cancel() to interrupt the current utterance. It sends a cancel, drains any remaining audio, and returns the terminal WebSocketSpeechResult (with cancelled=True). It is safe to call cancel() from another thread while synthesize() is running; you are billed only for audio produced before the cancel.
result = ws.cancel() print(result.cancelled, result.characters_used)
The server closes idle connections after 60 seconds without an incoming message. The SDK sends a keepalive ping while the session is open; you can also ping explicitly between utterances, which resets the server's idle timer:
ws.ping()

Error handling

The SDK maps the API error envelope into typed exceptions:
from vakyamai import RateLimitError, ValidationError try: client.tts.generate( text="...", model_id="raaga-v1", voice="Archana", language="ta-IN", ) except RateLimitError as exc: print("retry after", exc.retry_after_seconds) except ValidationError as exc: print(exc.code, exc.message)
Available exception classes:
  • AuthenticationError
  • InsufficientCreditsError
  • ConcurrencyLimitError — too many concurrent synthesis requests for the account
  • RateLimitError — exposes retry_after_seconds
  • ValidationError
  • ServiceUnavailableError — no worker was available to synthesize (HTTP 503)
  • APIError — base for API responses, exposes status_code, code, message
  • APIConnectionError — raised when the API cannot be reached