> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gnani.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Text-to-Speech (REST)

> Synchronous text-to-speech with full audio returned in one response.

<Info>
  **Currently in beta.** You're on the priority waitlist and among the first to get access.
</Info>

## Overview

Get the complete synthesized audio in one response. Best for downloads or batch processing. For streaming playback, see [TTS Streaming](/vachana/TTS/tts-sse) or [TTS Realtime](/vachana/TTS/tts-websocket).

<Note>
  Passing numbers, IDs, dates, or currency as raw strings causes mispronunciations. See the [Input Formatting Guide](/vachana/TTS/tts-input-formating) for correct formatting of phone numbers, account numbers, PINs, Aadhaar, vehicle registration numbers, GSTIN, currency, and more.
</Note>

## Available Voices

To see the available voices, [click here](/api/TTS/available-voices).

## Endpoint

```text theme={null}
POST https://api.vachana.ai/api/v1/tts/inference
```

## Authentication

All requests require the following headers:

| Header         | Required | Description                     | Example             |
| -------------- | -------- | ------------------------------- | ------------------- |
| `Content-Type` | Yes      | Must be `application/json`      | `application/json`  |
| `X-API-Key-ID` | Yes      | Your API key for authentication | `<your-api-key-id>` |

## Request Parameters

Send a JSON body with the following structure:

```json theme={null}
{
  "text": "नमस्ते, आप कैसे हैं?",
  "voice": "Pranav",
  "model": "Timbre v2.0 / Timbre v2.5",
  "audio_config": {
    "sample_rate": 48000,
    "num_channels": 1,
    "sample_width": 2,
    "encoding": "linear_pcm",
    "container": "wav"
  }
}
```

<ParamField body="text" type="string" required>
  The text to synthesize into speech. Pass numbers, dates, and currency as spoken words to avoid mispronunciations — see [Input Formatting Guide](/vachana/TTS/tts-input-formating).
</ParamField>

<ParamField body="model" type="string" required>
  TTS model to use. Currently supported: `Timbre v2.0 / Timbre v2.5`
</ParamField>

<ParamField body="voice" type="string">
  ID of a pre-defined voice. See [Available Voices](/api/TTS/available-voices)
</ParamField>

<ParamField body="sample_rate" type="integer" default="48000">
  Sample rate in Hz. Supported: `8000`, `16000`, `22050`, `24000`, `44100`, `48000`.
</ParamField>

<ParamField body="num_channels" type="integer" required>
  Number of audio channels (e.g., `1` for mono, `2` for stereo)
</ParamField>

<ParamField body="sample_width" type="integer" required>
  Sample width in bytes (e.g., `2` for 16-bit audio)
</ParamField>

<ParamField body="encoding" type="string" default="linear_pcm">
  Audio encoding. 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.
</ParamField>

<ParamField body="container" type="string" default="wav">
  Output container. Options: `wav`, `raw`, `mp3`, `ogg`, `mulaw`, `alaw`. Use `ogg` for OGG Opus. Use `mulaw` or `alaw` for G.711 telephony (forces 8000 Hz regardless of `sample_rate`).
</ParamField>

<ParamField body="bitrate" type="string" default="128k">
  MP3 bitrate. Only used when `container` is `mp3`. Supported: `32k`, `64k`, `96k`, `128k`, `192k`.
</ParamField>

## 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`               |

