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

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

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; для пустой расшифровки возвращается пустая строка
GET /api/account/recordings/{id}/client-report?format=pdf Клиентский отчёт в PDF или DOCX; includeTranscript=false исключает полный текст

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

{
  "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-RU",
  "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 да — Аудио/видеофайл, до 500 МБ
requestId нет случайный UUID сервера UUID для безопасного повтора загрузки после обрыва; становится id записи
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, синтеза речи или другой клиентской обработки

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

Если повторить запрос с тем же requestId в том же аккаунте, сервер вернёт уже созданную запись и не сохранит второй файл. Идентификатор, принадлежащий другому аккаунту, отклоняется с 409 Conflict.

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-RU" \
  -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. Удаление исходного аудио не удаляет эти производные данные, но переход к прослушиванию после удаления медиа, разумеется, недоступен.

Запись результата синтеза речи

Готовый результат простого или фонового синтеза можно сохранить как WAV вместе с исходным текстом и основными параметрами:

{
  "source": "tts",
  "status": "ok",
  "model": "SpeechExpert-TTS",
  "lang": "ru-RU",
  "channel_mode": "mono",
  "transcript": "Текст синтезированной записи.",
  "response": {
    "text": "Текст синтезированной записи.",
    "format": "wav",
    "voice": "elena-speech-expert-tts",
    "speed": 1.0
  }
}

В архиве сохраняются итоговый WAV и переданный клиентом объект response.

Обновление 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 Удалить аудио примерно через 24 часа после назначения политики
delete_after_processing Удалить медиа после обработки; проверяйте итоговые 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 и медиафайл; ответ 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 Превышена квота или недостаточно места в хранилище

См. также