# Transcriptions

POST /v1/audio/transcriptions - OpenAI-compatible speech-to-text, served through your connected Codex login.

*ProxyLLM docs · https://proxyllm.ai/docs/api/transcriptions*

```
POST /v1/audio/transcriptions
```

Auth: **[routing key](/docs/api/authentication)** (`pllm_…`). Speech-to-text that behaves like OpenAI's transcription API, served through the Codex login connected to the key's account - no separate transcription bill. The key must have a connected Codex seat.

Point any OpenAI SDK at `https://api.proxyllm.ai/v1` and call `audio.transcriptions.create` as usual.

## Request body

Send `multipart/form-data`, the same shape an OpenAI SDK sends.

| Field             | Type            | Notes                                                                                                   |
| ----------------- | --------------- | ------------------------------------------------------------------------------------------------------- |
| `file`            | file, required  | The audio to transcribe (mp3, mp4/m4a, wav, webm, …).                                                   |
| `model`           | string          | `gpt-4o-transcribe` (default when omitted is `gpt-4o-mini-transcribe`). `whisper-1` is not available on a Codex login and is served by `gpt-4o-transcribe` instead - see below. |
| `language`        | string          | ISO-639-1 hint, forwarded.                                                                              |
| `prompt`          | string          | Optional context to bias the transcript, forwarded.                                                     |
| `response_format` | string          | `json` (default) or `text`. Other formats are normalized to `json`.                                     |
| `temperature`     | number          | Forwarded.                                                                                              |

A JSON body is also accepted as a convenience for hand testing: `{"file": "<base64>", "filename": "voice.mp4", "model": "gpt-4o-transcribe"}`.

```bash
curl https://api.proxyllm.ai/v1/audio/transcriptions \
  -H "Authorization: Bearer pllm_your_routing_key" \
  -F model="gpt-4o-transcribe" \
  -F file="@voice.mp4"
```

```python
from openai import OpenAI

client = OpenAI(base_url="https://api.proxyllm.ai/v1", api_key="pllm_your_routing_key")
client.audio.transcriptions.create(model="gpt-4o-transcribe", file=open("voice.mp4", "rb"))
```

## Models

Two transcription models run on a Codex login:

- `gpt-4o-transcribe`
- `gpt-4o-mini-transcribe` (the default when `model` is omitted)

`whisper-1` is blocked for a Codex login, so a request for it is served by `gpt-4o-transcribe` and the response header `x-proxyllm-model-substituted: whisper-1` names what you asked for. `x-proxyllm-model` always names the model that actually ran.

## Response

`response_format=json` (the default) returns the OpenAI transcription shape:

```json
{
  "text": "No, I've done it before.",
  "usage": {
    "type": "tokens",
    "input_tokens": 20,
    "output_tokens": 9,
    "total_tokens": 29
  }
}
```

`response_format=text` returns the transcript as `text/plain`.

Response headers report which lane served the request and what it would have cost at API rates (a Codex seat bills `$0`): `x-proxyllm-provider`, `x-proxyllm-model`, `x-proxyllm-model-substituted`, `x-proxyllm-cost-usd`, `x-proxyllm-api-equivalent-usd`, `x-proxyllm-latency-ms`.

## Errors

| Status | Code                       | When                                                        |
| ------ | -------------------------- | ----------------------------------------------------------- |
| 400    | `no_audio_file`            | No audio file was found in the request.                     |
| 401    | `signup_required`          | Missing key, or a raw provider key was sent.                |
| 401    | `invalid_api_key`          | Unknown or revoked routing key.                             |
| 401    | `codex_reconnect_required` | The connected Codex login expired; reconnect it.            |
| 402    | `budget_exceeded`          | Monthly budget exhausted.                                   |
| 405    | (none)                     | Method other than POST.                                     |
| 502    | `no_codex_session`         | No Codex login is connected for this key.                   |
| 502    | `capacity_reached`         | The Codex account is out of transcription capacity for now. |
| 502    | `upstream_error`           | The transcription service was unavailable; try again.       |

Full list: [error codes](/docs/api#error-codes).
