REST API · отдельный ₽-баланс, от 0,50 ₽/мин

Транскрибация через API
— за 30 строк кода

REST-эндпоинты с JSON-ответами и авторизацией через X-API-Key. Загружайте файлы, получайте текст, саммари, субтитры SRT/VTT — в свой бэкенд.

Quick start

3 шага от файла до субтитров

Загрузка, поллинг статуса, экспорт SRT — всё через 3 curl-запроса.

# 1. Загрузить файл
curl -X POST https://wonderscribe.pro/api/v1/transcribe \
 -H "X-API-Key: ws_..." \
 -F "file=@interview.mp3" \
 -F "language=ru"
# → {"task_id": "abc-123", "status": "pending"}

# 2. Поллить статус (раз в 10-15 секунд)
curl -H "X-API-Key: ws_..." \
 https://wonderscribe.pro/api/v1/tasks/abc-123
# → {"status": "completed", "progress": 100}

# 3. Экспортировать субтитры SRT
curl -H "X-API-Key: ws_..." \
 "https://wonderscribe.pro/api/v1/tasks/abc-123/export?format=srt"
# → {"content": "1\n00:00:00,000 --> 00:00:04,200\n...", "format": "srt"}
Эндпоинты

16 методов для всего флоу

Method Endpoint Назначение
GET /api/v1/account Инфо об аккаунте, план, использовано минут
POST /api/v1/transcribe Загрузить файл + старт транскрибации
Нет денег на балансе → status: "awaiting_balance", файл ждёт пополнения
POST /api/v1/transcribe-url Транскрибация по ссылке: YouTube, VK Видео, RuTube, Дзен, Яндекс.Диск или прямой URL на аудио/видео
GET /api/v1/tasks Список задач (пагинация: limit, offset, status)
GET /api/v1/tasks/{id} Статус задачи + progress %
GET /api/v1/tasks/{id}/result Полный результат: текст, сегменты, саммари
GET /api/v1/tasks/{id}/export?format=… Экспорт: txt · srt · vtt · json
POST /api/v1/tasks/{id}/cancel Отмена pending/processing задачи
POST /api/v1/api-key/generate Ротация ключа (старый — invalidated)
POST /api/v1/meeting AI-бот на встречу (Zoom/Meet/Teams/Telemost): сейчас или по расписанию
Пустой баланс → 402: бот не отправляется
GET /api/v1/meeting/{bot_id} Статус бота + task_id записи когда готово
DELETE /api/v1/meeting/{bot_id} Отменить запланированную или остановить идущую запись
GET /api/v1/dictionary Словарь терминов аккаунта — что применяется к расшифровкам
PUT /api/v1/dictionary Заменить словарь целиком
POST /api/v1/dictionary Добавить термины к существующим
DELETE /api/v1/dictionary Очистить свой словарь
POST /meeting

AI-бот на встречу

Из вашей CRM отправьте бота на онлайн-встречу — он подключится, запишет и автоматически расшифрует. Заберите результат поллингом GET /api/v1/meeting/{bot_id}/api/v1/tasks/{task_id}/result или получите webhook, когда транскрипт готов. Тело запроса — JSON или form-данные (подходит для amoCRM, Bitrix24, Make, Zapier «из коробки»).

Полная инструкция: запись встреч из CRM →

Поле Тип Default Описание
meeting_url *stringСсылка на встречу (Zoom, Google Meet, Teams, Telemost, Webex)
consent_acknowledged *boolПодтверждение, что участники уведомлены о записи и согласны на обработку ПДн (152-ФЗ)
start_atISO 8601сейчасВремя запуска (напр. 2026-06-02T15:00:00+03:00). В будущем → бот зайдёт по расписанию. Макс. +30 дней
webhook_urlhttps URLCallback, куда придёт POST когда транскрипт готов. Тело подписано HMAC-SHA256 заголовком X-WS-Signature ключом webhook_secret из ответа

* — обязательное поле · ответ: {bot_id, status, scheduled_start_at?, webhook_secret?}

/dictionary

Словарь узких терминов

Термины из словаря применяются ко всем расшифровкам аккаунта — и к тем, что приходят через API. Это помогает, когда в записях звучат имена, аббревиатуры и слова, которых нет в обычной речи.

