Помощь

Центр помощи

Короткий справочник по первой загрузке и экспорту.

Для разработчиков

Справочник по внешнему API

Справочник по REST API Vibe2Text для интеграций по персональному ключу (v2t_…). Все примеры — готовые curl-команды: загрузка файлов, расшифровка, отчёты и экспорт, импорт по ссылке, запись звонков и вебхуки.

Запросы и ответы — в формате JSON, только по HTTPS; все пути начинаются с /api/v1. Ключ открывает методы, перечисленные ниже; удаление, ручное редактирование, чат, поиск и оплата доступны только из веб-кабинета. Базовый адрес — https://api.vibe2text.ru

Начало работы: ключ и аутентификация

Каждый запрос авторизуется одним персональным API-ключом вида v2t_… Создайте ключ один раз и подставляйте его в заголовок каждого запроса.

  • Создать ключ. Ключи создаются только из веб-интерфейса под своей учётной записью: Настройки → API-ключи → «Создать», укажите имя и нужные права (scopes). Полное значение v2t_… показывается один раз — скопируйте его сразу. Можно держать до 5 активных ключей; список — GET /api/v1/user/api-keys/, отзыв — DELETE /api/v1/user/api-keys/:id (только из сессии, не по ключу).
  • Передать ключ. Подставляйте в каждый запрос заголовок `Authorization: Bearer v2t_ВАШ_ТОКЕН`.
  • Права (scopes). Ключу выдаётся набор прав. Запрос к не-разрешённому для ключей эндпоинту вернёт 403 с просьбой войти через сессию; нехватка нужного права — 403 «требуется scope X». Право `*` открывает все права из таблицы ниже.
  • По защищённому каналу. Отправляйте запросы по HTTPS. По обычному HTTP ключи передавать небезопасно.

Запрос

# Create a key from a signed-in web session:
#   Settings → API keys → Create (give it a name + the scopes it needs).
# The full v2t_... value is shown ONCE — copy it immediately.
# Up to 5 active keys; revoke from the same screen (session only).

# Pass the key on every request via the Authorization header.
curl https://api.vibe2text.ru/api/v1/transcripts/?limit=2 \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN'

Ответ

{
  "items": [
    {
      "id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff",
      "organization_id": null,
      "file_id": "7040f5b9-2492-4934-b284-f5eb715f6e0d",
      "title": "voice.ogg",
      "language": "",
      "detected_language": null,
      "status": "completed",
      "progress": 1.0,
      "error": null,
      "error_code": null,
      "error_hint": null,
      "duration_s": 3.44,
      "word_count": 10,
      "speaker_count": 1,
      "smart_reports_count": 2,
      "credits_charged": 0,
      "created_at": "2026-06-04T00:17:34Z",
      "completed_at": "2026-06-04T00:17:50Z",
      "shared": false,
      "share_role": null,
      "owner_name": null
    }
  ],
  "meta": { "total": 24, "skip": 0, "limit": 2 }
}
Права (scopes)

16 значений, сгруппированных в 8 семейств. Большинству ресурсов соответствуют права на чтение (:read) и на запись (:write). Выдавайте ключу только то, что ему нужно.

СемействоЧтениеЗаписьДля чего
Расшифровкиtranscripts:readtranscripts:writeЗапуск расшифровки и чтение текста, сегментов, спикеров.
Файлыfiles:readfiles:writeМногочастная загрузка записей и статус загрузки.
Импорт по ссылкеimports:readimports:writeИмпорт аудио/видео по URL (YouTube, подкасты и т. п.).
Экспортыexports:readexports:writeЭкспорт расшифровок в docx, pdf, srt и другие форматы.
Smart Reportreports:readreports:writeСоздание и чтение AI-отчётов по расшифровкам.
Базы знанийkb:readkb:writeУправление базами знаний и добавление записей.
Вебхукиwebhooks:readwebhooks:writeПодписка на события и просмотр доставок.
Записи звонковrecordings:readrecordings:writeЗапуск бота-записи встреч и статус задания.

Право `*` эквивалентно выдаче всех перечисленных прав сразу.

