# Транскрибация · Speech-to-Text — neuraldeep.ru API

> Раздел машиночитаемой справки. Все разделы: https://neuraldeep.ru/llms.txt · всё одним файлом: https://neuraldeep.ru/llms-full.txt

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

Речь в текст, OpenAI-совместимый `POST /v1/audio/transcriptions`. Работает синхронно: отправили файл, в том же ответе получили текст. Для длинных записей с разметкой по спикерам есть асинхронный [SpeechCore](https://neuraldeep.ru/docs/speechcore.md).

| модель | что это |
|---|---|
| `whisper-1` | Whisper large-v3-turbo, 100+ языков, понимает все форматы ответа |
| `whisper-podlodka-turbo` | Whisper turbo, дообученный под русский |
| `gigaam-v3` | GigaAM v3, модель под русский язык |

**Запрос.** `multipart/form-data`, поля:

- `file`, обязательно: аудио или видео файлом;
- `model`, обязательно: одна из моделей выше;
- `language`: код языка (`ru`, `en`...). Без него язык определяется сам, на коротких файлах лучше задать явно;
- `prompt`: подсказка с терминами и именами, повышает точность на специальной лексике;
- `response_format`: `json` (по умолчанию), `verbose_json`, `text`, `srt`, `vtt`;
- `timestamp_granularities[]=word`: тайм-коды по словам, только вместе с `verbose_json`;
- `temperature`: по умолчанию 0.

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

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

**Ответ.** `json` и `verbose_json` возвращают `text`, `language`, `duration` в секундах и `segments` с тайм-кодами. Форматы `text`, `srt` и `vtt` гейт тоже заворачивает в JSON: содержимое лежит строкой в поле `text`. Субтитры `srt` и `vtt` собирает только `whisper-1`. Для других моделей берите `verbose_json` и стройте субтитры из `segments` сами.

```json
{"text": "Добрый день, начинаем созвон.", "language": "ru", "duration": 3.0,
 "segments": [{"id": 0, "start": 0.0, "end": 2.9, "text": "Добрый день, начинаем созвон."}]}
```

**Ограничения на вход.**

- Размер файла: до 25 МБ на запрос. Файл больше основной движок не принимает, такой запрос уходит в резерв и может отработать медленнее или не пройти. Длинную запись режьте на части до 25 МБ.
- Длительность: отдельного предела нет, но ответ должен уложиться в 240 секунд. На практике это десятки минут речи за один запрос. Внутри запроса движок сам делит речь по паузам на короткие фрагменты и склеивает результат, резать на 30-секундные куски не нужно.
- Форматы: всё, что читает ffmpeg. mp3, wav, m4a и mp4, ogg и opus, flac, webm, aac, amr, wma, mov и mkv (берётся звуковая дорожка).
- Частота и каналы: любые, сервер сам приводит звук к 16 кГц моно. Чтобы влезть в 25 МБ, отправляйте 16 кГц моно в mp3 или opus: час речи в opus 32 кбит/с весит около 15 МБ.

**Квота.** На бесплатном тарифе действует небольшая дневная квота транскрибаций, сутки считаются по UTC. Когда она кончилась, запрос пройдёт с оплатой по минутам аудио, если у аккаунта есть деньги на кошельке. Иначе придёт `429` с заголовками `X-Window: stt-free-daily`, `X-STT-Limit` и `Retry-After` до 00:00 UTC. На платных тарифах отдельной квоты на транскрибацию нет: каждый запрос считается в общие окна ключа вместе с чатом (запросы в минуту, параллельность, session и week), остатки видны в `GET /v1/limits`.

**Ошибки.**

- `400`: файл пустой или не похож на аудио (`X-Window: stt-bad-file`), ffmpeg не смог его прочитать (недокачан, битый), `timestamp_granularities` без `verbose_json`.
- `429`: кончилась бесплатная дневная квота (см. выше) или сработал лимит частоты или параллельности ключа, ждите `Retry-After`.
- `408` или `504`: распознавание не уложилось во время. Порежьте файл.
- `503`: распознавание временно недоступно, повторите через минуту.
