# Text to speech

`POST https://api.llm.buzz/api/v1/audio/speech`

OpenRouter's text-to-speech API: one text in, the whole audio out as MP3 or raw PCM, never streamed. A call bills the input's characters, and settles before the first byte is sent. The answer has no JSON body, so its cost is in the generation record that `X-Generation-Id` names. `GET /api/v1/models?output_modalities=speech` lists the models your key can call, each with its `supported_voices`, `default_voice` and `speech_speed`.

Authentication: an inference key, as `Authorization: Bearer KEY`.

## Body

- `model` (string, required): A text-to-speech model from `GET /api/v1/models?output_modalities=speech`, such as `hexgrad/kokoro-82m`.
- `input` (string, required): 1 to 4,096 characters. An array of turns (several speakers) is a 400.
- `voice` (string): One of the model's `supported_voices`; omitted, its `default_voice`.
- `response_format` (string, one of `pcm`, `mp3`): `pcm` (the default: signed 16-bit little-endian mono) or `mp3`.
- `speed` (number): 0.25 to 4.0, on a model whose `speech_speed` is `true`.
- `provider` (object): The audio routes read only the data policy fields; `order`, `only`, `ignore`, `allow_fallbacks` and `sort` are accepted and ignored. With the OpenAI SDK, send it in `extra_body`.
  - `zdr` (boolean): `true` keeps the request on providers that declare 0 days of retention.
  - `data_collection` (string, one of `allow`, `deny`): `deny` keeps the request on providers that declare no training and 0 days of retention.

## Responses

- 200: The audio: `audio/mpeg`, or `audio/pcm` at the provider's rate, with `Cache-Control: no-store` and the `X-Generation-Id` header.
- 400: A field is missing or malformed (`invalid_request`, with `metadata.param`), or the model cannot do what the request asks (`unsupported_capability`).
- 401: No key, or the key is unknown, expired, revoked or disabled.
- 402: Your balance is spent and the model is not free, or the request could cost more than your balance.
- 404: No model has this name, or your key may not call it.

## Example (curl)

```bash
curl -X POST https://api.llm.buzz/api/v1/audio/speech \
  -H "Authorization: Bearer $LLM_BUZZ_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "hexgrad/kokoro-82m",
  "input": "Your order has shipped.",
  "voice": "af_heart",
  "response_format": "mp3"
}'
```