Основной сценарий: загрузка → расшифровка → результат

Базовый путь от файла до готового текста — шесть шагов. Каждый шаг помечен нужным правом.

  1. 1. Инициировать многочастную загрузку и получить file_id и список частей.

    Запрос

    # 1) Start a multipart upload (scope files:write; rate-limit 10/h).
    #    Optionally send an Idempotency-Key (<=128 chars) — reusing it within
    #    60s returns the same upload instead of starting a new one.
    curl -X POST https://api.vibe2text.ru/api/v1/files/upload-init \
      -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
      -H 'Content-Type: application/json' \
      -H 'Idempotency-Key: my-upload-2026-06-01' \
      -d '{
        "filename": "interview.mp3",
        "size_bytes": 25400000,
        "mime_type": "audio/mpeg"
      }'

    Ответ

    {
      "file_id": "75ad1a37-8945-4613-afb2-5748f7a47cd1",
      "upload_id": "1ea0eeef1f77d8dc",
      "s3_key": "files/<user_id>/75ad1a37-8945-4613-afb2-5748f7a47cd1.mp3",
      "upload_kind": "multipart_s3",
      "chunk_size": 8388608,
      "parts": [
        {
          "part_no": 1,
          "url": "https://uploads.vibe2text.ru/<pre-signed-put-url>",
          "expires_at": "2026-06-04T01:41:17Z"
        }
      ],
      "expires_at": "2026-06-04T01:41:17Z",
      "presigned_put_url": "https://uploads.vibe2text.ru/<pre-signed-put-url>"
    }
  2. 2. Залить каждую часть PUT-запросом по выданной ссылке загрузки и сохранить ETag каждой части.

    Запрос

    # 2) PUT each chunk straight to the pre-signed upload url and capture its ETag.
    #    Pre-signed urls expire after 3600s — re-presign an expired part with
    #    POST /files/upload-init/{file_id}/parts/{part_no}/presign.
    #    GET /files/{file_id}/upload-status lists which parts still need bytes.
    curl -X PUT "<parts[0].url>" \
      --upload-file ./chunk-1.bin \
      -D - -o /dev/null
    # Grab the ETag header from each response.

    Ответ

    HTTP/1.1 200 OK
    ETag: "9b2cf535f27731c974343645a3985328"
    # Save the ETag of each part for upload-complete.
  3. 3. Завершить загрузку, передав ETag всех частей.

    Запрос

    # 3) Finalise the upload with every part's ETag (scope files:write).
    curl -X POST https://api.vibe2text.ru/api/v1/files/upload-complete \
      -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
      -H 'Content-Type: application/json' \
      -d '{
        "file_id": "75ad1a37-8945-4613-afb2-5748f7a47cd1",
        "parts": [ { "part_no": 1, "etag": "\"9b2cf5...\"" } ]
      }'

    Ответ

    {
      "file_id": "75ad1a37-8945-4613-afb2-5748f7a47cd1",
      "s3_key": "files/<user_id>/75ad1a37...mp3",
      "size": 2048000,
      "status": "ready"
    }
  4. 4. Запустить расшифровку по file_id.

    Запрос

    # 4) Start transcription (scope transcripts:write). file_id is required.
    #    Omit "language" to auto-detect; "diarize" defaults to true.
    #    Set "auto_smart_report": true to also queue a summary automatically.
    curl -X POST https://api.vibe2text.ru/api/v1/transcripts/ \
      -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
      -H 'Content-Type: application/json' \
      -d '{ "file_id": "75ad1a37-8945-4613-afb2-5748f7a47cd1", "title": "Interview", "diarize": true }'

    Ответ

    {
      "id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff",
      "file_id": "75ad1a37-8945-4613-afb2-5748f7a47cd1",
      "title": "Interview",
      "status": "pending",
      "progress": 0.0,
      "created_at": "2026-06-04T00:17:34Z"
    }
  5. 5. Опрашивать статус, пока он не станет completed.

    Запрос

    # 5) Poll status until it is "completed" (scope transcripts:read).
    curl https://api.vibe2text.ru/api/v1/transcripts/{id}/status \
      -H 'Authorization: Bearer v2t_YOUR_TOKEN'

    Ответ

    {
      "id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff",
      "status": "completed",
      "progress_percent": 100
    }
  6. 6. Забрать результат: полный объект или сегменты плюс список спикеров.

    Запрос — /segments

    # 6) Read the result (scope transcripts:read). Either pull the full
    #    payload, page through segments, or read the speaker list.
    curl "https://api.vibe2text.ru/api/v1/transcripts/{id}/segments?limit=2&include_words=true" \
      -H 'Authorization: Bearer v2t_YOUR_TOKEN'

    Ответ

    {
      "items": [
        {
          "id": "41d7346e-6d54-4551-b7e7-73d320740254",
          "seq": 1,
          "start_s": 0.48,
          "end_s": 3.44,
          "speaker_id": "3baad45e-3631-48bb-927d-5abff2351029",
          "text": "Один, два, три, четыре, пять, шесть, семь, восемь, девять, десять.",
          "confidence": 1.0,
          "edited": false,
          "words": [
            { "start_s": 0.48, "end_s": 0.88, "text": "Один,", "confidence": null },
            { "start_s": 0.96, "end_s": 1.2, "text": "два,", "confidence": null }
          ],
          "language": "auto"
        }
      ],
      "total": 1,
      "offset": 0,
      "limit": 2
    }

    Запрос — /speakers

    curl https://api.vibe2text.ru/api/v1/transcripts/{id}/speakers \
      -H 'Authorization: Bearer v2t_YOUR_TOKEN'

    Ответ

    [
      {
        "id": "3baad45e-3631-48bb-927d-5abff2351029",
        "label": "S1",
        "name": "Спикер 1",
        "avatar_color": "#4F46E5",
        "speaking_seconds": 0
      }
    ]

