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

# Speech endpoint (legacy)

> The original /tts/v1 speech endpoint. The URL still works as an alias for /v1/audio/speech; the old mira_ keys are retired.

<Warning>
  This page documents the **original** speech endpoint. Start new integrations at
  the [TTS quickstart](/v2/tts-quickstart): the current endpoint lives at
  `/v1/audio/speech`, uses model `mira-tts`, streams, and takes the same
  `sk_live_` key as the rest of the API.
</Warning>

## What `/tts/v1` does now

**The URL keeps working.** `POST /tts/v1/audio/speech` is an alias for
[`POST /v1/audio/speech`](/v2/tts-quickstart). It runs the same handler and
returns the same audio, so a caller that changes only its key needs no other
change:

* **Auth is your `sk_live_` API key**, the one you mint in the
  [console](https://sandbox.voice.miraiminds.co) under **Developers**. The old
  `mira_` speech keys are retired. If you still have one, get an `sk_live_` key
  from the [quickstart](/v2/tts-quickstart#1-get-a-key).
* **`model` is `mira-tts`**, and `mira-tts-v51` is accepted as an alias, so an
  existing body keeps working unchanged.
* **Everything else follows the current endpoint**: voices, the
  [output formats and sample rates](/v2/tts-quickstart#output-formats),
  `pcm` streaming, the 2,000-character ceiling, the response headers, the
  [price](/v2/tts-quickstart#billing), the wallet it debits and the
  [request log](/v2/tts-quickstart#your-request-log). The TTS quickstart
  documents all of it.
* **The options below that were unique to this endpoint** (`speech_ready`,
  `instructions`, `lexicon` and `numbers`) are no longer applied. The endpoint
  ignores them, and sending them does not cause an error.

The rest of this page describes the original endpoint as it behaved, for
callers reading old code.

## The original endpoint

The speech endpoint is the voice our agents use, on its own. You send text and
get a WAV back. It takes the same request shape as the OpenAI audio API, so any
OpenAI SDK works once you swap `base_url` and the key.

The engine speaks Hindi, English and the Hinglish in between, plus Gujarati in
beta. Five more languages (Telugu, Tamil, Marathi, Kannada and Bengali) arrive
over the next two months. See the [language roadmap](/v2/tts-languages).

## Calling the alias

This request sends the old body with the new key:

```bash theme={null}
curl https://sandbox.voice.miraiminds.co/tts/v1/audio/speech \
  -H "Authorization: Bearer $MIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mira-tts-v51",
    "input": "नमस्ते, मैं आशु बोल रहा हूं। आपका ऑर्डर तैयार है।",
    "voice": "ashu",
    "response_format": "wav"
  }' \
  --output speech.wav
```

The response body is the audio itself, in the format you ask for. Send
`response_format` explicitly: `wav` gives you a file, and `pcm`, `ulaw_8000`
and the other raw formats stream, which is what you want in a live pipeline.
See [Output formats](/v2/tts-quickstart#output-formats).

## Request

<Note>
  Read this table as history. On the alias, `model`, `input`, `voice` and
  `response_format` behave as the [TTS quickstart](/v2/tts-quickstart) documents:
  `input` goes up to 2,000 characters and `pcm` streams. The four fields below
  that are specific to Mirai are ignored.
</Note>

| Field | Type | Notes |
| :- | :- | :- |
| `model` | string | **Required.** Must be `mira-tts-v51`. |
| `input` | string | **Required.** Up to **600 characters**. |
| `voice` | string | `ashu` (default) or `aishe`. Same catalogue as [Voices](/v2/voices). |
| `response_format` | string | `wav` only, and it is the default. Anything else is a 400. |
| `speech_ready` | boolean | `true` (default) runs the rewrite pass below. `false` sends your text to the engine untouched. |
| `instructions` | string | Up to 500 characters, steers the rewrite (tone, pacing). Ignored when `speech_ready` is `false`. |
| `lexicon` | object | Pronunciation overrides, `{"Gallabox": "Galla Box"}`. Applied as a deterministic replace, never by the model. |
| `numbers` | string | Which language digits are spoken in: `auto` (default), `english` or `native`. |

<Note>
  `model` is a stable public name rather than a build number. It always points at
  the current production voice, which we upgrade over time, so a clip you
  generate today may sound better than one from last month with no change to your
  code.
</Note>

## The rewrite pass

<Warning>
  The rewrite pass is **not** part of the current endpoint. `speech_ready`,
  `instructions` and `lexicon` are ignored and no `X-Mira-Speech-Ready` header is
  returned. Send text you are happy to hear read aloud.
</Warning>

Raw text is rarely speech-ready. `97%` should be read as "ninety-seven
percent", a product name should not be transliterated, and a bare URL should
not be spelled out character by character. By default, before your text reaches
the engine, a rewrite pass fixes these cases and keeps the meaning the same.

Every response carries a header that says what happened:

| `X-Mira-Speech-Ready` | Meaning |
| :- | :- |
| `rewritten` | The rewrite ran and its output was synthesised. |
| `bypassed` | You sent `"speech_ready": false`, so your text was synthesised untouched. |
| `fallback` | The rewrite was unavailable, so your **original** text was synthesised. |

`fallback` is a degradation, never an error: you still get audio and still get
a 200. If you are debugging pronunciation and the header says `fallback`, the
rewrite did not shape that clip.

```bash title="Skip the rewrite" theme={null}
curl https://sandbox.voice.miraiminds.co/tts/v1/audio/speech \
  -H "Authorization: Bearer $MIRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"mira-tts-v51","input":"Order #4417 ready","voice":"ashu","speech_ready":false}' \
  --output raw.wav
```

## Listing models

```bash theme={null}
curl https://sandbox.voice.miraiminds.co/tts/v1/models \
  -H "Authorization: Bearer $MIRA_API_KEY"
```

The list names one model, the current one:

```json theme={null}
{
  "object": "list",
  "data": [
    { "id": "mira-tts", "object": "model", "owned_by": "miraiminds" }
  ]
}
```

`mira-tts-v51` is still accepted in a request body; it is no longer listed.

## Errors

Errors use the same envelope as the rest of the API. See [Errors](/v2/errors).

| Status | `code` | Cause |
| :- | :- | :- |
| 400 | `missing_input` | `input` absent or empty. |
| 400 | `input_too_long` | Over 600 characters. Split it. |
| 400 | `invalid_voice` | Not `ashu` or `aishe`. |
| 400 | `invalid_response_format` | Anything other than `wav`. |
| 400 | `invalid_instructions` | Not a string, or over 500 characters. |
| 400 | `invalid_lexicon` | Not an object that maps strings to strings. |
| 400 | `invalid_numbers` | Not `auto`, `english` or `native`. |
| 400 | `invalid_json` | Body is not valid JSON. |
| 401 | `invalid_api_key` | Missing or unknown key. |
| 404 | `model_not_found` | `model` is not `mira-tts-v51`. |

```json title="404 Not Found" theme={null}
{
  "error": {
    "message": "Unknown model 'tts-1'. Use 'mira-tts-v51'.",
    "type": "invalid_request_error",
    "code": "model_not_found"
  }
}
```

The alias returns the current endpoint's codes instead:
`invalid_request`, `unauthorized`, `insufficient_balance`, `at_capacity`,
`rate_limited`, `model_not_found`, `upstream_error`. See
[When something fails](/v2/tts-quickstart#when-something-fails).

## Using an OpenAI SDK

The request shape matches, so you can point the client at us and keep your
code:

```python theme={null}
from openai import OpenAI

client = OpenAI(
    base_url="https://sandbox.voice.miraiminds.co/tts/v1",
    api_key=MIRA_API_KEY,   # sk_live_… — the mira_ speech keys are retired
)

client.audio.speech.create(
    model="mira-tts-v51",
    voice="neha",
    input="नमस्ते, आपका ऑर्डर तैयार है।",
).stream_to_file("speech.wav")
```

<Note>
  `lexicon`, `numbers`, `instructions` and `speech_ready` are ours, not
  OpenAI's. SDKs that validate their request body may reject them, so send those
  fields with a plain HTTP client, or use `extra_body` where your SDK supports
  it.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.