# Text to speech

> Turn text into speech with POST /v1/audio/speech on BigModel.io, pick a voice from /v1/audio/voices, and pay per second of audio or per 10k characters.

Web version: https://bigmodel.io/docs/text-to-speech · Updated 2026-10-18

`POST /v1/audio/speech` follows the OpenAI speech API: send text, get audio bytes back. Speech models are listed under [Models → Audio](https://bigmodel.io/models?type=Audio). Some are priced per second of audio, others per 10,000 characters of input.

## List voices

```bash
curl https://bigmodel.io/v1/audio/voices \
  -H "Authorization: Bearer $BIGMODEL_API_KEY"
```

```json
{"object": "list", "data": [{"id": "...", "name": "...", "language": "zh", "tags": ["female", "calm"]}]}
```

Pass a voice's `id` as `voice`. Without `voice`, the model's default voice is used.

## Generate speech

```bash [cURL]
curl https://bigmodel.io/v1/audio/speech \
  -H "Authorization: Bearer $BIGMODEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "minimax-speech-2.8-turbo", "input": "Welcome to BigModel.io. One key for every model.", "voice": "VOICE_ID"}' \
  --output speech.mp3
```

```python [Python]
import os
from openai import OpenAI

client = OpenAI(base_url="https://bigmodel.io/v1", api_key=os.environ["BIGMODEL_API_KEY"])

with client.audio.speech.with_streaming_response.create(
    model="minimax-speech-2.8-turbo",
    voice="VOICE_ID",
    input="Welcome to BigModel.io. One key for every model.",
) as response:
    response.stream_to_file("speech.mp3")
```

The response body is the audio file, with its type in `Content-Type` (usually `audio/mpeg`) and the task ID in `X-Task-Id`.

| Field | Notes |
|---|---|
| `model` | Required. A speech model ID. |
| `input` | Required. Up to 4,000 characters. |
| `voice` | A voice `id` from `/v1/audio/voices`. |
| `speed` | 0.5 to 2. |
| `emotion` | A mood hint, on models that support it. |

### Long texts

The request waits up to 2 minutes. If the audio is not ready by then, you get `202` with a task (`object: "audio.generation"`) and a `Location` header instead of audio. Poll `GET /v1/audio/generations/{id}` and download from `GET /v1/audio/generations/{id}/content`, as described in [Music, sound effects & audio tools](https://bigmodel.io/docs/audio-generation). To always work asynchronously, send the same body to `POST /v1/audio/generations`.

## How you are charged

Per-10k-character models charge for the characters in `input`. Per-second models charge for the length of the audio produced. Add `"dry_run": true` to the body to get `{"object": "quote", "estimated_cost_usd": ...}` without generating anything. Failed requests are not charged. Charges appear in [Usage](https://bigmodel.io/usage).

## Verify the setup

Call `/v1/audio/voices`, then run the generation example with one of the IDs. A playable `speech.mp3` means the key works.

## Troubleshooting

**400 "input is required" or "input must be at most 4000 characters".** Send text in `input` and split long texts into several requests.

**400 "speed must be between 0.5 and 2".** Use a value in that range.

**404 `model_not_available`.** The model is not offered to this key, or it is not a speech model. Check `GET /v1/models`.

**402 `insufficient_balance`.** Top up in [Billing](https://bigmodel.io/purchase).

**502 `upstream_error`.** The speech could not be generated. Try a different voice or text. You are not charged.

**`data` is empty in `/v1/audio/voices`.** No speech model is offered to this key's group.

## Related

- [Video generation](https://bigmodel.io/docs/video-generation): avatar models use a voice track as `input_audio`.
- [Music, sound effects & audio tools](https://bigmodel.io/docs/audio-generation).
- [Pricing](https://bigmodel.io/pricing) for speech prices.
