> For clean Markdown of any page, append `.md` to the page URL.
> For a complete documentation index, see https://docs.sarvam.ai/llms.txt.
> For full documentation content in one file, see https://docs.sarvam.ai/llms-full.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.sarvam.ai/_mcp/server.

# API reference — Speech-to-Text

> The InvokeEndpoint request and response contract for a self-hosted Saaras v3 endpoint on SageMaker: parameters, the five output modes, response schema, the streaming protocol, and errors.

The contract for invoking a self-hosted **Saaras v3** endpoint. Unlike the Managed API, the invoke contract lives in the SageMaker model container — this page is the reference for it.

**Model identifier.** Send **`model: saaras:v3`** in every request. The Marketplace package is versioned **`saaras:v3.1`** (the revision you subscribe to) — do not send `saaras:v3.1` as the model id.

## Real-time — `InvokeEndpoint`

| Field            | Value                                                                        |
| ---------------- | ---------------------------------------------------------------------------- |
| **Operation**    | `sagemaker-runtime:InvokeEndpoint`                                           |
| **Content-Type** | `multipart/form-data; boundary=<boundary>`                                   |
| **Accept**       | `application/json`                                                           |
| **Max audio**    | 30 seconds (use streaming for longer — batch is not supported for Saaras v3) |

`multipart/form-data` is the **only** content type the Saaras v3 endpoint accepts. Any other content type is rejected with a **4xx**.

### Request fields

| Field             | Type   | Required | Description                                                                                             |
| ----------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------- |
| `file`            | file   | yes      | The audio to transcribe (WAV and common formats).                                                       |
| `model`           | string | yes      | `saaras:v3`                                                                                             |
| `mode`            | string | no       | Output mode. One of `transcribe`, `translate`, `verbatim`, `translit`, `codemix`. Default `transcribe`. |
| `with_timestamps` | string | no       | `"true"` to return word-level timestamps.                                                               |
| `language-code`   | string | no       | e.g. `hi-IN`. Auto-detected if omitted.                                                                 |

### Output modes

| Mode         | Output                                            |
| ------------ | ------------------------------------------------- |
| `transcribe` | Text in the source language                       |
| `translate`  | English translation                               |
| `verbatim`   | Word-for-word, including fillers and repetitions  |
| `translit`   | Source speech transliterated to Roman script      |
| `codemix`    | Code-mixed text (e.g. Hindi-English) kept natural |

### Response

```json
{
  "request_id": "20260728_de2321d1-9ddf-4a99-9ed4-49a19bda3136",
  "transcript": "namaste, main aapki kaise madad kar sakta hoon",
  "language_code": "hi-IN",
  "language_probability": 0.98,
  "timestamps": {
    "words": ["namaste", "main", "aapki", "..."],
    "start_time_seconds": [0.10, 0.72, 1.05],
    "end_time_seconds":   [0.61, 0.94, 1.38]
  }
}
```

`timestamps` is present only when `with_timestamps` is `"true"`. The `request_id` format is `YYYYMMDD_<uuid4>` (not `req_…`).

## Streaming — `InvokeEndpointWithBidirectionalStream`

For continuous, low-latency audio, open a **two-way SigV4 HTTP/2 stream on port 8443** (client `aws-sdk-sagemaker-runtime-http2`): audio-in frames go up and transcript-out frames come back. This is a full-duplex **bidirectional** stream — *not* the one-way `InvokeEndpointWithResponseStream` response-streaming operation.

**Query parameters** — sent URL-encoded in the `ModelQueryString`:

| Parameter       | Values            | Notes                      |
| --------------- | ----------------- | -------------------------- |
| `model`         | `saaras:v3`       | required                   |
| `language-code` | e.g. `en-IN`      | optional                   |
| `sample_rate`   | `8000` or `16000` | mono 16-bit PCM only       |
| `vad_signals`   | `true` / omit     | emit voice-activity events |

**Message protocol** — send JSON frames, then read frames back:

```json
// 1. open with a config frame
{ "type": "config" }
// 2. stream audio chunks
{ "audio": { "data": "<base64 PCM>", "sample_rate": 16000, "encoding": "audio/wav" } }
// 3. flush at end
{ "type": "flush" }
```

The endpoint returns `events` frames (VAD signals, when `vad_signals=true`) and `data` frames (incremental transcripts).

Streaming accepts only **8 kHz or 16 kHz, mono, 16-bit PCM**. Other sample rates or encodings are rejected.

## Errors

Every non-2xx is delivered as **HTTP 424** through `InvokeEndpoint` — branch on `OriginalStatusCode` and `error.code`, never on the HTTP status. See [Error handling on SageMaker](/api/self-hosted/sagemaker/errors) for the collapse rule, the boto3 branch snippet, and the shared envelope.

**Bad request** — `OriginalStatusCode` `400`, `code: invalid_request_error`. Causes: a wrong model id (send `saaras:v3`, not `saaras:v3.1`), audio over 30 s on the real-time path, empty / unreadable / truncated audio, a missing `file`, or any content type other than `multipart/form-data`.

```json
{
  "error": {
    "message": "Lean STT supports only 'saaras:v3'. Got 'not-a-model'.",
    "code": "invalid_request_error",
    "request_id": "20260728_…"
  }
}
```

**Overload** — `OriginalStatusCode` `429`, `code: service_overloaded`. The container sheds fast rather than queueing; back off using the body `retry_after`.

```json
{
  "error": {
    "message": "Server is busy. Please retry shortly.",
    "code": "service_overloaded",
    "request_id": "20260728_…",
    "retry_after": 1
  }
}
```

Fix `400`s and never retry them; back off on `429 service_overloaded` using `retry_after`; retry other `5xx` once, then report `error.request_id`.

#### [Deploy a Saaras v3 endpoint](/api/self-hosted/sagemaker/deploy-saaras)

Step-by-step real-time and streaming deployment with boto3.