Запрос Что делает
GET /api/v1/dictionaryТекущий список: terms, count, chars, limit_chars, limit_terms, effective_terms, ignored_terms
PUT /api/v1/dictionaryЗаменить целиком. Тело: {"terms": ["ЭКГ", "Дентиум"]} либо {"text": "ЭКГ, Дентиум"}
POST /api/v1/dictionaryДобавить к существующим, дубликаты отбрасываются
DELETE /api/v1/dictionaryОчистить свой словарь
POST /api/v1/dictionary/previewПроверка без пересчёта: {"task_id": "...", "terms": [...]} — что новый список изменил бы в уже готовой расшифровке. Ничего не сохраняет, минуты не тратит
limit_termsСколько терминов реально применяется к записи (первые по порядку). Хранить можно больше — ignored_terms покажет, какие в обработку не пойдут
curl -X PUT https://wonderscribe.pro/api/v1/dictionary \
  -H "X-API-Key: $WS_KEY" -H "Content-Type: application/json" \
  -d '{"terms": ["трохантерит", "гистероскопия", "Дентиум"]}'

# разовые термины только для одной записи — прямо в загрузке:
curl -X POST https://wonderscribe.pro/api/v1/transcribe \
  -H "X-API-Key: $WS_KEY" \
  -F "file=@lecture.mp3" -F "prompt=трохантерит, вертлужная впадина"

Разделители в text — запятая, точка с запятой, перенос строки. Лимит словаря — 20 000 символов; при превышении приходит 413, список не обрезается молча. У команды участник без своего словаря наследует список владельца — в ответе это поле inherited_from_team_owner.

POST /transcribe

Параметры загрузки

Поле Тип Default Описание
file *fileАудио/видео файл (.mp3, .wav, .mp4, .mov, .m4a, .ogg, .flac, .webm и др.)
languagestringruISO-код языка. 99 поддерживаемых
num_speakersintautoКол-во спикеров (1-6). Если известно — точность выше
promptstringИмена, термины, аббревиатуры — для повышения точности
webhook_urlhttps URLКуда прислать POST, когда расшифровка готова — чтобы не опрашивать статус. Тело подписано HMAC-SHA256 в заголовке X-WS-Signature ключом webhook_secret из ответа
domainstringlegal / medical / tech — для domain-prompts
summary_templatestringgeneral92 шаблона: meeting / lecture / interview / podcast / др.

* — обязательное поле

Жизненный цикл

Что происходит с задачей

POST /transcribe возвращает task_id сразу и не ждёт расшифровки. Дальше опрашивайте GET /tasks/{id} — раз в 5–10 секунд достаточно, обработка часа записи занимает около 5 минут.

status Что значит Что делать
pending Принята, ждёт свободный GPU. В ответе есть queue_position и queue_total Продолжать опрос
pending
awaiting_balance: true
Денег на API-балансе не хватило. Файл сохранён, в очередь не поставлен Пополнить баланс — расшифровка стартует сама в течение нескольких минут. Повторно загружать файл не нужно
processing Идёт обработка. progress — проценты, stage — текущий этап Продолжать опрос
completed Готово GET /tasks/{id}/result или /export?format=srt
failed Ошибка. Причина — в поле error Минуты за упавшую задачу не списываются

Поле queue_state уточняет состояние: working · queued · not_started · done · awaiting_balance.

Повторные отправки — заголовок Idempotency-Key. Передайте свой уникальный ключ в POST /transcribe: при повторе с тем же ключом вернётся тот же task_id, а не вторая задача. Спасает при ретраях по таймауту — загрузка большого файла легко переживает разрыв соединения уже после того, как сервер её принял.

Время ответа

Сколько ждать расшифровку

Обработка не потоковая: файл считается целиком, и текст приходит одним ответом. Ниже — замер по реальным задачам за 30 дней.

Длина записи Обычно В 9 случаях из 10
до 1 минуты~30 секунддо 1 минуты
1–10 минут~1,5 минутыдо 2,5 минут
10–60 минут~7 минутдо 11 минут
больше часа~13 минутдо 24 минут

На коротких записях время почти не зависит от длины: и 4 секунды, и 20 занимают примерно одинаково — это постоянные расходы на запуск, а не пропорция. Указано время самой обработки; когда все GPU заняты длинными файлами, добавляется ожидание в очереди — в редких случаях до нескольких минут. Чтобы не опрашивать статус, передайте webhook_url при загрузке — пришлём POST, как только текст готов.

Ошибки и лимиты

Что вернётся, если что-то не так

Тело ошибки — {"detail": {"error_code": "...", "message": "..."}}. Ветвитесь по error_code, а не по тексту: текст может меняться.