Альтернативный способ загрузки: вместо шагов 1–4 можно отправить ссылку через POST /source-imports/ или запустить запись встречи через POST /recording-jobs/ — затем опрашивать задание и прочитать появившийся transcript_id, как в шаге 6.

Справочник по ресурсам

Полный список эндпоинтов, доступных по ключу, с методом, путём, нужным правом и назначением. Все пути относятся к префиксу /api/v1.

Файлы

files:write / files:read

Многочастная загрузка записей. upload-init возвращает file_id, upload_id, chunk_size и список частей parts (part_no + url + expires_at).

  • POST/files/upload-init— запросить загрузку (filename, size_bytes, mime_type?, sha256?); лимит 10/час; Idempotency-Key на 60 с
  • POST/files/upload-init/:file_id/parts/:part_no/presign— пере-подписать просроченную часть
  • POST/files/upload-complete— завершить загрузку (file_id, parts (part_no + etag))
  • GET/files/:id— метаданные файла
  • GET/files/:id/download-url— ссылка на скачивание
  • GET/files/:id/upload-status— какие части ещё нужно догрузить

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

# POST /files/upload-init →
{
  "file_id": "75ad1a37-8945-4613-afb2-5748f7a47cd1",
  "upload_id": "1ea0eeef1f77d8dc",
  "s3_key": "files/<user_id>/75ad1a37-...-f5eb715f6e0d.mp3",
  "upload_kind": "multipart_s3",
  "chunk_size": 8388608,
  "parts": [
    { "part_no": 1, "url": "https://uploads.vibe2text.ru/<pre-signed-put-url>", "expires_at": "2026-06-04T01:41:17Z" }
  ],
  "expires_at": "2026-06-04T01:41:17Z",
  "presigned_put_url": "https://uploads.vibe2text.ru/<pre-signed-put-url>"
}

# POST /files/upload-complete →
{ "file_id": "75ad1a37-...", "s3_key": "files/<user_id>/75ad1a37...mp3", "size": 2048000, "status": "ready" }

Расшифровки — чтение

transcripts:read

