Перейти к содержанию

Сохранённые записи и транскрипты

Account API управляет архивом Мои записи: исходным или синтезированным аудио, ответом обработки, текстовой проекцией и политикой хранения медиа. Резюме, готовые наборы и подтверждения связаны с записью, но хранятся отдельно от аудиофайла.

Только portal-сессия

Все методы /api/account/recordings... требуют активную cookie-сессию портала. Одного API-ключа недостаточно. Пользователь видит только свои записи; чужой или отсутствующий идентификатор возвращает 404.

Список и чтение

Метод Назначение
GET /api/account/recordings?offset=0&limit=50 Записи текущего пользователя от новых к старым; offset >= 0, limit от 1 до 100
GET /api/account/recordings/{id} Одна запись с metadata и сохранённым объектом response
GET /api/account/recordings/{id}/media Сохранённый медиафайл с исходным Content-Type и именем
GET /api/account/recordings/{id}/transcript Только текст, text/plain; для пустой расшифровки возвращается пустая строка

Объект записи имеет следующий основной контракт:

{
  "id": "7ae1ee00-4fb3-4c43-83c3-53568ef06b0b",
  "name": "Звонок клиенту",
  "original_filename": "call.wav",
  "content_type": "audio/wav",
  "file_size": 1843200,
  "duration_ms": 57300,
  "source": "upload",
  "status": "saved",
  "model": "SpeechExpert-STT",
  "lang": "ru-RU",
  "channel_mode": "mono",
  "transcript": "Добрый день...",
  "response": {"result": "Добрый день..."},
  "created_at": "2026-07-15T12:00:00+00:00",
  "modified_at": "2026-07-15T12:01:00+00:00",
  "audio_retention": "keep",
  "media_status": "available",
  "media_available": true,
  "audio_expires_at": null,
  "media_deleted_at": null,
  "media_url": "/api/account/recordings/7ae1ee00-4fb3-4c43-83c3-53568ef06b0b/media",
  "transcript_url": "/api/account/recordings/7ae1ee00-4fb3-4c43-83c3-53568ef06b0b/transcript"
}

media_url равен null, когда аудио уже удалено; transcript_url остаётся доступен. Оба URL относительные и требуют ту же cookie-сессию.

Создание записи

POST /api/account/recordings
Content-Type: multipart/form-data
Поле формы Обязательное По умолчанию Описание
audio да Аудио/видеофайл, до MAX_AUDIO_UPLOAD_BYTES (штатно 200 МБ)
name нет исходное имя файла Отображаемое название
duration_ms нет null Известная клиенту длительность
source нет upload Короткая метка источника
status нет saved Статус записи
model нет null Модель или режим, которым получен результат
lang нет null Язык записи, распознавания или синтеза
channelMode нет null Сохранённый режим каналов
audioRetention нет keep keep, 24h или delete_after_processing
transcript нет выводится из response Текстовая проекция
response нет null JSON-строка с полным результатом STT, TTS Studio или другой клиентской обработки

Если transcript не передан или равен пустой строке, сервер последовательно ищет текст в response.utterances, response.result и response.text. Ответ имеет статус 201 Created и форму объекта записи из предыдущего раздела.

curl -X POST "https://api.speech.example.com/api/account/recordings" \
  -b portal-cookie.txt \
  -F "audio=@call.wav" \
  -F "name=Звонок клиенту" \
  -F "model=SpeechExpert-STT" \
  -F "lang=ru-RU" \
  -F "channelMode=mono" \
  -F 'response={"result":"Добрый день"}'

Этот метод сохраняет уже имеющийся клиентский результат и сам не запускает ASR. Для распознавания существующей записи передайте её recordingId в POST /api/stt/v1:recognizeAsync.

Если при распознавании было передано emotionAnalysis=true, полный response.emotion_analysis и response.emotion_analysis_status сохраняются вместе с транскриптом. Раздел Мои записи поэтому восстанавливает метрики, эпизоды, связи с репликами и временную шкалу без повторного emotion inference. Удаление исходного аудио не удаляет эти производные данные, но переход к прослушиванию после удаления медиа, разумеется, недоступен.

