{
    "openapi": "3.1.0",
    "info": {
        "title": "Cosmo Scribe API",
        "version": "1.0.0",
        "summary": "Транскрибация аудио и видео, краткие содержания, перевод и экспорт.",
        "description": "Программный доступ к транскрибации Cosmo Scribe.\n\nАутентификация — постоянный ключ в заголовке X-API-Key или Authorization: Bearer.\nСоздание записи асинхронно: метод отвечает 202 и идентификатором, о готовности сообщает вебхук с подписью HMAC-SHA256.\nМинуты аудио списываются из лимитов тарифа аккаунта.\n\nПолная документация: https://cosmoscribe.ru/api-dokumentatsiya",
        "contact": {
            "name": "Поддержка Cosmo Scribe",
            "url": "https://cosmoscribe.ru/api-dokumentatsiya",
            "email": "info@cosmoscribe.ru"
        }
    },
    "servers": [
        {
            "url": "https://cosmoscribe.ru/api/v1",
            "description": "Продакшен"
        }
    ],
    "security": [
        {
            "ApiKeyHeader": []
        },
        {
            "BearerToken": []
        }
    ],
    "tags": [
        {
            "name": "Транскрибация",
            "description": "Создание записей, статус, результат и экспорт. Идентификаторы записей — UUID."
        },
        {
            "name": "AI поверх записи",
            "description": "Краткие содержания и перевод. Оба метода асинхронные: создают объект в статусе queued и наполняют его позже."
        },
        {
            "name": "Словарь терминов",
            "description": "Замены применяются к тексту при выдаче: имена, бренды, аббревиатуры. Требуется тариф со словарём."
        },
        {
            "name": "Группы записей",
            "description": "Папки для записей: передавайте group_id при создании или переносите записи методом assign."
        },
        {
            "name": "Ключ и вебхук",
            "description": "Состояние ключа, лимиты тарифа и адрес доставки уведомлений."
        }
    ],
    "paths": {
        "/transcriptions": {
            "post": {
                "operationId": "transcriptions_create",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Загрузить файл",
                "description": "Принимает аудио или видео и ставит расшифровку в очередь.\n\nТело — multipart/form-data. Ответ приходит сразу, до окончания обработки: запись создаётся в статусе queued. Из видео на сервере остаётся только аудиодорожка. Лимит размера файла зависит от тарифа, для видео он выше — фактические значения возвращает GET /account.",
                "responses": {
                    "202": {
                        "description": "Запись создана и поставлена в очередь.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "message": "Транскрибация поставлена в очередь",
                                    "log_id": "9f1c2f7e-5a44-4c0e-9b1e-2d3c4b5a6f70",
                                    "status": "queued"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Лимит записей или минут тарифа исчерпан. Код ошибки: limit_transcriptions.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Запрос с этим Idempotency-Key ещё выполняется. Код ошибки: idempotency_in_flight.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Файл не прошёл валидацию: формат, размер или неверный webhook_url.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Защита от дублей при повторе запроса. Подробнее — в разделе об идемпотентности.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "file": {
                                        "description": "Аудио- или видеофайл: MP3, WAV, M4A, AAC, OGG, OPUS, FLAC, MP4, MOV, MKV, AVI, WEBM и другие.",
                                        "type": "string",
                                        "format": "binary"
                                    },
                                    "language": {
                                        "description": "Язык записи. auto — определить автоматически.",
                                        "type": "string",
                                        "enum": [
                                            "auto",
                                            "ru",
                                            "en"
                                        ],
                                        "default": "auto"
                                    },
                                    "group_id": {
                                        "description": "Группа, в которую попадёт запись. Должна принадлежать вашему аккаунту.",
                                        "type": "string",
                                        "format": "uuid"
                                    },
                                    "denoise_enabled": {
                                        "description": "Шумоподавление перед распознаванием. Игнорируется, если тариф его не включает.",
                                        "type": "boolean",
                                        "default": false
                                    },
                                    "webhook_url": {
                                        "description": "Адрес для уведомления именно об этой записи. Перебивает адрес по умолчанию с ключа.",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "file"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/url": {
            "post": {
                "operationId": "transcriptions_url",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Импортировать по ссылке",
                "description": "Скачивает запись по ссылке и расшифровывает её.\n\nРоссийские источники (VK Видео, RuTube, Одноклассники, Дзен, Mail.ru, Telegram, Яндекс.Диск) доступны на всех тарифах; зарубежные (YouTube, Vimeo, Twitch, SoundCloud, Dailymotion, Apple Podcasts и другие) — с тарифа «Профессионал». Прямые ссылки на файл проходят проверку хоста от подмены на внутренний адрес. Скачивание асинхронное: ответ приходит до его окончания.",
                "responses": {
                    "202": {
                        "description": "Скачивание поставлено в очередь.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Лимит тарифа исчерпан либо платформа требует тариф выше. Код ошибки: forbidden_platform_tier.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Хост заблокирован или запись закрыта. Код ошибки: private_content.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "413": {
                        "description": "Запись длиннее или больше лимита тарифа. Код ошибки: size_exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "415": {
                        "description": "Платформа не поддерживается. Код ошибки: unsupported_platform.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Ссылка не разобрана, ведёт на прямую трансляцию или не содержит звука. Код ошибки: invalid_url.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "504": {
                        "description": "Источник не ответил вовремя. Код ошибки: timeout.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Защита от повторного импорта одной ссылки.",
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "description": "Ссылка на запись или прямая ссылка на файл, до 2048 символов.",
                                        "type": "string"
                                    },
                                    "language": {
                                        "description": "Язык записи. Обратите внимание: у импорта по ссылке значение по умолчанию — ru, а не auto.",
                                        "type": "string",
                                        "enum": [
                                            "auto",
                                            "ru",
                                            "en"
                                        ],
                                        "default": "ru"
                                    },
                                    "group_id": {
                                        "description": "Группа для записи.",
                                        "type": "string",
                                        "format": "uuid"
                                    },
                                    "webhook_url": {
                                        "description": "Адрес уведомления об этой записи.",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "url"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/url/preview": {
            "post": {
                "operationId": "transcriptions_url-preview",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Проверить ссылку",
                "description": "Возвращает платформу, название и длительность без создания записи.\n\nПолезно, чтобы показать пользователю, что именно будет расшифровано, и заранее убедиться, что ссылка поддерживается. Минуты не списываются.",
                "responses": {
                    "200": {
                        "description": "Поля ok, platform, host, url и meta с заголовком, длительностью и размером записи.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "415": {
                        "description": "Платформа не поддерживается. Код ошибки: unsupported_platform.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Ссылка не разобрана. Код ошибки: invalid_url.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "description": "Проверяемая ссылка.",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "url"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/batch": {
            "post": {
                "operationId": "transcriptions_batch",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Пакетная загрузка",
                "description": "Ставит в очередь несколько файлов одним запросом.\n\nКоличество файлов за раз и суммарный размер ограничены настройками сервиса. Параметр webhook_url этот метод не принимает — уведомления по каждой записи придут на адрес по умолчанию, заданный на ключе.",
                "responses": {
                    "202": {
                        "description": "Массив items: имя файла, log_id и статус по каждой записи.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Не хватает лимита на весь пакет. Код ошибки: limit_transcriptions.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Превышено число файлов, размер одного файла или суммарный размер.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "files": {
                                        "description": "Массив файлов, минимум один.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "binary"
                                        }
                                    },
                                    "language": {
                                        "description": "Язык для всех файлов пакета.",
                                        "type": "string",
                                        "enum": [
                                            "auto",
                                            "ru",
                                            "en"
                                        ],
                                        "default": "auto"
                                    },
                                    "group_id": {
                                        "description": "Группа для всех записей пакета.",
                                        "type": "string",
                                        "format": "uuid"
                                    },
                                    "denoise_enabled": {
                                        "description": "Шумоподавление для всех файлов пакета.",
                                        "type": "boolean",
                                        "default": false
                                    }
                                },
                                "required": [
                                    "files"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/{id}": {
            "get": {
                "operationId": "transcriptions_show",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Статус и результат",
                "description": "Отдаёт статус, текст, сегменты и спикеров.\n\nОдин метод на весь жизненный цикл: пока запись не готова, поля с текстом пустые, а status равен queued или processing. К тексту уже применён словарь терминов. Опрашивать метод в цикле не нужно, если настроен вебхук.",
                "responses": {
                    "200": {
                        "description": "Объект записи в поле data.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "data": {
                                        "id": "9f1c2f7e-5a44-4c0e-9b1e-2d3c4b5a6f70",
                                        "status": "completed",
                                        "original_filename": "meeting.mp3",
                                        "language": "ru",
                                        "clean_text": "Добрый день. Начнём с плана на квартал…",
                                        "formatted_text": "[00:00] Спикер 1: Добрый день…",
                                        "segments": [
                                            {
                                                "start": 0.48,
                                                "end": 4.12,
                                                "text": "Добрый день. Начнём с плана на квартал.",
                                                "speaker": "SPEAKER_00",
                                                "words": [
                                                    {
                                                        "word": "Добрый",
                                                        "start": 0.48,
                                                        "end": 0.91
                                                    },
                                                    {
                                                        "word": "день.",
                                                        "start": 0.94,
                                                        "end": 1.32
                                                    }
                                                ]
                                            }
                                        ],
                                        "is_partial": false,
                                        "audio_duration_seconds": 1847,
                                        "full_duration_seconds": 1847,
                                        "group_id": null,
                                        "source_type": "upload"
                                    }
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Запись принадлежит другому аккаунту.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Записи с таким идентификатором нет.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи из ответа на создание.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            },
            "put": {
                "operationId": "transcriptions_update",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Правка записи",
                "description": "Меняет название, текст, сегменты или группу.\n\nПравка текста через API — то же действие, что редактирование в интерфейсе: сохранённый текст становится источником для экспорта и поиска.",
                "responses": {
                    "200": {
                        "description": "Обновлённая запись.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Ошибка валидации.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "title": {
                                        "description": "Название записи, до 200 символов.",
                                        "type": "string"
                                    },
                                    "clean_text": {
                                        "description": "Полный текст расшифровки.",
                                        "type": "string"
                                    },
                                    "segments": {
                                        "description": "Массив сегментов. Меняйте вместе с текстом, иначе таймкоды разойдутся.",
                                        "type": "array",
                                        "items": {
                                            "type": "object"
                                        }
                                    },
                                    "group_id": {
                                        "description": "Новая группа записи; null — вынести из группы.",
                                        "type": "string",
                                        "format": "uuid"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "operationId": "transcriptions_delete",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Удалить запись",
                "description": "Удаляет запись вместе с аудиофайлом.\n\nДействие необратимо: удаляются и текст, и файл в хранилище.",
                "responses": {
                    "200": {
                        "description": "Запись удалена.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/transcriptions/history": {
            "get": {
                "operationId": "transcriptions_history",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Список записей",
                "description": "Постраничный список записей аккаунта с фильтрами.",
                "responses": {
                    "200": {
                        "description": "Поля data и meta с current_page, last_page, per_page и total.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "Размер страницы, от 1 до 100.",
                        "schema": {
                            "type": "integer",
                            "default": 50
                        }
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "description": "Номер страницы.",
                        "schema": {
                            "type": "integer",
                            "default": 1
                        }
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Поиск по названию и тексту, до 200 символов.",
                        "schema": {
                            "type": "string"
                        }
                    },
                    {
                        "name": "group_id",
                        "in": "query",
                        "required": false,
                        "description": "Фильтр по группе. Пустая строка — записи без группы.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "date_from",
                        "in": "query",
                        "required": false,
                        "description": "Начало периода.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "date_to",
                        "in": "query",
                        "required": false,
                        "description": "Конец периода.",
                        "schema": {
                            "type": "string",
                            "format": "date"
                        }
                    },
                    {
                        "name": "date_preset",
                        "in": "query",
                        "required": false,
                        "description": "Готовый период вместо пары дат.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "today",
                                "week",
                                "month"
                            ]
                        }
                    },
                    {
                        "name": "has_summary",
                        "in": "query",
                        "required": false,
                        "description": "Только записи с готовым кратким содержанием.",
                        "schema": {
                            "type": "boolean"
                        }
                    }
                ]
            }
        },
        "/transcriptions/{id}/export": {
            "get": {
                "operationId": "transcriptions_export",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Экспорт",
                "description": "Отдаёт готовую расшифровку в одном из пяти форматов.\n\nФормат json возвращает JSON с текстом и сегментами, остальные — файл на скачивание. Текстовые форматы отдаются в UTF-8 с BOM, чтобы Windows-редакторы не ломали кириллицу. Если у записи есть пословные тайм-коды, srt и vtt режутся по границам слов: карточка не длиннее 7 секунд и не шире двух строк по 42 символа, разрыв предпочитается на конце предложения. Без пословных данных реплика отдаётся одной карточкой, как раньше. Если у записи распознаны спикеры, srt получает имя в начале карточки при смене говорящего, а vtt — тег <v Имя> в каждой карточке; на записях без спикеров вывод прежний.",
                "responses": {
                    "200": {
                        "description": "Файл или JSON в зависимости от формата.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Запись ещё не готова. Код ошибки: not_completed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    },
                    {
                        "name": "format",
                        "in": "query",
                        "required": true,
                        "description": "Формат выгрузки.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "txt",
                                "srt",
                                "vtt",
                                "json",
                                "doc"
                            ]
                        }
                    }
                ]
            }
        },
        "/transcriptions/{id}/resume": {
            "post": {
                "operationId": "transcriptions_resume",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Докрутить остаток",
                "description": "Расшифровывает часть записи, отрезанную по лимиту минут.\n\nНужен, когда в ответе пришло is_partial = true. Метод дочитывает запись с того места, где остановился прошлый прогон, и склеивает сегменты. Доступен, пока исходный файл не удалён по сроку хранения тарифа.",
                "responses": {
                    "202": {
                        "description": "Докрутка поставлена в очередь; в ответе planned_to_seconds и new_seconds.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Минут на продолжение не хватает. Код ошибки: audio_budget_exceeded.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "410": {
                        "description": "Исходный файл уже удалён по сроку хранения. Код ошибки: audio_unavailable.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Запись расшифрована полностью.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор усечённой записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/transcriptions/{id}/retry": {
            "post": {
                "operationId": "transcriptions_retry",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Повторить обработку",
                "description": "Перезапускает расшифровку записи со статусом failed.",
                "responses": {
                    "200": {
                        "description": "Запись поставлена в очередь повторно.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Аудиофайл не найден в хранилище.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Повтор возможен только для статуса failed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/transcriptions/{id}/audio": {
            "get": {
                "operationId": "transcriptions_audio",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Аудио записи",
                "description": "Отдаёт исходное аудио потоком.\n\nФайл расшифровывается на лету, поддерживаются частичные запросы по Range для перемотки в плеере.",
                "responses": {
                    "200": {
                        "description": "Поток аудио.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Файл уже удалён по сроку хранения.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/transcriptions/{id}/waveform": {
            "get": {
                "operationId": "transcriptions_waveform",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Пики волны",
                "description": "Готовые пики для отрисовки дорожки без декодирования файла.",
                "responses": {
                    "200": {
                        "description": "Массив пиков и длительность.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/transcriptions/assign": {
            "post": {
                "operationId": "transcriptions_assign",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Перенести в группу",
                "description": "Меняет группу у нескольких записей сразу.",
                "responses": {
                    "200": {
                        "description": "Число перенесённых записей.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ids": {
                                        "description": "Идентификаторы записей, минимум один.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "uuid"
                                        }
                                    },
                                    "group_id": {
                                        "description": "Целевая группа; null — вынести из групп.",
                                        "type": "string",
                                        "format": "uuid"
                                    }
                                },
                                "required": [
                                    "ids"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/bulk-delete": {
            "post": {
                "operationId": "transcriptions_bulk-delete",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Массовое удаление",
                "description": "Удаляет до 100 записей за запрос.",
                "responses": {
                    "200": {
                        "description": "Число удалённых записей.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ids": {
                                        "description": "Идентификаторы записей, от 1 до 100.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "uuid"
                                        }
                                    }
                                },
                                "required": [
                                    "ids"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/bulk-download": {
            "post": {
                "operationId": "transcriptions_bulk-download",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Массовая выгрузка",
                "description": "Собирает ZIP-архив с расшифровками выбранных записей.",
                "responses": {
                    "200": {
                        "description": "Поток ZIP-архива.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "ids": {
                                        "description": "Идентификаторы записей, от 1 до 100.",
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "format": "uuid"
                                        }
                                    },
                                    "format": {
                                        "description": "Формат файлов внутри архива.",
                                        "type": "string",
                                        "enum": [
                                            "txt",
                                            "srt",
                                            "vtt"
                                        ]
                                    }
                                },
                                "required": [
                                    "ids",
                                    "format"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/{id}/share": {
            "post": {
                "operationId": "transcriptions_share",
                "tags": [
                    "Транскрибация"
                ],
                "summary": "Публичная ссылка",
                "description": "Создаёт ссылку на расшифровку со сроком жизни и паролем.",
                "responses": {
                    "200": {
                        "description": "Токен, готовый share_url и дата истечения.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Лимит ссылок исчерпан или пароль не входит в тариф. Код ошибки: limit_share_links.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "expires_in": {
                                        "description": "Срок жизни ссылки.",
                                        "type": "string",
                                        "enum": [
                                            "1h",
                                            "1d",
                                            "1w"
                                        ]
                                    },
                                    "password": {
                                        "description": "Пароль на ссылку, от 4 символов. Доступен на платных тарифах.",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "expires_in"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/transcriptions/{id}/summaries": {
            "post": {
                "operationId": "summaries_create",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Создать краткое содержание",
                "description": "Ставит в очередь пересказ записи по готовому шаблону или по своему промпту.\n\nЗапись должна быть готова и содержать не меньше 50 символов текста. По одной записи можно держать несколько шаблонов одновременно. Готовность отслеживается через GET /summaries/{id}: пока модель работает, статус равен queued или processing. Шаблон custom требует поля custom_instruction — текстового описания нужного разбора; формат ответа при этом остаётся тем же, а поле metadata у такого пересказа всегда пустое.",
                "responses": {
                    "202": {
                        "description": "Объект краткого содержания в статусе queued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Запись не готова, текста мало или шаблон неизвестен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Месячный лимит кратких содержаний исчерпан либо они не входят в тариф — различить можно по тексту message.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "template": {
                                        "description": "Шаблон под формат записи. Расшифровка шаблонов — в разделе о кратких содержаниях.",
                                        "type": "string",
                                        "enum": [
                                            "general",
                                            "meeting",
                                            "interview",
                                            "lecture",
                                            "podcast",
                                            "sales_call",
                                            "support_call",
                                            "voice_note",
                                            "brainstorm",
                                            "highlights",
                                            "custom"
                                        ]
                                    },
                                    "custom_instruction": {
                                        "description": "Описание нужного разбора для template=custom: от 10 до 2000 символов. Задаёт, что искать в записи и на чём сделать акцент; схему ответа и запрет на выдумывание фактов не отменяет.",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "template"
                                ]
                            }
                        }
                    }
                }
            },
            "get": {
                "operationId": "summaries_index",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Краткие содержания записи",
                "description": "Все пересказы одной записи со статусами.",
                "responses": {
                    "200": {
                        "description": "Массив кратких содержаний.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/summaries/{id}": {
            "get": {
                "operationId": "summaries_show",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Готовое краткое содержание",
                "description": "Текст пересказа, тезисы, задачи и темы.\n\nСостав полей зависит от шаблона: задачи есть у встречи и звонков, темы — у встречи, интервью, лекции и подкаста, у хайлайтов вместо текста массив цитат с таймкодами.",
                "responses": {
                    "200": {
                        "description": "Объект краткого содержания.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "id": "b4c9a1d2-77e3-4f10-8c55-1a2b3c4d5e6f",
                                    "transcription_log_id": "9f1c2f7e-5a44-4c0e-9b1e-2d3c4b5a6f70",
                                    "template": "meeting",
                                    "status": "completed",
                                    "summary_text": "Обсудили план на квартал…",
                                    "key_points": [
                                        "Запуск переносится на март"
                                    ],
                                    "action_items": [
                                        {
                                            "task": "Прислать смету",
                                            "assignee": "Иван",
                                            "due_date": "2026-09-01",
                                            "completed": false
                                        }
                                    ],
                                    "topics": [
                                        "Планирование"
                                    ],
                                    "language": "ru",
                                    "generated_at": "2026-08-25T12:44:19+00:00"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор краткого содержания.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            },
            "put": {
                "operationId": "summaries_update",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Отметить задачи",
                "description": "Обновляет список задач в готовом кратком содержании.\n\nЕдинственное разрешённое изменение — состав и флаги выполнения задач. Работает только для шаблонов с задачами: встреча, звонок клиенту, звонок в поддержку, голосовая заметка.",
                "responses": {
                    "200": {
                        "description": "Обновлённое краткое содержание.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Пересказ не готов или шаблон не поддерживает задачи.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор краткого содержания.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "action_items": {
                                        "description": "Массив объектов с полями task, assignee, due_date и completed.",
                                        "type": "array",
                                        "items": {
                                            "type": "object"
                                        }
                                    }
                                },
                                "required": [
                                    "action_items"
                                ]
                            }
                        }
                    }
                }
            },
            "delete": {
                "operationId": "summaries_delete",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Удалить краткое содержание",
                "description": "Удаляет пересказ, сама запись остаётся.",
                "responses": {
                    "200": {
                        "description": "Удалено.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор краткого содержания.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/transcriptions/{id}/translations": {
            "post": {
                "operationId": "translations_create",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Перевести расшифровку",
                "description": "Ставит в очередь перевод текста и сегментов.\n\nПеревод сохраняет разбиение на сегменты, поэтому из него получаются субтитры. Повторный запрос того же языка вернёт существующий перевод, а не создаст второй.",
                "responses": {
                    "202": {
                        "description": "Объект перевода в статусе queued. Тот же код вернётся, если перевод на этот язык уже готовится.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Запись не готова, текста мало, он длиннее лимита модели или язык записи совпадает с языком перевода.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Месячный лимит переводов исчерпан либо перевод не входит в тариф — различить можно по тексту message.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "target_language": {
                                        "description": "Язык перевода.",
                                        "type": "string",
                                        "enum": [
                                            "ru",
                                            "en",
                                            "de",
                                            "fr",
                                            "es",
                                            "it",
                                            "pt",
                                            "zh",
                                            "tr",
                                            "ar",
                                            "kk",
                                            "uk"
                                        ],
                                        "default": "ru"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "get": {
                "operationId": "translations_index",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Переводы записи",
                "description": "Все переводы одной записи со статусами.",
                "responses": {
                    "200": {
                        "description": "Массив переводов.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/translations/{id}": {
            "get": {
                "operationId": "translations_show",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Готовый перевод",
                "description": "Переведённый текст и сегменты.",
                "responses": {
                    "200": {
                        "description": "Объект перевода.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор перевода.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            },
            "delete": {
                "operationId": "translations_delete",
                "tags": [
                    "AI поверх записи"
                ],
                "summary": "Удалить перевод",
                "description": "Удаляет перевод, сама запись остаётся.",
                "responses": {
                    "200": {
                        "description": "Удалено.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор перевода.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/dictionary": {
            "get": {
                "operationId": "dictionary_index",
                "tags": [
                    "Словарь терминов"
                ],
                "summary": "Список замен",
                "description": "Все пары «как распознано» и «как должно быть».",
                "responses": {
                    "200": {
                        "description": "Массив записей словаря.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Словарь не входит в тариф. Код ошибки: feature_dictionary_disabled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "operationId": "dictionary_store",
                "tags": [
                    "Словарь терминов"
                ],
                "summary": "Добавить замену",
                "description": "Создаёт или обновляет пару замены.\n\nЕсли пара с таким from уже есть, обновится только to — повторный вызов безопасен.",
                "responses": {
                    "201": {
                        "description": "Созданная или обновлённая запись.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Лимит записей словаря исчерпан. Код ошибки: limit_dictionary_entries.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "from": {
                                        "description": "Как слово распознаётся сейчас, до 500 символов.",
                                        "type": "string"
                                    },
                                    "to": {
                                        "description": "Как его нужно писать, до 500 символов.",
                                        "type": "string"
                                    }
                                },
                                "required": [
                                    "from",
                                    "to"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/dictionary/export": {
            "get": {
                "operationId": "dictionary_export",
                "tags": [
                    "Словарь терминов"
                ],
                "summary": "Выгрузить словарь",
                "description": "Пары from и to в порядке алфавита — готовый бэкап.",
                "responses": {
                    "200": {
                        "description": "Массив пар.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/dictionary/import": {
            "post": {
                "operationId": "dictionary_import",
                "tags": [
                    "Словарь терминов"
                ],
                "summary": "Загрузить словарь",
                "description": "Массовое добавление до 1000 пар за запрос.",
                "responses": {
                    "200": {
                        "description": "Сколько записей добавлено и сколько обновлено.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "data": {
                                        "description": "Массив объектов с полями from и to, до 1000 элементов.",
                                        "type": "array",
                                        "items": {
                                            "type": "object"
                                        }
                                    }
                                },
                                "required": [
                                    "data"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/dictionary/{id}": {
            "delete": {
                "operationId": "dictionary_delete",
                "tags": [
                    "Словарь терминов"
                ],
                "summary": "Удалить замену",
                "description": "Убирает одну пару из словаря.",
                "responses": {
                    "204": {
                        "description": "Удалено, тело ответа пустое.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор записи словаря.",
                        "schema": {
                            "type": "integer"
                        }
                    }
                ]
            }
        },
        "/groups": {
            "get": {
                "operationId": "groups_index",
                "tags": [
                    "Группы записей"
                ],
                "summary": "Список групп",
                "description": "Группы аккаунта с числом записей.",
                "responses": {
                    "200": {
                        "description": "Массив групп.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "operationId": "groups_store",
                "tags": [
                    "Группы записей"
                ],
                "summary": "Создать группу",
                "description": "Новая папка для записей.",
                "responses": {
                    "200": {
                        "description": "Созданная группа.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "402": {
                        "description": "Лимит групп тарифа исчерпан. Код ошибки: limit_groups.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "description": "Название, до 255 символов.",
                                        "type": "string"
                                    },
                                    "description": {
                                        "description": "Описание группы.",
                                        "type": "string"
                                    },
                                    "color": {
                                        "description": "Цвет метки в формате #RRGGBB.",
                                        "type": "string",
                                        "default": "#000000"
                                    }
                                },
                                "required": [
                                    "name"
                                ]
                            }
                        }
                    }
                }
            }
        },
        "/groups/{id}": {
            "get": {
                "operationId": "groups_show",
                "tags": [
                    "Группы записей"
                ],
                "summary": "Группа",
                "description": "Одна группа с её записями.",
                "responses": {
                    "200": {
                        "description": "Объект группы.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор группы.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            },
            "put": {
                "operationId": "groups_update",
                "tags": [
                    "Группы записей"
                ],
                "summary": "Изменить группу",
                "description": "Меняет название, описание или цвет.",
                "responses": {
                    "200": {
                        "description": "Обновлённая группа.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор группы.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "description": "Новое название.",
                                        "type": "string"
                                    },
                                    "description": {
                                        "description": "Новое описание.",
                                        "type": "string"
                                    },
                                    "color": {
                                        "description": "Новый цвет в формате #RRGGBB.",
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "operationId": "groups_delete",
                "tags": [
                    "Группы записей"
                ],
                "summary": "Удалить группу",
                "description": "Удаляет папку; записи остаются без группы.",
                "responses": {
                    "200": {
                        "description": "Группа удалена.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "id",
                        "in": "path",
                        "required": true,
                        "description": "Идентификатор группы.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        }
                    }
                ]
            }
        },
        "/account": {
            "get": {
                "operationId": "account_show",
                "tags": [
                    "Ключ и вебхук"
                ],
                "summary": "Состояние ключа",
                "description": "Лимиты ключа, секрет вебхука и лимиты тарифа.\n\nПервый запрос, которым стоит проверить интеграцию: если он вернул 200, ключ рабочий. Поле plan содержит те же лимиты, что видит интерфейс, — по нему удобно заранее понять допустимый размер файла и остаток минут.",
                "responses": {
                    "200": {
                        "description": "Объекты client, webhook и plan.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                },
                                "example": {
                                    "client": {
                                        "id": "3f2a1b0c-1111-2222-3333-444455556666",
                                        "name": "Продакшен",
                                        "status": "active",
                                        "rpm_limit": 60,
                                        "daily_limit": 5000,
                                        "monthly_limit": 100000
                                    },
                                    "webhook": {
                                        "url": "https://example.ru/hooks/cosmic",
                                        "secret": "8f14e45fceea167a5a36dedd4bea2543",
                                        "signature_header": "X-Cosmic-Signature",
                                        "signature_algo": "hmac-sha256(raw_body, secret), hex"
                                    },
                                    "plan": {
                                        "max_file_mb": 500,
                                        "monthly_audio_minutes": 1200
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/account/webhook": {
            "put": {
                "operationId": "account_webhook",
                "tags": [
                    "Ключ и вебхук"
                ],
                "summary": "Адрес и секрет вебхука",
                "description": "Задаёт адрес доставки по умолчанию и ротирует секрет.\n\nАдрес по умолчанию работает для всех записей ключа, включая пакетную загрузку. Ротация секрета мгновенная: подписи со старым секретом перестанут совпадать, поэтому меняйте секрет и настройки приёмника вместе. То же самое можно сделать в профиле, без обращения к API.",
                "responses": {
                    "200": {
                        "description": "Актуальные адрес и секрет.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Адрес недоступен или указывает на приватный хост. Код ошибки: webhook_invalid.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Ключ не передан или недействителен.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Превышен лимит запросов ключа или маршрута.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Error"
                                }
                            }
                        }
                    }
                },
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "webhook_url": {
                                        "description": "Публичный http/https-адрес; пустая строка убирает адрес.",
                                        "type": "string"
                                    },
                                    "rotate_secret": {
                                        "description": "Сгенерировать новый секрет подписи.",
                                        "type": "boolean",
                                        "default": false
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "ApiKeyHeader": {
                "type": "apiKey",
                "in": "header",
                "name": "X-API-Key",
                "description": "Ключ выпускается в профиле: Безопасность → API-ключи."
            },
            "BearerToken": {
                "type": "http",
                "scheme": "bearer",
                "description": "Тот же ключ, переданный как Authorization: Bearer."
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "Человекочитаемое описание на русском."
                    },
                    "code": {
                        "type": "string",
                        "description": "Машинный код ошибки, если он определён для случая."
                    },
                    "errors": {
                        "type": "object",
                        "description": "Разбор ошибок по полям для статуса 422."
                    }
                },
                "required": [
                    "message"
                ]
            },
            "TranscriptionWord": {
                "type": "object",
                "properties": {
                    "word": {
                        "type": "string"
                    },
                    "start": {
                        "type": "number",
                        "description": "Начало слова в секундах от начала записи."
                    },
                    "end": {
                        "type": "number",
                        "description": "Конец слова в секундах от начала записи."
                    }
                }
            },
            "TranscriptionSegment": {
                "type": "object",
                "properties": {
                    "start": {
                        "type": "number",
                        "description": "Начало сегмента в секундах."
                    },
                    "end": {
                        "type": "number",
                        "description": "Конец сегмента в секундах."
                    },
                    "text": {
                        "type": "string"
                    },
                    "speaker": {
                        "type": "string",
                        "description": "Метка спикера, если включена диаризация."
                    },
                    "words": {
                        "type": "array",
                        "description": "Пословные тайм-коды. Присутствуют, если для языка записи выполнено выравнивание; порядок слов совпадает с порядком в text.",
                        "items": {
                            "$ref": "#/components/schemas/TranscriptionWord"
                        }
                    }
                }
            },
            "Transcription": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "queued",
                            "processing",
                            "completed",
                            "failed"
                        ]
                    },
                    "original_filename": {
                        "type": "string"
                    },
                    "language": {
                        "type": "string"
                    },
                    "clean_text": {
                        "type": "string"
                    },
                    "formatted_text": {
                        "type": "string"
                    },
                    "segments": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/TranscriptionSegment"
                        }
                    },
                    "is_partial": {
                        "type": "boolean",
                        "description": "true — запись усечена по лимиту минут, остаток дочитывается методом resume."
                    },
                    "audio_duration_seconds": {
                        "type": "integer"
                    },
                    "full_duration_seconds": {
                        "type": "integer"
                    },
                    "group_id": {
                        "type": "string",
                        "format": "uuid"
                    },
                    "source_type": {
                        "type": "string"
                    }
                }
            }
        }
    }
}