API

Отправляйте аудио на транскрибацию и получайте готовый текст программно. Базовый адрес: https://ruslo.app/api/v1

Аутентификация

Каждый запрос должен содержать API-ключ в заголовке Authorization. Создайте ключ в настройках аккаунта в приложении Русло.

Authorization: Bearer rsk_live_ВАШ_КЛЮЧ

1. Создать транскрипцию

POST /transcriptions — передайте ссылку на аудио. Файл должен быть доступен публично по https. В ответ придёт id задачи.

javascript
const res = await fetch('https://ruslo.app/api/v1/transcriptions', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer rsk_live_ВАШ_КЛЮЧ',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    audio_url: 'https://example.com/audio.mp3',
    language: 'ru', // необязательно
  }),
});

const { id } = await res.json();
// { "id": "...", "status": "processing", "created_at": "..." }

Параметры:

audio_url — ссылка на аудио (обязательно)
language — код языка, напр. ru (необязательно)
webhook_url — https-адрес для уведомления о готовности (необязательно)

2. Получить результат

GET /transcriptions/{id} — опрашивайте задачу, пока статус не станет completed.

javascript
const res = await fetch(`https://ruslo.app/api/v1/transcriptions/${id}`, {
  headers: { 'Authorization': 'Bearer rsk_live_ВАШ_КЛЮЧ' },
});

const data = await res.json();

if (data.status === 'completed') {
  console.log(data.text);     // весь текст
  console.log(data.segments); // сегменты с таймкодами
}

Пример ответа:

json
{
  "id": "8f3c...",
  "status": "completed",
  "language": "ru",
  "duration_seconds": 122,
  "title": "Планёрка команды",
  "text": "Полный текст транскрипции...",
  "segments": [
    { "start": 0, "end": 4.2, "text": "Привет всем", "speaker_id": "0" }
  ],
  "failure_reason": null,
  "failure_message": null,
  "created_at": "...",
  "updated_at": "..."
}

Статусы:

processing — в обработке
completed — готово
failed — ошибка (см. failure_reason)

Причины ошибки (failure_reason):

input_failed — не удалось скачать аудио по audio_url или это не корректный, распознаваемый файл. Проверьте, что ссылка доступна (не истекла и не приватная) и ведёт на поддерживаемое аудио/видео.
timeout — обработка не завершилась за отведённое время. Повторите запрос или используйте файл короче.
processing_failed — ошибка на нашей стороне. Повторите запрос; если повторяется — напишите в поддержку.

Поле failure_message содержит человекочитаемое пояснение к той же причине.

Вебхуки (необязательно)

Если передать webhook_url, мы отправим на него POST-запрос, когда транскрипция завершится — не придётся опрашивать статус. Тело запроса: { event, data }, где data совпадает с ответом из шага 2. Подпись передаётся в заголовке X-Ruslo-Signature — проверьте её своим секретом:

javascript
import crypto from 'crypto';

// rawBody — сырое тело запроса (строка), secret — ваш секрет вебхука
function isValid(rawBody, signature, secret) {
  const expected = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return signature === expected; // signature из заголовка X-Ruslo-Signature
}

Повторные попытки (retry):

• Доставка считается успешной при ответе 2xx.
• Если получатель ответил не 2xx или запрос не дошёл, мы повторяем доставку до 5 раз с увеличивающейся задержкой: 1с → 2с → 4с → 8с.
• Редиректы (3xx) не выполняются — доставка прекращается.
• Отвечайте быстро статусом 2xx. Если все попытки неуспешны, результат всё равно доступен через GET (шаг 2).