REST API позволяет встроить автоматическую транскрибацию аудио и видео в собственные приложения и сервисы. С помощью API можно создавать задачи на распознавание речи, загружать файлы напрямую или передавать ссылки на записи — с Яндекс.Диска, из VK Видео и YouTube, получать текст расшифровки с тайм-кодами, разделение по спикерам с ролями и AI-саммари, а также отслеживать статус обработки — опросом или через webhook. Для распознавания в реальном времени есть отдельный WebSocket-эндпоинт живых субтитров: поток аудио превращается в текст по мере речи, с переводом на другой язык при необходимости.
Авторизация выполняется по API-ключу: он создаётся в разделе «API-ключи» личного кабинета. Запросы расходуют тот же баланс минут, что и задачи на сайте, — первые 45 бесплатных минут можно потратить на тестирование интеграции. Ниже — полное описание методов, параметров и форматов ответов с примерами запросов, поддерживаемые форматы файлов, режимы обработки и типовые сценарии использования API. Готовые примеры кода на Python, PHP, Node.js, Go и C# — на странице примеров интеграции.
Передавайте ключ в заголовке Authorization. Базовый адрес — https://speech-recognition.ru.
Authorization: Bearer sk_live_ваш_ключЛибо короче: создаёте задачу сразу со ссылкой на запись (url) — шаги 2–3 не нужны, скачивание берёт на себя сервис.
POST/api/v1/jobs
Создать задачу. Поля: fileName, fileSize (байт) — либо вместо них url (Яндекс.Диск, VK Видео, YouTube или прямая ссылка на файл); mode — DIARIZED_SUMMARY (по умолчанию: текст + роли + саммари) или TRANSCRIPT (только текст); summaryTemplate — формат саммари: default (универсальное), meeting (протокол встречи), lecture (конспект лекции), interview (карточка интервью), sales (карточка звонка), social (пост для соцсетей); callbackUrl — необязательный адрес для уведомления о готовности.
curl -X POST https://speech-recognition.ru/api/v1/jobs \
-H "Authorization: Bearer sk_live_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{
"fileName": "meeting.mp3",
"fileSize": 5242880,
"mode": "DIARIZED_SUMMARY",
"summaryTemplate": "meeting",
"callbackUrl": "https://ваш-сервер.ru/webhook"
}'
# Ответ:
{ "jobId": "clx…", "uploadUrl": "https://s3.speech-recognition.ru/…" }
# Или по ссылке — задача сразу уходит в обработку:
curl -X POST https://speech-recognition.ru/api/v1/jobs \
-H "Authorization: Bearer sk_live_ваш_ключ" \
-H "Content-Type: application/json" \
-d '{ "url": "https://disk.yandex.ru/i/abc123" }'
# Ответ:
{ "jobId": "clx…" }PUT{uploadUrl}
Загрузить файл по полученной ссылке (действует 1 час).
curl -X PUT "{uploadUrl}" --data-binary @meeting.mp3POST/api/v1/jobs/{jobId}/start
Запустить распознавание. Минуты списываются по длительности записи.
curl -X POST https://speech-recognition.ru/api/v1/jobs/{jobId}/start \
-H "Authorization: Bearer sk_live_ваш_ключ"GET/api/v1/jobs/{jobId}
Статус и результат. Статусы: QUEUED, DOWNLOADING (для задач по ссылке), TRANSCRIBING, SUMMARIZING, DONE, FAILED.
curl https://speech-recognition.ru/api/v1/jobs/{jobId} \
-H "Authorization: Bearer sk_live_ваш_ключ"
# Ответ при DONE:
{
"job": {
"id": "clx…",
"status": "DONE",
"durationSeconds": 634,
"chargedSeconds": 660,
"trimStartSeconds": null,
"trimEndSeconds": null,
"parentJobId": null,
"continuationJobId": null,
"result": {
"text": "Полный текст расшифровки…",
"segments": [
{ "start": 0.0, "end": 4.2, "text": "…", "speaker": "SPEAKER_00" }
],
"speakerRoles": { "SPEAKER_00": "Менеджер", "SPEAKER_01": "Клиент" },
"summary": "**О чём запись:** …"
}
}
}Поля задачи:
durationSeconds — полная длительность записи в секундах; не меняется, если расшифрован только фрагмент.chargedSeconds — списано с баланса, секунд: за фактически расшифрованную часть записи с округлением вверх до минуты.trimStartSeconds, trimEndSeconds — number | null, границы расшифрованного фрагмента в секундах от начала исходного файла; null — расшифрована вся запись. Задаются только из личного кабинета при повторном запуске упавшей задачи — через API v1 обрезку запустить нельзя.parentJobId, continuationJobId — string | null. Готовый фрагмент можно дорасшифровать продолжением — отдельной задачей на нерасшифрованный остаток той же записи без повторной загрузки. У продолжения parentJobId — id первой части, у первой части continuationJobId — id продолжения; результат каждой задачи отдельный, тайминги обеих — от начала исходного файла. Запускается только из личного кабинета — через API v1 продолжение недоступно.result.segments — start и end всегда отсчитываются от начала исходного файла, в том числе у фрагмента: сегменты накладываются на исходную запись без пересчёта.canRetry — упавшую задачу можно перезапустить в личном кабинете: исходник ещё хранится в сервисе (7 дней после создания задачи — срок хранения исходника, настраивается сервисом).Остальные поля ответа (canTrim, canContinue, sourceAvailableUntil, retryCount, shareToken и подобные) — служебные, нужны личному кабинету и не входят в контракт API: их состав может меняться без предупреждения, не опирайтесь на них в интеграции.
GET/api/v1/account
Баланс аккаунта.
curl https://speech-recognition.ru/api/v1/account \
-H "Authorization: Bearer sk_live_ваш_ключ"
# Ответ:
{ "email": "…", "balanceSeconds": 18000, "balanceMinutes": 300 }Если указан callbackUrl, по завершении мы отправим на него POST с JSON-телом из полей jobId, status, mode, originalFileName, durationSeconds, chargedSeconds, trimStartSeconds, trimEndSeconds, parentJobId, continuationJobId, error и result (text, segments, speakerRoles, summary; null при ошибке). Значения те же, что в GET /api/v1/jobs/{jobId}, идентификатор приходит как jobId; служебных полей кабинета (canRetry и т. п.) в callback нет. Если задача была перезапущена на фрагменте из кабинета, придут его границы, а тайминги сегментов останутся в координатах исходного файла. Продолжение остатка, запущенное из кабинета, — отдельная задача с тем же callbackUrl: придёт свой callback с parentJobId первой части. Ответьте 2xx — иначе доставка считается неуспешной (повторов нет, статус всегда можно опросить).
Распознавание в реальном времени: вы отправляете поток аудио по WebSocket и получаете текст по мере речи — черновые фразы, финальные фразы с тайм-кодами и, при желании, построчный перевод. После завершения сессии запись автоматически уходит в обычную обработку — готовая задача с полной расшифровкой появится в GET /api/v1/jobs и в личном кабинете. Не хотите хранить запись — включите режим noRecording.
POST/api/v1/live/token
Одноразовый токен входа в сессию. Действует 60 секунд и гасится при первом использовании — запрашивайте его непосредственно перед подключением, по токену на сессию.
curl -X POST https://speech-recognition.ru/api/v1/live/token \
-H "Authorization: Bearer sk_live_ваш_ключ"
# Ответ:
{
"token": "3f9a…",
"expiresInSeconds": 60,
"wsUrl": "wss://speech-recognition.ru/api/live/ws"
}WSwss://speech-recognition.ru/api/live/ws
Первым сообщением отправьте start (текстовый JSON-фрейм). Поле lang — auto либо локаль из списка: ru-RU, en-US, tr-TR, de-DE, es-ES, fr-FR, it-IT, uk-UA; необязательный translateTo (те же локали) включает перевод финальных фраз; noRecording: true — приватный режим: сервер не сохраняет запись и не создаёт задачу пост-обработки.
{ "type": "start", "token": "3f9a…", "lang": "ru-RU", "translateTo": "en-US" }session — оно подтверждает, что сессия открыта. Аудио, отправленное раньше, сервер молча отбрасывает (узел ещё подключается, это может занять несколько секунд).{ "type": "ping" } (ответ — { "ev": "pong" }), иначе NAT может молча закрыть соединение.{ "type": "stop" }; дождитесь события session_end.{ "type": "resume", "sessionId": "…", "resumeToken": "…", "lastSeq": N } (sessionId и resumeToken — из события session, lastSeq — последний полученный вами seq, отслеживайте его сами): в течение 60 секунд сессия ждёт возврата, сервер подтвердит приём событием resumed и доиграет пропущенные финальные фразы с seq больше lastSeq. Аудио за время обрыва теряется честно — в записи будет пауза.Минимальный клиент на Node.js:
import WebSocket from 'ws';
const { token, wsUrl } = await fetch('https://speech-recognition.ru/api/v1/live/token', {
method: 'POST',
headers: { Authorization: 'Bearer sk_live_ваш_ключ' },
}).then((r) => r.json());
const ws = new WebSocket(wsUrl);
ws.on('open', () => {
ws.send(JSON.stringify({ type: 'start', token, lang: 'ru-RU' }));
});
ws.on('message', (raw, isBinary) => {
if (isBinary) return;
const msg = JSON.parse(String(raw));
if (msg.ev === 'session') {
// сессия открыта — с этого момента шлите бинарные PCM-фреймы: ws.send(pcmChunk)
}
if (msg.ev === 'partial') process.stdout.write('\r' + msg.text);
if (msg.ev === 'final') console.log('\r' + msg.text);
if (msg.ev === 'session_end') console.log('Запись ушла в обработку, jobId:', msg.jobId);
});Все события установленной сессии несут монотонный seq — по нему работает реплей при resume. Ошибки, отправленные до открытия сессии (неверный токен, bad_lang, неудачный resume), приходят без seq; pong его тоже не несёт.
session — подтверждение старта: sessionId, resumeToken (сохраните для реконнекта), balanceSeconds (число или null, если баланс не удалось прочитать), maxSessionSeconds, noRecording.resumed — подтверждение resume: sessionId, seq (текущий счётчик сервера); следом доигрываются пропущенные финальные фразы.partial — черновик текущей фразы (text, startMs); текст только дописывается, уже показанное не меняется.final — готовая фраза: text, startMs, endMs.translation — перевод финальной фразы (text, startMs, sourceSeq); может отставать, при перегрузке отдельные фразы пропускаются.billing — после каждой оплаченной минуты: chargedSeconds (оплачено с начала сессии нарастающим итогом), balanceSeconds.warning — code: low_balance | translation_lagging.session_end — сессия завершена: reason (user_stop | no_balance | timeout | idle | server_shutdown), audioMs, jobId — если запись ушла в обработку.error — терминальная ошибка (unauthorized, no_balance, capacity, bad_lang, session_exists, session_finalized и другие); соединение закрывается.402).reason: idle).401 — неверный или отозванный ключ.402 — недостаточно минут на балансе.429 — более 30 задач в час.API принимает те же форматы, что и загрузка на сайте, — из видео звуковая дорожка извлекается автоматически. Один файл — до 2 ГБ и до 4 часов записи. Подробнее о каждом формате — на отдельных страницах:
Режим передаётся в поле mode при создании задачи:
DIARIZED_SUMMARY (по умолчанию) — полный текст, разделение по спикерам с ролями, определёнными по смыслу разговора, и AI-саммари. Выбирайте для звонков, интервью и совещаний — везде, где говорят несколько человек и нужна структура разговора.TRANSCRIPT — только текст расшифровки, без диаризации и саммари. Обрабатывается быстрее; подходит для лекций, диктовок и подкастов с одним ведущим.callbackUrl, и готовая расшифровка с саммари сама придёт в вашу систему: прикрепляйте её к карточке клиента или сделки.