> This page is for Gateway.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.merge.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.merge.dev/_mcp/server.

# Speech to text

> Transcribe audio on Gateway with POST /v1/audio/transcriptions: the multipart request, the JSON transcript response, duration-based billing, and size limits.

`POST /v1/audio/transcriptions` turns an audio file into text, for when the transcript is what you need, such as indexing a call recording. To have a model reason about a recording instead, send an [audio content block](/merge-gateway/capabilities/multimodal/overview) to a chat model.

The request is `multipart/form-data`. `openai/whisper-1` is the transcription model in the [model catalog](/merge-gateway/models/catalog).

**`cURL`**

```bash title="cURL"
curl https://api-gateway.merge.dev/v1/audio/transcriptions \
  -H "Authorization: Bearer $MERGE_GATEWAY_API_KEY" \
  -F "file=@standup-2026-09-01.mp3" \
  -F "model=openai/whisper-1" \
  -F "response_format=verbose_json"
```

**`Python`**

```python title="Python"
import os, requests

with open("standup-2026-09-01.mp3", "rb") as audio:
    resp = requests.post(
        "https://api-gateway.merge.dev/v1/audio/transcriptions",
        headers={"Authorization": f"Bearer {os.environ['MERGE_GATEWAY_API_KEY']}"},
        files={"file": audio},
        data={"model": "openai/whisper-1", "response_format": "verbose_json"},
    )
print(resp.json()["text"])
```

The response is always this JSON object, whatever `response_format` you send:

```json
{
  "text": "Yesterday I finished the routing policy migration and today I am picking up the retry work.",
  "vendor": "openai",
  "language": "english",
  "duration": 8.4
}
```

`text` and `vendor` are always present; `language` and `duration` (seconds) appear when the model reports them, which on Whisper means `response_format=verbose_json`.

## Reference

All fields are form fields.

| Field             | Notes                                                                                |
| ----------------- | ------------------------------------------------------------------------------------ |
| `file`            | Required. The audio file.                                                            |
| `model`           | Required. A canonical model ID. `@alias/...` returns `400 alias_not_supported`.      |
| `language`        | ISO-639-1 code. Setting it when you know the language improves accuracy and latency. |
| `prompt`          | Text that biases spelling, such as product or attendee names                         |
| `response_format` | Passed to the vendor. `verbose_json` returns `language` and `duration`.              |
| `temperature`     | Sampling temperature                                                                 |
| `vendor`          | Pin the execution vendor                                                             |

This endpoint takes no `customer` field. Gateway doesn't cap file size, so the vendor's limit applies (25 MB on OpenAI) and an oversized file returns the vendor's error; split or downsample long recordings.

Transcription bills per second of audio at the model's `input_per_second` rate (`unit: per_second` on `GET /v1/models`). A rejected vendor credential returns `503` with `code: provider_authentication_failed`, and a vendor throttle returns a retryable `429` ([Errors](/merge-gateway/errors)).

## Next steps

#### [Text to speech](/merge-gateway/capabilities/multimodal/text-to-speech)

Synthesize audio from text

#### [Multimodal](/merge-gateway/capabilities/multimodal/overview)

Send audio to a chat model to reason over the recording