HTTP error_code Когда
401Ключ не передан, недействителен или API не включён в кабинете
402api_balance_exhaustedНет денег на балансе при отправке бота на встречу. Для POST /transcribe отказа нет — задача ждёт пополнения
409Параллельный запрос с тем же Idempotency-Key ещё выполняется. Повторить чуть позже
413audio_too_long_api_balanceЗапись длиннее 4 часов. Разбейте на части
413Файл больше 8 ГБ
429Больше 20 задач одновременно в работе. Дождитесь завершения части
503service_unavailableВременный сбой. Повторить с экспоненциальной задержкой

Лимиты. Файл до 8 ГБ и до 4 часов; одновременно в работе до 20 задач на аккаунт. Запросов в минуту на ключ: /transcribe — 10, /meeting — 20, регенерация саммари — 5, остальные (чтение статуса, результата, словарь) — 60. Превышение — 429. Нужны другие пороги — напишите.

Python

Полный end-to-end пример

Загрузка → поллинг → результат + субтитры. Не хотите опрашивать — передайте webhook_url при загрузке и ждите POST с task_id.

import requests, time

API_KEY = "ws_..."
BASE  = "https://wonderscribe.pro/api/v1"
HEADERS = {"X-API-Key": API_KEY}

# 1) Upload
with open("interview.mp3", "rb") as f:
  r = requests.post(
    f"{BASE}/transcribe",
    headers=HEADERS,
    files={"file": f},
    data={"language": "ru", "num_speakers": 2},
  )
task_id = r.json()["task_id"]
print("task_id:", task_id)

# 2) Poll status
while True:
  s = requests.get(f"{BASE}/tasks/{task_id}", headers=HEADERS).json()
  print(s["status"], s.get("progress", 0), "%")
  if s["status"] in ("completed", "failed"): break
  time.sleep(10)

# 3) Get text + SRT
result = requests.get(f"{BASE}/tasks/{task_id}/result", headers=HEADERS).json()
print(result["text"])

srt = requests.get(f"{BASE}/tasks/{task_id}/export?format=srt", headers=HEADERS).json()
with open("out.srt", "w") as f:
  f.write(srt["content"])
// Node.js 18+ — fetch и FormData уже встроены
import fs from "node:fs";

const API_KEY = "ws_...";
const BASE = "https://wonderscribe.pro/api/v1";
const H = { "X-API-Key": API_KEY };

// 1) Загрузка
const fd = new FormData();
fd.append("file", new Blob([fs.readFileSync("interview.mp3")]), "interview.mp3");
fd.append("language", "ru");
fd.append("num_speakers", "2");

let r = await fetch(`${BASE}/transcribe`, { method: "POST", headers: H, body: fd });
const { task_id, status } = await r.json();

// Денег не хватило — файл уже сохранён, задача поедет после пополнения
if (status === "awaiting_balance") console.warn("ждём пополнения баланса");

// 2) Поллинг
let s;
do {
  await new Promise((ok) => setTimeout(ok, 5000));
  s = await (await fetch(`${BASE}/tasks/${task_id}`, { headers: H })).json();
  console.log(s.status, s.progress ?? 0, "%");
} while (!["completed", "failed"].includes(s.status));

// 3) Результат и субтитры
const res = await (await fetch(`${BASE}/tasks/${task_id}/result`, { headers: H })).json();
console.log(res.text.slice(0, 300));

const srt = await (await fetch(`${BASE}/tasks/${task_id}/export?format=srt`, { headers: H })).json();
fs.writeFileSync("interview.srt", srt.content);
Цены

Отдельный ₽-баланс

REST API — не часть тарифов (Старт/Базовый/Профи/Команда). Отдельный prepaid-баланс, посекундная тарификация, прогрессивная шкала: чем больше минут за месяц — тем дешевле. Диаризация, пунктуация и таймкоды по фразам включены в цену; посадочного платежа нет.

Объём в месяц ₽/мин
первые 10 000 мин 0,50 ₽
10 000 – 50 000 мин 0,44 ₽
50 000 – 200 000 мин 0,40 ₽
свыше 200 000 мин 0,36 ₽

Ступени считаются за календарный месяц, переход между ними — автоматический. Минимальное пополнение — 500 ₽.

Кончились деньги — файл не теряется. POST /transcribe вернёт status: "awaiting_balance" и сохранит загрузку: расшифровка начнётся сама в течение нескольких минут после пополнения, повторно загружать не нужно. Опрашивать — обычным GET /tasks/{id} (там будет awaiting_balance: true).

Потоковое распознавание (реальное время, живые звонки) — скоро. Сейчас доступна пакетная обработка: загруженный файл или готовая запись.