Чтение расшифровок и связанных данных. Идентификаторы ASR-моделей в ответах не отдаются.

  • GET/transcripts/— список с фильтрами (skip, limit≤200, status, q, language, date_from/to, speaker, tag, smart, sort)
  • GET/transcripts/:id— полный объект + сегменты + спикеры
  • GET/transcripts/:id/meta— только метаданные
  • GET/transcripts/:id/status— опрос статуса
  • GET/transcripts/:id/segments— сегменты (offset, limit≤2000, include_words)
  • GET/transcripts/:id/speakers— спикеры
  • GET/transcripts/:id/chapters— главы
  • GET/transcripts/:id/action-items— задачи
  • GET/transcripts/:id/annotations— аннотации
  • GET/transcripts/:id/content-events— события содержимого
  • GET/transcripts/:id/scope-config— конфигурация
  • GET/transcripts/:id/suggestions— подсказки

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

# GET /transcripts/?limit=2 →
{
  "items": [
    {
      "id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff",
      "file_id": "7040f5b9-2492-4934-b284-f5eb715f6e0d",
      "title": "voice.ogg",
      "status": "completed",
      "progress": 1.0,
      "duration_s": 3.44,
      "word_count": 10,
      "speaker_count": 1,
      "smart_reports_count": 2,
      "created_at": "2026-06-04T00:17:34Z",
      "completed_at": "2026-06-04T00:17:50Z",
      "shared": false
    }
  ],
  "meta": { "total": 24, "skip": 0, "limit": 2 }
}

# GET /transcripts/{id}/meta → (same item fields) +
"file": {
  "id": "7040f5b9-2492-4934-b284-f5eb715f6e0d",
  "name": "voice.ogg",
  "mime": "audio/mp4",
  "size": 13041,
  "public_url": "https://media.vibe2text.ru/<pre-signed-stream-url>"
}

# GET /transcripts/{id}/status →
{ "id": "9f3e4d3a-...", "status": "completed", "progress_percent": 100 }

# GET /transcripts/{id}/speakers →
[ { "id": "3baad45e-...", "label": "S1", "name": "Спикер 1", "avatar_color": "#4F46E5", "speaking_seconds": 0 } ]

Расшифровки — запись

transcripts:write

Только создание расшифровки и запуск AI-обработки (правки текста вручную по ключу недоступны).

  • POST/transcripts/— создать (file_id обязателен; title?, language?, diarize=true, auto_smart_report=false, clip_start_s?, clip_end_s?)
  • POST/transcripts/:id/detect-speakers— определить спикеров
  • POST/transcripts/:id/generate-chapters— сгенерировать главы
  • POST/transcripts/:id/speakers/auto-name— авто-именование спикеров
  • POST/transcripts/:id/chapters/regenerate— пересобрать главы
  • POST/transcripts/:id/action-items/extract— извлечь задачи

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

# POST /transcripts/ →
{
  "id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff",
  "file_id": "75ad1a37-8945-4613-afb2-5748f7a47cd1",
  "title": "Interview",
  "status": "pending",
  "progress": 0.0,
  "created_at": "2026-06-04T00:17:34Z"
}

Экспорты

exports:read / exports:write

Экспорт расшифровок в файл. Форматы: docx, pdf, srt, vtt, txt, json, md, xlsx.

  • POST/exports/— поставить экспорт (transcript_id, format)
  • GET/exports/— список (?transcript_id)
  • GET/exports/:id— опрос статуса
  • GET/exports/:id/download— ссылка (url, expires_in)
  • POST/transcripts/:id/exports— вложенный запуск экспорта
  • GET/transcripts/:id/exports— вложенный список экспортов

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

# POST /exports/ →
{
  "id": "b0d7ef8b-1f21-4448-8b50-29e3d06df0b8",
  "transcript_id": "9f3e4d3a-...",
  "format": "pdf",
  "status": "pending",
  "size_bytes": null,
  "error": null,
  "expires_at": "2026-06-11T00:41:18Z",
  "created_at": "2026-06-04T00:41:18Z"
}

# GET /exports/{id} → (status becomes "ready", size_bytes filled)
{ "id": "b0d7ef8b-...", "status": "ready", "size_bytes": 25603, "format": "pdf", ... }