**Encoding aliases** — produce identical output to the `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.

## Response

A successful request returns `200 OK` with raw binary audio in the format specified by `audio_config.container` (for example `audio/wav`, `audio/mpeg`, or `audio/ogg`).

## Code Example

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.vachana.ai/api/v1/tts/inference \
    -H "Content-Type: application/json" \
    -H "X-API-Key-ID: <your-api-key>" \
    -d '{
      "text": "नमस्ते, आप कैसे हैं?",
      "voice": "Pranav",
      "model": "Timbre v2.0 / Timbre v2.5",
      "audio_config": {
        "sample_rate": 48000,
        "num_channels": 1,
        "sample_width": 2,
        "encoding": "linear_pcm",
        "container": "wav"
      }
    }' \
    --output response.wav
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.vachana.ai/api/v1/tts/inference", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-API-Key-ID": "<your-api-key>",
    },
    body: JSON.stringify({
      text: "नमस्ते, आप कैसे हैं?",
      voice: "Pranav",
      model: "Timbre v2.0 / Timbre v2.5",
      audio_config: {
        sample_rate: 48000,
        num_channels: 1,
        sample_width: 2,
        encoding: "linear_pcm",
        container: "wav",
      },
    }),
  });

  const audio = await response.arrayBuffer();
  // Handle binary audio data
  console.log("Received audio:", audio.byteLength, "bytes");
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.vachana.ai/api/v1/tts/inference",
      headers={
          "Content-Type": "application/json",
          "X-API-Key-ID": "<your-api-key>",
      },
      json={
          "text": "नमस्ते, आप कैसे हैं?",
          "voice": "Pranav",
          "model": "Timbre v2.0 / Timbre v2.5",
          "audio_config": {
              "sample_rate": 48000,
              "num_channels": 1,
              "sample_width": 2,
              "encoding": "linear_pcm",
              "container": "wav",
          },
      },
  )

  with open("response.wav", "wb") as f:
      f.write(response.content)
  ```
</CodeGroup>

***

## Python SDK

The official Python SDK lets you synthesize speech in one line, without constructing JSON payloads or handling binary audio responses manually.

### Installation

```bash theme={null}
pip install gnani-vachana
```

Requires **Python 3.10+**.

### Authentication

<CodeGroup>
  ```python Constructor argument theme={null}
  from gnani.tts import GnaniTTSClient

  client = GnaniTTSClient(api_key="your-api-key")
  ```

  ```bash Environment variable theme={null}
  export GNANI_API_KEY="your-api-key"
  ```

  ```python Environment variable (usage) theme={null}
  from gnani.tts import GnaniTTSClient

  client = GnaniTTSClient()
  ```
</CodeGroup>

### Synthesize Speech

The `synthesize` method returns the complete audio as bytes, which you can write to a file or pass directly to an audio player.

```python theme={null}
from gnani.tts import GnaniTTSClient

client = GnaniTTSClient(api_key="your-api-key")

audio = client.synthesize(
    "नमस्ते, आप कैसे हैं?",
    voice="Kaveri",
)

with open("output.wav", "wb") as f:
    f.write(audio)
```

### Custom Audio Config

Control the sample rate, encoding, and container format of the output audio.

```python theme={null}
from gnani.tts import GnaniTTSClient, AudioConfig

client = GnaniTTSClient(api_key="your-api-key")

audio = client.synthesize(
    "यह एक टेस्ट है",
    voice="Pranav",
    audio_config=AudioConfig(
        sample_rate=48000,
        encoding="linear_pcm",
        container="wav",
    ),
)

with open("output.wav", "wb") as f:
    f.write(audio)
```

### List Available Voices

```python theme={null}
from gnani.tts import GnaniTTSClient

voices = GnaniTTSClient.supported_voices()
print(voices)
```

## Supported Languages

The Gnani Timbre v2.0 API supports 2 languages.

| Language | Native Script       | Example                    |
| -------- | ------------------- | -------------------------- |
| English  | Latin               | "I am going to the market" |
| Hindi    | Devanagari (हिन्दी) | "मैं बाज़ार जा रहा हूँ"    |


## OpenAPI

````yaml POST /api/v1/tts/inference
openapi: 3.1.0
info:
  title: TTS Server
  description: Text-to-Speech API with WebSocket, SSE and gRPC streaming support
  version: 1.0.0
servers:
  - url: https://api.vachana.ai
    description: Production server
security: []
paths:
  /api/v1/tts/inference:
    post:
      summary: TTS Inference
      operationId: tts_inference_api_v1_tts_inference_post
      parameters:
        - name: X-API-Key-ID
          in: header
          required: true
          schema:
            anyOf:
              - type: string
            title: X-Api-Key-Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TextToSpeechRequest'
      responses:
        '200':
          description: Successful audio synthesis
          content:
            audio/wav:
              schema:
                type: string
                format: binary
            audio/mpeg:
              schema:
                type: string
                format: binary
            audio/ogg:
              schema:
                type: string
                format: binary
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorResponse'
              example:
                success: false
                error:
                  type: INVALID_REQUEST_ERROR
                  message: Invalid text or audio configuration.
        '429':
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorResponse'
              example:
                success: false
                error:
                  type: RATE_LIMIT_ERROR
                  message: Rate limit exceeded. Please try again later.
        '500':
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorResponse'
              example:
                success: false
                error:
                  type: API_ERROR
                  message: An unexpected error occurred while processing.
        '503':
          description: Service Unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorResponse'
              example:
                success: false
                error:
                  type: SERVICE_UNAVAILABLE
                  message: Text-to-speech service is temporarily unavailable.
