# Transcription · Speech-to-Text — neuraldeep.tech API

> One section of the machine-readable reference. All sections: https://neuraldeep.tech/llms.txt · everything in one file: https://neuraldeep.tech/llms-full.txt

Base URL: `https://api.neuraldeep.tech/v1`
Auth: `Authorization: Bearer $YOUR_KEY`

Speech to text, OpenAI-compatible `POST /v1/audio/transcriptions`. It is synchronous: you send a file and get the text in the same response. For long recordings with speaker labels there is the asynchronous [SpeechCore](https://neuraldeep.tech/docs/speechcore.md).

| model | what it is |
|---|---|
| `whisper-1` | Whisper large-v3-turbo, 100+ languages, supports every response format |
| `whisper-podlodka-turbo` | Whisper turbo fine-tuned for Russian |
| `gigaam-v3` | GigaAM v3, a model built for Russian |

**Request.** `multipart/form-data`, fields:

- `file`, required: audio or video as a file;
- `model`, required: one of the models above;
- `language`: language code (`ru`, `en`...). Without it the language is detected automatically; set it explicitly for short files;
- `prompt`: a hint with terms and names, improves accuracy on special vocabulary;
- `response_format`: `json` (default), `verbose_json`, `text`, `srt`, `vtt`;
- `timestamp_granularities[]=word`: per-word timestamps, only together with `verbose_json`;
- `temperature`: default 0.

```bash
curl https://api.neuraldeep.tech/v1/audio/transcriptions \
  -H "Authorization: Bearer $YOUR_KEY" \
  -F file=@meeting.mp3 \
  -F model=whisper-1 \
  -F language=en
```

```python
from openai import OpenAI
client = OpenAI(api_key="$YOUR_KEY", base_url="https://api.neuraldeep.tech/v1")
with open("meeting.mp3", "rb") as f:
    r = client.audio.transcriptions.create(model="whisper-1", file=f, language="en")
print(r.text)
```

**Response.** `json` and `verbose_json` return `text`, `language`, `duration` in seconds and `segments` with timestamps. The gateway wraps `text`, `srt` and `vtt` in JSON as well: the content is a string in the `text` field. Only `whisper-1` builds `srt` and `vtt` subtitles. For the other models use `verbose_json` and build subtitles from `segments` yourself.

```json
{"text": "Good afternoon, let's start the call.", "language": "en", "duration": 3.0,
 "segments": [{"id": 0, "start": 0.0, "end": 2.9, "text": "Good afternoon, let's start the call."}]}
```

**Input limits.**

- File size: up to 25 MB per request. The main engine does not accept larger files; such a request goes to a reserve engine and may run slower or fail. Split long recordings into parts under 25 MB.
- Duration: there is no separate cap, but the response has to fit into 240 seconds. In practice that is tens of minutes of speech per request. Inside a request the engine splits speech at pauses into short fragments and joins the result; you do not need to cut it into 30-second pieces.
- Formats: anything ffmpeg reads. mp3, wav, m4a and mp4, ogg and opus, flac, webm, aac, amr, wma, mov and mkv (the audio track is used).
- Sample rate and channels: any, the server converts audio to 16 kHz mono. To stay under 25 MB, send 16 kHz mono mp3 or opus: an hour of speech in 32 kbit/s opus is about 15 MB.

**Quota.** The free plan has a small daily transcription quota, days are counted in UTC. Once it is used up, a request still goes through and is billed per minute of audio if the account has money in the wallet. Otherwise you get `429` with `X-Window: stt-free-daily`, `X-STT-Limit` and `Retry-After` until 00:00 UTC. Paid plans have no separate transcription quota: each request counts towards the key's common windows together with chat (requests per minute, concurrency, session and week); the remainders are in `GET /v1/limits`.

**Errors.**

- `400`: the file is empty or does not look like audio (`X-Window: stt-bad-file`), ffmpeg could not read it (truncated, corrupted), `timestamp_granularities` without `verbose_json`.
- `429`: the free daily quota is used up (see above) or the key's rate or concurrency limit fired, wait for `Retry-After`.
- `408` or `504`: recognition did not finish in time. Split the file.
- `503`: transcription is temporarily unavailable, retry in a minute.