# GET /exports/{id}/download →
{ "url": "https://media.vibe2text.ru/<pre-signed-download-url>", "expires_in": 3600 }

Импорт по ссылке

imports:read / imports:write

Импорт аудио/видео по публичному URL. После готовности в ответе появляется transcript_id.

  • POST/source-imports/— запустить импорт (url, kind?, title?, language?, clip_*?); лимит 30/час
  • POST/source-imports/preview— предпросмотр ссылки
  • POST/source-imports/:id/retry— повторить импорт
  • GET/source-imports/— список импортов
  • GET/source-imports/providers— поддерживаемые источники
  • GET/source-imports/:id— статус импорта

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

# GET /source-imports/providers →
{
  "providers": [
    { "code": "direct_url", "label": "Direct URL", "status": "available" },
    { "code": "rutube", "label": "RuTube", "status": "available" },
    { "code": "vk_video", "label": "VK Video", "status": "available" },
    { "code": "twitch", "label": "Twitch (VODs)", "status": "available" },
    { "code": "dzen", "label": "Dzen Video", "status": "available" }
  ]
}

# POST /source-imports/preview →
{ "title": null, "thumbnail": null, "duration_s": null, "provider": "rutube", "supported": true }

Smart Report

reports:read / reports:write

Только создание и чтение отчётов. Чат, регенерация, экспорт, стриминг и ревизии по ключу недоступны. До 3 одновременных LLM-задач на пользователя (иначе 429).

  • POST/smart-reports/— создать (transcript_id ИЛИ transcript_ids[]; type обязателен; model?, style_hint?, prompt_template_id?, render_mode=auto, knowledge_base_ids?, instructions?; Idempotency-Key)
  • GET/smart-reports/— список отчётов
  • GET/smart-reports/by-transcript/:id— отчёты по расшифровке
  • GET/smart-reports/:id— отчёт (status, content_md, content_blocks)

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

# POST /smart-reports/ →
{
  "id": "59d0af3f-926a-435b-adc4-b1b766bb87bc",
  "transcript_id": "9f3e4d3a-...",
  "transcript_ids": ["9f3e4d3a-..."],
  "type": "summary",
  "status": "pending",
  "render_mode": "constructor",
  "content_md": null,
  "created_at": "2026-06-04T00:41:00Z"
}

# GET /smart-reports/{id} →
{
  "id": "c7d7a0d3-...",
  "type": "summary",
  "status": "completed",
  "render_mode": "text",
  "content_md": "## Счёт от одного до десяти\n\nВ записи звучит последовательный счёт от 1 до 10.",
  "content_blocks": null,
  "tokens_input": 420,
  "tokens_output": 38,
  "completed_at": "2026-06-04T00:17Z"
}

# GET /smart-reports/ →
{ "items": [ { ...SmartReport... } ], "meta": { "total": 6, "skip": 0, "limit": 20 } }

Базы знаний

kb:read / kb:write

Управление базами и добавление записей. Все запросы требуют указания области видимости: добавьте ?personal=true (личное пространство) или ?organization_id=<uuid>. Без этого параметра вернётся 400. Семантический поиск (/query) и удаления по ключу недоступны.

  • GET/knowledge-bases— список баз
  • GET/knowledge-bases/:id— база
  • GET/knowledge-bases/:id/entries— записи базы
  • POST/knowledge-bases— создать базу (name, description?)
  • PATCH/knowledge-bases/:id— изменить базу
  • POST/knowledge-bases/:id/entries— добавить запись (source_kind, title?, content)
  • POST/knowledge-bases/:id/entries/upload— загрузить запись из PDF/DOCX

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

# POST /ai-processing/knowledge-bases?personal=true →
{
  "id": "62106610-74ef-4a20-964f-a570057bdcaf",
  "name": "Glossary",
  "description": "Terms",
  "scope_user_id": "<user_id>",
  "scope_organization_id": null,
  "entries_count": 0,
  "created_at": "2026-06-04T00:42:08Z",
  "updated_at": "2026-06-04T00:42:08Z"
}