components:
  schemas:
    TextToSpeechRequest:
      properties:
        text:
          type: string
          title: Text
        voice:
          type: string
          title: Voice
          description: Voice name from the Timbre catalog.
        model:
          allOf:
            - $ref: '#/components/schemas/TTSModel'
        language:
          type: string
          title: Language
          description: >-
            Language code. Use `IND-IN` for Timbre v2.0. For Timbre v2.5 use
            `auto`, `hi-IN`, `en-IN`, `ta-IN`, `te-IN`, `kn-IN`, `ml-IN`,
            `mr-IN`, `pa-IN`, `bn-IN`, or `gu-IN`.
        speed:
          type: number
          title: Speed
          description: 'Playback speed multiplier (Timbre v2.5 only). Range: 0.85–1.15.'
        audio_config:
          allOf:
            - $ref: '#/components/schemas/AudioConfig'
      type: object
      required:
        - text
        - model
        - audio_config
      title: TextToSpeechRequest
      description: Request body for TTS inference.
      example:
        text: नमस्ते, आप कैसे हैं?
        voice: Pranav
        model: timbre-v2.5
        language: hi
        speed: 1
        audio_config:
          encoding: linear_pcm
          container: wav
          num_channels: 1
          sample_rate: 48000
          sample_width: 2
    StandardErrorResponse:
      type: object
      properties:
        success:
          type: boolean
          example: false
        error:
          $ref: '#/components/schemas/ErrorDetail'
    TTSModel:
      type: string
      enum:
        - timbre-v2.5
        - timbre-v2.0
      title: TTSModel
      description: Supported TTS models.
    AudioConfig:
      properties:
        sample_rate:
          type: integer
          maximum: 48000
          minimum: 8000
          title: Sample Rate
          description: >-
            Sample rate in Hz. Supported: 8000, 16000, 22050, 24000, 44100,
            48000
        num_channels:
          type: integer
          maximum: 8
          minimum: 1
          title: Num Channels
          description: Number of audio channels
        sample_width:
          type: integer
          maximum: 4
          minimum: 1
          title: Sample Width
          description: Sample width in bytes
        encoding:
          allOf:
            - $ref: '#/components/schemas/AudioEncoding'
          description: Audio encoding format
        container:
          allOf:
            - $ref: '#/components/schemas/AudioContainer'
          description: Audio container format
        bitrate:
          allOf:
            - $ref: '#/components/schemas/MP3Bitrate'
          description: MP3 bitrate (only used when container=mp3)
      type: object
      title: AudioConfig
      description: Audio output configuration.
    ErrorDetail:
      type: object
      properties:
        type:
          type: string
          description: A short error code string (e.g., 'INVALID_REQUEST_ERROR').
        message:
          type: string
          description: A descriptive error message.
    AudioEncoding:
      type: string
      enum:
        - linear_pcm
        - pcm_s16le
        - pcm_mulaw
        - pcm_alaw
        - oggopus
      title: AudioEncoding
      description: >-
        Supported audio encodings. Use pcm_mulaw or pcm_alaw for G.711 telephony
        codecs (forces 8000 Hz output). Use oggopus or set container=ogg to
        receive a playable OGG Opus file.
    AudioContainer:
      type: string
      enum:
        - raw
        - mp3
        - wav
        - mulaw
        - alaw
        - ogg
      title: AudioContainer
      description: Supported audio containers.
    MP3Bitrate:
      type: string
      enum:
        - 32k
        - 64k
        - 96k
        - 128k
        - 192k
      title: MP3Bitrate
      description: >-
        Supported MP3 bitrate options (only used when container is MP3).
        Default: 128k

````