Запись из TTS Studio

TTS Studio сохраняет собранный файл как WAV со следующими основными полями:

{
  "source": "tts",
  "status": "ok",
  "model": "tts-studio",
  "lang": "ru-RU",
  "channel_mode": "mono",
  "transcript": "Первый фрагмент.\n\nВторой фрагмент.",
  "response": {
    "text": "Первый фрагмент.\n\nВторой фрагмент.",
    "format": "wav",
    "tts_studio": {
      "schema_version": 1,
      "blocks": [
        {
          "text": "Первый фрагмент.",
          "voice": "elena-speech-expert-tts",
          "speed": 1.0,
          "pause_after_ms": 300
        },
        {
          "text": "Второй фрагмент.",
          "voice": "elena-speech-expert-tts",
          "speed": 1.0,
          "pause_after_ms": 0
        }
      ]
    }
  }
}

В архиве остаются итоговый WAV и конфигурация фрагментов. Отдельные версии аудио, выбранные дубли и состояние редактора не сохраняются; повторное открытие такой записи как редактируемого проекта Studio пока не поддерживается.

Обновление metadata и транскрипта

PATCH /api/account/recordings/{id}
Content-Type: application/json

Можно передать любое подмножество полей name (1–512 символов), duration_ms (>= 0), source, status, model, lang, channel_mode, transcript и response. В PATCH используется channel_mode в snake_case, в отличие от multipart-поля channelMode при создании.

response заменяет весь client-managed объект, а не сливается с ним по полям. При замене сервер сохраняет принадлежащую ему проекцию активной саммаризации (summarization и summarization_status). Управляйте её версиями специализированными методами, описанными в саммаризации STT v1.

Хранение и удаление

Политика меняется JSON-запросом:

PUT /api/account/recordings/{id}/retention
Content-Type: application/json

{"audio_retention":"24h"}
Политика Поведение
keep Хранить аудио без заданного срока
24h Удалить best-effort worker через 24 часа от назначения политики
delete_after_processing Текущие account-методы синхронно пытаются удалить доступное медиа; проверяйте итоговые media_status и media_available

Состояние медиа отражается в media_status: available, purge_pending, purged или purge_failed. Смена политики не восстанавливает удалённый файл. При создании записи с delete_after_processing неудачная очистка всё равно может вернуть 201 с media_status: "purge_failed"; при последующем PUT retention или DELETE .../media такая же ошибка возвращается как 500.

Метод Результат
DELETE /api/account/recordings/{id}/media Удаляет только аудио и возвращает обновлённую запись; транскрипт, резюме, источники и производные результаты остаются
DELETE /api/account/recordings/{id} Удаляет запись, версии резюме, производные результаты и review-items и best-effort удаляет локальный файл; ответ 204 No Content. Дайджесты с JSON-ссылкой на эту запись автоматически не удаляются

Если media_status отличается от available, GET .../media возвращает 410 Gone, в том числе для purge_pending или purge_failed. Если metadata утверждает, что медиа доступно, но файл потерян в хранилище, ответ будет 404. Успешная очистка выставляет media_status: "purged", media_available: false, file_size: 0 и media_url: null, а также заполняет media_deleted_at.

Ошибки

Код Когда возникает
400 Пустое аудио, response не является валидным JSON-объектом
401 Нет действующей portal-сессии
404 Запись не найдена, принадлежит другому пользователю или файл неожиданно отсутствует
410 Медиа недоступно по текущему media_status; текст остаётся доступен
413 Загрузка превышает серверный лимит
422 JSON обновления или retention не прошёл проверку схемы
500 Не удалось удалить сохранённый файл
503 Не удалось безопасно зарезервировать место в хранилище из-за конкурирующей операции
507 Превышена пользовательская/общая квота либо резерв свободного диска

См. также