# POST /ai-processing/knowledge-bases/{kb_id}/entries?personal=true →
{
  "entries": [
    {
      "id": "9196354b-...",
      "knowledge_base_id": "62106610-...",
      "source_kind": "text",
      "source_doc_id": "92f53be1-...",
      "title": "ASR",
      "content": "ASR = automatic speech recognition.",
      "tokens_count": 5,
      "chunk_index": 0,
      "created_at": "2026-06-04T00:42:26Z"
    }
  ]
}

# Without a scope param → 400:
{ "detail": [ { "key": "invalid_input_data", "text": "Scope is required: pass organization_id or personal=true." } ] }

Вебхуки

webhooks:read / webhooks:write

Подписка на события. Удаления нет — отключайте вебхук через PATCH. Секрет показывается один раз.

  • POST/webhooks/— создать (url, events?; секрет один раз)
  • PATCH/webhooks/:id— изменить (можно отключить)
  • POST/webhooks/:id/retest— проверить эндпоинт
  • POST/webhooks/:id/regenerate-secret— перевыпустить секрет
  • GET/webhooks/— список вебхуков
  • GET/webhooks/:id/logs— журнал доставок

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

# POST /webhooks/ →
{
  "id": "0550f52d-...",
  "url": "https://example.com/hook",
  "events": ["transcript.completed"],
  "secret_hint": "p4-X...zkvI",
  "is_active": true,
  "last_delivery_at": null,
  "last_status_code": null,
  "created_at": "2026-06-04T00:41:21Z",
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxx"
}
# "secret" is returned ONLY on create and regenerate-secret. Later reads show "secret_hint".

Записи звонков

recordings:read / recordings:write

Бот заходит в встречу и записывает её; после готовности задание ссылается на transcript_id.

  • POST/recording-jobs/— запустить запись (platform, meet_url)
  • POST/recording-jobs/:id/cancel— отменить запись
  • GET/recording-jobs/— список заданий
  • GET/recording-jobs/platforms— поддерживаемые платформы
  • GET/recording-jobs/:id— статус задания

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

# GET /recording-jobs/platforms →
{
  "platforms": [
    { "code": "yandex_telemost", "label": "Yandex Telemost", "status": "available", "message": null },
    { "code": "mtslink", "label": "MTS Link", "status": "available", "message": null },
    { "code": "sberjazz", "label": "SberJazz", "status": "available", "message": null },
    { "code": "ktalk", "label": "Kontur Talk", "status": "available", "message": null }
  ]
}
Типовые сценарии
  • Расшифровать ссылку

    Отправьте URL (например, видео YouTube) через source-import — мы скачаем и расшифруем, а вы заберёте готовый transcript_id.

  • Собрать краткое содержание

    Запросите Smart Report типа summary по готовой расшифровке и заберите готовый отчёт или его экспорт в файл.

  • Подписаться на событие

    Создайте вебхук на transcript.completed — и получайте уведомление автоматически, без опроса.

Расшифровать ссылку или запись звонка

Вместо ручной загрузки файла можно отправить публичный URL или попросить бота записать встречу. И то и другое возвращает задание, которое нужно опросить; по готовности появляется transcript_id — читайте его как обычную расшифровку.

# Ingest a public URL (a video, a podcast, a file link).
# scope imports:write; rate-limit 30/h.
curl -X POST https://api.vibe2text.ru/api/v1/source-imports/ \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "url": "https://rutube.ru/video/...", "language": "ru" }'

# Poll the import; once it finishes it carries a transcript_id you can read
# exactly like step 6 above.
curl https://api.vibe2text.ru/api/v1/source-imports/{id} \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN'

Ответ

{
  "id": "0d5e8f12-3a4b-4c5d-9e0f-112233445566",
  "url": "https://rutube.ru/video/...",
  "provider": "rutube",
  "status": "queued",
  "transcript_id": null,
  "created_at": "2026-06-04T00:41:00Z"
}
# Send a bot to record a live meeting (scope recordings:write).
# Check GET /recording-jobs/platforms for supported platforms.
curl -X POST https://api.vibe2text.ru/api/v1/recording-jobs/ \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "platform": "yandex_telemost", "meet_url": "https://telemost.yandex.ru/j/..." }'

