Developer Portal
Документация STT/ASR API: аутентификация, эндпоинты, форматы ответа и лимиты. Тестовый ключ выдаётся в течение часа в рабочее время — без звонка с отделом продаж.
Быстрый старт
Три шага до первого ответа: получите ключ, отправьте файл, заберите транскрипт. Ниже — минимальный работающий запрос.
curl -X POST https://api.aisupervisor.kz/api/v1/stt/upload \
-H "X-API-Key: $AIBS_API_KEY" \
-F "file=@dialog.mp3" \
-F "language=kz"
# {"recording_id": "b68257a2-5e8c-445a-ba30-b41db6c5d6e5",
# "status": "completed",
# "transcript": {"text": "Сәлеметсіз бе, менің атым Әсел…"}}import requests, time
BASE = "https://api.aisupervisor.kz"
H = {"X-API-Key": API_KEY}
with open("dialog.mp3", "rb") as f:
r = requests.post(f"{BASE}/api/v1/stt/upload",
headers=H,
files={"file": f},
data={"language": "kz"},
timeout=40)
data = r.json()
if data["status"] == "completed":
print(data["transcript"]["text"])
else:
# Not ready in time — poll by recording_id.
rid = data["recording_id"]
for _ in range(12):
time.sleep(5)
t = requests.get(f"{BASE}/api/v1/recordings/transcript",
headers=H, params={"recording_id": rid}, timeout=15)
if t.status_code == 200:
print(t.json()["transcript"]["text"])
breakimport { readFileSync } from "node:fs"
const BASE = "https://api.aisupervisor.kz"
const H = { "X-API-Key": process.env.AIBS_API_KEY }
const form = new FormData()
form.append("file", new Blob([readFileSync("dialog.mp3")]), "dialog.mp3")
form.append("language", "kz")
const res = await fetch(`${BASE}/api/v1/stt/upload`, {
method: "POST",
headers: H,
body: form,
})
const data = await res.json()
if (data.status === "completed") {
console.log(data.transcript.text)
} else {
// Not ready in time — poll by recording_id.
const url = `${BASE}/api/v1/recordings/transcript?recording_id=${data.recording_id}`
for (let i = 0; i < 12; i++) {
await new Promise((r) => setTimeout(r, 5000))
const t = await fetch(url, { headers: H })
if (t.ok) {
console.log((await t.json()).transcript.text)
break
}
}
}Базовый адрес — https://api.aisupervisor.kz. Все запросы по HTTPS, загрузка аудио — multipart/form-data, ответы в JSON с кодировкой UTF-8 (транскрипт может содержать кириллицу).
Запрос к /stt/upload может выполняться до 25–30 секунд. Установите таймаут HTTP-клиента не меньше 30 секунд — значения по умолчанию у большинства библиотек ниже, и это самая частая причина «сервис не отвечает» на первой интеграции.
Аутентификация
Поддерживаются два способа. Для серверной интеграции рекомендуется API-ключ: он передаётся в заголовке X-API-Key: <ваш_ключ> и привязан к вашей организации (tenant).
Второй способ — JWT от имени пользователя: POST /api/v1/auth/login с email и password возвращает access_token, refresh_token и expires_in (по умолчанию 3600 секунд). Токен передаётся как Authorization: Bearer <access_token>.
Ключ — это секрет: он даёт доступ к вашей квоте и вашим записям. Не кладите его в клиентский код мобильного приложения или фронтенда и не публикуйте в репозиториях; запрос к API должен уходить с вашего сервера, из защищённого конфига.
Эндпоинты
| Метод | Путь | Назначение |
|---|---|---|
POST | /api/v1/stt/upload | Загрузить аудиофайл на транскрибацию. Отвечает готовым текстом или, если не успел, отдаёт recording_id. |
GET | /api/v1/recordings/transcript | Забрать транскрипт по recording_id, если /stt/upload вернул статус queued. |
POST | /api/v1/auth/login | Получить JWT по email и паролю — для доступа от имени пользователя вместо API-ключа. |
Загрузка идёт одним запросом: POST /api/v1/stt/upload принимает поля file и language (kz или ru, поле обязательное) и обычно отвечает готовым текстом за несколько секунд. Если результат не успел подготовиться, в ответе придёт status: "queued" и recording_id, по которому транскрипт забирается отдельным запросом.
Поддерживаемые форматы аудио
| Расширение | MIME |
|---|---|
mp3 | audio/mpeg |
wav | audio/wav |
ogg | audio/ogg |
flac | audio/flac |
m4a | audio/mp4 |
webm | audio/webm |
Формат ответа
Ответ всегда содержит recording_id и status. Текст приходит в transcript.text — но только при status: "completed", поэтому читать это поле без проверки статуса нельзя.
{
"recording_id": "b68257a2-5e8c-445a-ba30-b41db6c5d6e5",
"status": "completed",
"transcript": { "text": "Сәлеметсіз бе, менің атым Әсел, қош келдіңіз..." }
}Если результат ещё не готов:
{
"recording_id": "b68257a2-5e8c-445a-ba30-b41db6c5d6e5",
"status": "queued",
"message": "Transcription not ready yet. Retry GET /api/v1/recordings/transcript?recording_id=..."
}| Поле | Тип | Описание |
|---|---|---|
recording_id | string (UUID) | Идентификатор записи. По нему повторно запрашивается транскрипт. |
status | string | completed · queued · processing · failed |
transcript | object | Объект с полем text. Присутствует при completed. |
error | string | Причина сбоя при failed. |
message | string | Подсказка, если результат ещё не готов. |
Рекомендуемый сценарий
- Получите API-ключ (или войдите через
/auth/loginи используйте JWT). - Отправьте аудио на
POST /api/v1/stt/upload, указавlanguage. - При
status: "completed"заберите текст изtranscript.text. - При
queuedсохранитеrecording_idи через несколько секунд запроситеGET /api/v1/recordings/transcript, повторяя с интервалом 5–10 секунд. - При
failedповторите загрузку; при повторных сбоях — в поддержку.
Лимиты и тарификация
| Параметр | Тестовый ключ | Коммерческие тарифы |
|---|---|---|
| Объём | 60 минут аудио или 100 запросов | По тарифу, от пакета минут |
| Размер файла | до 100 МБ | Согласуется |
| Длительность файла | до 2 часов | Согласуется |
| Параллельные задачи | 3 | Под профиль нагрузки |
| Скорость обработки | x30 | до x60–x80 на выделенных серверах |
Тарификация — по минутам обработанного аудио, округление вверх до минуты. Подробности тарифов на странице STT Core Engine.
Коды ошибок
| Код | Причина | Повторять? |
|---|---|---|
401 | missing_api_key — ключ или токен не передан | нет |
401 | invalid_api_key — ключ неверный или отозван | нет |
422 | Не передан language или указано недопустимое значение (допустимо kz, ru) | нет |
404 | recording_not_found — запись не найдена или принадлежит другой организации | нет |
404 | transcript_not_available — транскрипт ещё не готов | да, позже |
5xx | service_unavailable — временный сбой сервиса | да, с экспоненциальной паузой |
Повторять стоит 5xx с экспоненциальной паузой и transcript_not_available — просто позже. Остальные коды при повторе вернут тот же ответ.
Технический FAQ
Какой у вас WER и на чём он измерен?
Менее 10% на локальном сленге и смешанной казахско-русской речи. Измерение проводится на собственном тестовом наборе из реальных оффлайн-диалогов, а не на чистой студийной речи — на подготовленных записях цифра заметно ниже, но она ничего не говорит о работе в зале с фоновым шумом. Методику и разбивку по доменам отдаём по запросу вместе с тестовым ключом: считаем, что заявленную точность разумно проверять на своих данных.
Какая задержка в потоковом режиме?
Частичные гипотезы приходят в пределах нескольких сотен миллисекунд после конца фразы, финальные — после закрытия сегмента. Для пакетной обработки ориентир другой: скорость x30 к длительности аудио на базовой конфигурации и x60–x80 на выделенных серверах. Час записи на базовой обрабатывается примерно за две минуты.
Какие лимиты на подключения и частоту запросов?
На тестовом ключе — 100 запросов или 60 минут аудио, чего достаточно для интеграционного прототипа. На коммерческих тарифах частота и количество параллельных соединений согласуются под ваш профиль нагрузки: для потоков свыше миллиона минут в месяц резервируются выделенные мощности, и лимит становится вопросом ёмкости, а не тарифа.
Как вы работаете со смешанной казахско-русской речью?
Модель обучена на смешанной речи изначально, а не собрана из двух одноязычных с переключателем. Переключение между языками внутри одной реплики — норма для казахстанского говорящего, и именно на нём заметнее всего проседают глобальные движки: они распознают вставку на другом языке как искажённое слово родного. Поле language при запросе всё равно обязательно — оно задаёт основной язык записи (kz или ru), а вставки на втором языке модель разбирает сама.
Что происходит с моими аудиофайлами?
В облачном режиме файл хранится столько, сколько нужно для обработки и выдачи результата, и удаляется по вашему запросу или по истечении срока хранения в тарифе. Записи клиентов не используются для дообучения моделей без отдельного письменного согласия. Если этого недостаточно — существует On-Premise: развертывание внутри вашего периметра, где вопрос хранения решаете только вы.
Можно ли дообучить модель под нашу терминологию?
Да. Fine-tuning под отраслевую лексику — медицинскую, банковскую, техническую — выполняется на ваших данных. Обучение проходит в нашей закрытой корпоративной среде из-за требований к GPU; датасет не покидает её и не смешивается с чужими.
Получить ключ
Опишите стек и задачу — этого достаточно, чтобы выделить мощности и выдать ключ с тестовым лимитом. В рабочее время это занимает около часа.
Тестовый доступ
Ключ за час, без звонка с продажами
Коллекция Postman и публичные примеры на GitHub появятся здесь же — сейчас готовим репозитории.