# Poll the job; when done it links to a transcript_id.
curl https://api.vibe2text.ru/api/v1/recording-jobs/{id} \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN'

Ответ

{
  "id": "a1b2c3d4-5e6f-4071-8293-aabbccddeeff",
  "platform": "yandex_telemost",
  "meet_url": "https://telemost.yandex.ru/j/...",
  "status": "scheduled",
  "transcript_id": null,
  "created_at": "2026-06-04T00:41:00Z"
}

Собрать отчёт

Запросите отчёт по готовой расшифровке (краткое содержание, задачи, темы), опросите его статус и при необходимости поставьте экспорт в файл.

# Ask for a report on a ready transcript (scopes reports:write + reports:read).
# "type" is required. Pass transcript_id (one) OR transcript_ids (several).
# An Idempotency-Key dedupes retries; you may have 3 LLM jobs in flight (else 429).
curl -X POST https://api.vibe2text.ru/api/v1/smart-reports/ \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: report-9f3e4d3a' \
  -d '{ "transcript_id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff", "type": "summary" }'

Ответ

{
  "id": "59d0af3f-926a-435b-adc4-b1b766bb87bc",
  "transcript_id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff",
  "transcript_ids": ["9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff"],
  "type": "summary",
  "status": "pending",
  "render_mode": "constructor",
  "intent": {
    "requested_type": "summary",
    "render_mode": "auto",
    "style_hint": "summary",
    "instructions": null,
    "model": null,
    "transcript_ids": ["9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff"]
  },
  "plan": null,
  "template_id": null,
  "content_md": null,
  "created_at": "2026-06-04T00:41:00Z"
}
# Poll the report and read its rendered content.
curl https://api.vibe2text.ru/api/v1/smart-reports/{id} \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN'

Ответ

{
  "id": "c7d7a0d3-...",
  "transcript_id": "9f3e4d3a-...",
  "transcript_ids": ["9f3e4d3a-..."],
  "type": "summary",
  "status": "completed",
  "render_mode": "text",
  "content_md": "## Счёт от одного до десяти\n\nВ записи звучит последовательный счёт от 1 до 10.",
  "content_blocks": null,
  "tokens_input": 420,
  "tokens_output": 38,
  "error": null,
  "created_at": "2026-06-04T00:17Z",
  "completed_at": "2026-06-04T00:17Z"
}
# Need a file? Queue an export (scopes exports:write + exports:read):
curl -X POST https://api.vibe2text.ru/api/v1/exports/ \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{ "transcript_id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff", "format": "pdf" }'

# Then GET /exports/{id} (poll) and GET /exports/{id}/download for the url.

Ответ

# POST /exports/ →
{
  "id": "b0d7ef8b-1f21-4448-8b50-29e3d06df0b8",
  "transcript_id": "9f3e4d3a-1b2c-4d5e-8f90-aabbccddeeff",
  "format": "pdf",
  "status": "pending",
  "size_bytes": null,
  "error": null,
  "expires_at": "2026-06-11T00:41:18Z",
  "created_at": "2026-06-04T00:41:18Z"
}

# GET /exports/{id}/download →
{ "url": "https://media.vibe2text.ru/<pre-signed-download-url>", "expires_in": 3600 }

Структура итогового отчёта описана отдельным файлом JSON Schema — пригодится, если вы хотите валидировать ответы у себя: /schemas/report-document.schema.json

Подписаться на уведомления

Укажите свой URL и список интересных событий — мы будем сами присылать туда уведомление, как только что-то будет готово.

# Subscribe to events (scopes webhooks:write + webhooks:read).
# The response includes a secret shown ONCE — store it to verify signatures.
curl -X POST https://api.vibe2text.ru/api/v1/webhooks/ \
  -H 'Authorization: Bearer v2t_YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://hooks.your-app.com/vibe2text",
    "events": ["transcript.completed", "smart_report.generated"]
  }'

# Lost the secret? POST /webhooks/{id}/regenerate-secret.
# Test the endpoint with POST /webhooks/{id}/retest. Inspect deliveries
# with GET /webhooks/{id}/logs. (There is no DELETE — disable via PATCH.)

Ответ

{
  "id": "0550f52d-...",
  "url": "https://example.com/hook",
  "events": ["transcript.completed"],
  "secret_hint": "p4-X...zkvI",
  "is_active": true,
  "last_delivery_at": null,
  "last_status_code": null,
  "created_at": "2026-06-04T00:41:21Z",
  "secret": "whsec_xxxxxxxxxxxxxxxxxxxx"
}
# "secret" is returned ONLY on create (and regenerate-secret) — store it.
# Later reads show only "secret_hint".
Проверка подписи

К каждому уведомлению мы добавляем подпись в заголовке X-Signature (формат sha256=<hex>). Сверяйте её с секретом вебхука по сырым байтам тела (до json.loads) — так вы убедитесь, что письмо действительно от нас.

# Verify the signature on every incoming webhook.
# We send the signature in the "X-Signature" request header, formatted as
# "sha256=<hex>". Pass the RAW body bytes (before json.loads) to HMAC.
import hashlib
import hmac

def verify(raw_body: bytes, x_signature_header: str, secret: str) -> bool:
    if not x_signature_header or not x_signature_header.startswith("sha256="):
        return False
    expected = hmac.new(
        key=secret.encode("utf-8"),
        msg=raw_body,        # raw bytes, BEFORE json.loads(...)
        digestmod=hashlib.sha256,
    ).hexdigest()
    provided = x_signature_header.removeprefix("sha256=")
    return hmac.compare_digest(expected, provided)
Список событий
  • transcript.created
  • transcript.completed
  • transcript.failed
  • smart_report.generated
  • export.completed
  • action_item.created
  • payment.succeeded
  • payment.failed
Лимиты и идемпотентность
  • Загрузка файлов. POST /files/upload-init — не более 10 запросов в час.
  • Импорт по ссылке. POST /source-imports/ — не более 30 запросов в час.
  • Smart Report. Не более 3 одновременных LLM-задач на пользователя; при превышении — 429.
  • Idempotency-Key. Поддерживается на upload-init и smart-reports: ключ до 128 символов, повтор в течение 60 секунд возвращает прежний результат вместо нового запуска.
  • Подписанные ссылки. Действуют 3600 секунд. Просроченную часть загрузки можно пере-подписать через .../parts/:part_no/presign.
Ошибки

Ошибки возвращаются с кодом HTTP-статуса и телом в формате JSON. Поле detail — это массив объектов вида (key, text), где key пригоден для машинной обработки, а text содержит понятное описание. Каждый ответ об ошибке несёт поле request_id — указывайте его при обращении в поддержку.

Недостаточно прав (403)

Ключу не выдано право, требуемое эндпоинтом. Выпустите ключ с нужным scope.

HTTP/1.1 403 Forbidden
{
  "detail": [
    { "key": "not_enough_access_rights", "text": "API key requires scope reports:read" }
  ],
  "request_id": "<uuid>"
}
Эндпоинт недоступен по ключу (403)

Метод требует входа через веб-сессию и недоступен по API-ключу.

HTTP/1.1 403 Forbidden
{
  "detail": [
    {
      "key": "not_enough_access_rights",
      "text": "This endpoint is not available via API key — use a session login."
    }
  ],
  "request_id": "<uuid>"
}
Ошибка валидации (400 / 422)

Тело запроса не прошло проверку. Пример ниже — обязательный параметр области видимости для баз знаний.

HTTP/1.1 400 Bad Request
{
  "detail": [
    {
      "key": "invalid_input_data",
      "text": "Scope is required: pass organization_id or personal=true."
    }
  ],
  "request_id": "<uuid>"
}

request_id присутствует в каждом ответе об ошибке. Сохраните его и приложите к обращению в поддержку.

Поддержка

Написать в поддержку

Опишите вопрос одним сообщением. Ответим по почте.

Готовы попробовать?

Загрузите файл — мы расшифруем за пару минут.