Документация API

REST API для транскрибации аудио и видео. Платные клиенты используют для сторонних интеграций API-ключ, созданный в настройках аккаунта.

Базовый URL

https://scribe.uustudio.cc

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

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

Заголовок Authorization

Authorization: Bearer {token}

Создавайте и отзывайте ключи на странице API-ключей в настройках. Эндпоинты входа приложения предназначены только для официальных клиентов.

Ответы об ошибках

Все ошибки возвращают JSON-тело с полем message .

Стандартная ошибка

{
    "message": "Description of the error"
}

Ошибка валидации (422)

{
    "message": "The name field is required.",
    "errors": {
        "name": ["The name field is required."]
    }
}
СтатусОписание
401Не аутентифицирован (токен отсутствует или недействителен)
403Запрещено или превышен лимит тарифа
404Ресурс не найден
422Валидация не удалась
429Превышен лимит скорости или слишком много параллельных задач
500Внутренняя ошибка сервера

Лимиты скорости

Аутентифицированные API-эндпоинты ограничены 10 запросами в минуту на токен.

Лимиты использования

Доступность API

Сторонний REST API недоступен на бесплатном тарифе. Для создания и использования API-ключей перейдите на Pro или Max либо купите пакет с оплатой по мере использования.

Макс. размер файла
2 ГБ
Параллельные задачи
Макс. 3
Макс. повторов на задачу
3

Сравнение платных тарифов

ФункцияPay as you goProMax
Загрузок в деньБезлимитБезлимитБезлимит
Форматы экспортаВсеВсеВсе
Приоритет задачСреднийСреднийВысокий

Сценарии работы

Загрузить аудио/видео файл

  1. POST /api/uploads/sign → Получить upload_id и информацию о частях
  2. PUT {presigned_url} → Загрузить каждую часть в хранилище
  3. POST /api/uploads/complete → Завершить загрузку, автоматически создать задачу
  4. GET /api/tasks/{id} → Опрашивать статус (pending -> scribing -> finished)
  5. GET /api/tasks/{id}/download/srt → Экспортировать (опционально)

Создать задачу вручную

  1. POST /api/tasks → Создать с disk, path, name
  2. GET /api/tasks/{id} → Опрашивать статус
  3. GET /api/tasks/{id} → Получить segments, summary, mindmap

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

POST /api/login

Аутентификация по email и паролю. Возвращает токен Sanctum.

Тело запроса

ПолеТипОбязательноОписание
emailstringYesEmail пользователя (макс. 255)
passwordstringYesПароль пользователя

Ответ 200

{
    "token": "1|abc123...",
    "user": {
        "id": 1,
        "name": "Zhang San",
        "email": "[email protected]"
    }
}

Ограничено 5 попытками в минуту на email.

POST /api/register

Создать новый аккаунт. Возвращает токен Sanctum.

Тело запроса

ПолеТипОбязательноОписание
namestringYesОтображаемое имя (макс. 255)
emailstringYesУникальный email (макс. 255)
passwordstringYesДолжен быть подтверждён
password_confirmationstringYesПодтверждение пароля

Ответ 201

{
    "token": "1|abc123...",
    "user": {
        "id": 1,
        "name": "Zhang San",
        "email": "[email protected]"
    }
}
POST /api/auth/social-login

Аутентификация через Google OAuth. Создаёт аккаунт, если его нет.

Тело запроса

ПолеТипОбязательноОписание
providerstringYesgoogle поддерживаемые провайдеры
codestringYesКод авторизации OAuth

Ответ 200

{
    "token": "1|abc123...",
    "user": {
        "id": 1,
        "name": "Zhang San",
        "email": "[email protected]"
    }
}
POST /api/logout

Отзывает текущий токен доступа.

Ответ 204

Не возвращает тело.

Задачи

POST /api/tasks

Создать задачу транскрибации. Макс. 3 параллельные задачи на пользователя.

Тело запроса

ПолеТипОбязательноОписание
diskstringYesr2 / remote / youtube Идентификатор источника хранения
namestringYesНазвание задачи (макс. 255)
pathstringYesПуть к файлу или исходный URL
filestringNoИсходное имя файла (макс. 255)
sizeintegerNoРазмер файла в байтах
durationintegerNoПродолжительность в секундах
costintegerNoСтоимость в секундах
segmentsarrayNoСегменты транскрипции
speaker_diarizationbooleanНетapp.tasks.speaker_diarization_api_description

Ответ 201

{
    "id": 1,
    "name": "Meeting Recording",
    "status": "pending",
    "speaker_diarization": true,
    "created_at": "2026-03-02T10:30:00+08:00"
}

Ошибки

СтатусОписание
403Бесплатные пользователи не могут отправлять ссылки YouTube через API.
429Достигнут лимит параллельных задач (3)
GET /api/tasks/{id}

Получить полные детали задачи, включая результаты транскрибации.

Ответ

{
    "id": 1,
    "name": "Meeting Recording",
    "file": "meeting.mp3",
    "path": "2026-03-02/01HQX...mp3",
    "disk": "r2",
    "size": 50545869,
    "duration": 1965,
    "cost": 33,
    "status": "finished",
    "attempts": 1,
    "quality": 3,
    "created_at": "2026-03-02T10:30:00+08:00",
    "updated_at": "2026-03-02T10:45:00+08:00",
    "summary": "The meeting discussed three topics...",
    "mindmap": "# Topic\n## Sub-topic 1",
    "folder": "Work",
    "tags": ["Work"],
    "url": "https://youtube.com/watch?v=...",
    "segments": [
        {
            "id": 1,
            "start": 0,
            "end": 5000,
            "speaker": "Speaker 1",
            "tokens": ["Okay", "so let's", "begin"],
            "text": "Okay, so let's begin..."
        }
    ],
    "export": {
        "allowed_formats": ["txt", "srt", "vtt", "csv", "pdf", "docx"],
        "heavy_formats": ["pdf", "docx"],
        "version": "20260302104500"
    }
}

Поля ответа

ПолеТипОписание
diskstring|nullДиск хранения: r2 / remote / youtube
sizeint|nullРазмер файла в байтах
costint|nullСтоимость в секундах
attemptsintКоличество повторов
qualityint|nullОценка качества (0-5)
summarystring|nullРезюме, сгенерированное ИИ
mindmapstring|nullМайндмэп, сгенерированный ИИ
folderstring|nullИмя первой метки (папка)
tagsarrayВсе имена меток
urlstring|nullИсходный URL (для задач YouTube)
segmentsarray|nullСегменты транскрипции
segments[].startintВремя начала (мс)
segments[].endintВремя окончания (мс)
segments[].textstringТекст сегмента
segments[].speakerstring|nullИдентификатор спикера
segments[].tokensarray|nullМассив токенов слов
exportobjectМетаданные экспорта (allowed_formats, heavy_formats, version)
GET /api/tasks

Параметры запроса

ПараметрТипПо умолчаниюОписание
statusstringallФильтровать по статусу
searchstring—Искать по имени
folderstring—Фильтровать по папке (или Uncategorized)
pageint1Номер страницы
per_pageint25Элементов на странице (макс. 100)

Ответ

{
    "data": [
        {
            "id": 1,
            "name": "Meeting Recording",
            "file": "meeting.mp3",
            "disk": "r2",
            "size": 50545869,
            "duration": 1965,
            "cost": 33,
            "status": "finished",
            "attempts": 1,
            "quality": 3,
            "folder": "Work",
            "created_at": "2026-03-02T10:30:00+08:00"
        }
    ],
    "current_page": 1,
    "last_page": 1,
    "per_page": 25,
    "total": 1
}
PATCH /api/tasks/{id}/retry

Повторить неудачную задачу. Устанавливает статус в pending (R2) или waiting (remote/YouTube). Макс. 3 повтора.

Ответ 200

{
    "id": 1,
    "status": "pending",
    "attempts": 2
}
GET /api/tasks/{id}/download/{format}

Экспортировать транскрипт. Лёгкие форматы возвращают файл напрямую. Тяжёлые форматы (pdf/docx) могут возвращать 202 во время обработки.

Параметры пути

ПараметрОписание
formattxt / srt / vtt / csv / pdf / docx

Ответы

200 - Файл готов (лёгкие форматы)

Возвращает бинарный файл.

200 - Файл готов (тяжёлые форматы, JSON-запрос)

{
    "status": "ready",
    "url": "https://scribe.uustudio.cc/api/tasks/1/download/pdf"
}

202 - Обработка тяжёлого формата

{
    "status": "processing",
    "message": "Your export is being generated. Please try again shortly."
}
GET /api/tasks/{id}/audio

Передавать исходный аудио- или видеофайл напрямую из хранилища (только R2).

Ответ

200 - Бинарный поток аудио- или видеофайла. Возвращает 404, если файл отсутствует или не хранится на диске R2.

GET /api/tasks/{id}/refresh-summary

Обновить и вернуть последнее резюме и майндмэп, сгенерированные ИИ.

Ответ

{
    "summary": "The meeting discussed three topics...",
    "mindmap": "# Topic\n## Sub-topic 1"
}
GET /api/tasks/{id}/share-url

Get or generate a public share URL for the task.

Ответ

{
    "share_url": "https://scribe.uustudio.cc/share/tasks/1"
}
PATCH /api/tasks/{id}

Обновить поля задачи. Все поля опциональны.

Тело запроса

ПолеТипОписание
namestringНовое имя (макс. 255)
folderstring|nullИмя папки (null удаляет задачу из папки)
durationintegerПродолжительность в секундах
costintegerСтоимость в секундах
segmentsarrayПолный массив сегментов для замены
textstringПолный текст транскрипции
qualityintegerОценка качества (0-5)
indexintegerИндекс сортировки задачи

Ответ 200

Возвращает полный объект задачи (то же, что и Детали задачи).

DELETE /api/tasks/{id}

Response 200

{
    "message": "Task deleted successfully"
}
DELETE /api/tasks/bulk

Удалить несколько задач за раз. Будут удалены только задачи, принадлежащие аутентифицированному пользователю. ID, не принадлежащие пользователю, игнорируются.

Тело запроса

ПолеТипОбязательноОписание
idsarrayYesМассив ID задач для удаления (мин 1)

Ответ 200

{
    "message": "2 task(s) deleted successfully",
    "deleted_count": 2
}
PATCH /api/tasks/bulk/move

Переместить несколько задач в папку за раз. Будут перемещены только задачи, принадлежащие аутентифицированному пользователю.

Тело запроса

ПолеТипОбязательноОписание
idsarrayYesМассив ID задач для перемещения (мин 1)
folderstringYesИмя целевой папки (макс 255)

Ответ 200

{
    "message": "2 task(s) moved to Work",
    "moved_count": 2
}

Загрузки

Многочастная загрузка
POST /api/uploads/sign

Тело запроса

ПолеТипОбязательноОписание
filestringYesИмя файла (должен использоваться поддерживаемый формат)
content_typestringYesMIME-тип (должен соответствовать расширению файла)
sizeintegerYesРазмер файла в байтах (макс. 2 147 483 648 / 2 ГБ)
durationintegerNoПродолжительность аудио в секундах

Ответ

{
    "path": "2026-03-02/01HQX...mp3",
    "upload_id": "abc123",
    "part_size": 5242880,
    "part_count": 10,
    "expires_at": "2026-03-02T10:40:00+08:00"
}
POST /api/uploads/sign-part

Тело запроса

ПолеТипОбязательноОписание
pathstringYesПуть загрузки (макс. 2048)
upload_idstringYesID загрузки (макс. 2048)
part_numberintegerYesНомер части (1-10000)

Ответ

{
    "url": "https://storage.example.com/...?X-Amz-...",
    "headers": {
        "Content-Type": "audio/mpeg"
    }
}

Используйте PUT с возвращёнными URL и заголовками для загрузки части.

POST /api/uploads/complete

Завершить многочастную загрузку. Автоматически создаёт задачу и возвращает 403, если API недоступен или превышен лимит тарифа.

Тело запроса

ПолеТипОбязательноОписание
pathstringYesПуть загрузки (макс. 2048)
upload_idstringYesID загрузки (макс. 2048)
original_namestringYesИсходное имя файла (должен использоваться поддерживаемый формат)
content_typestringYesMIME-тип (должен соответствовать расширению файла)
sizeintegerYesРазмер файла в байтах (макс. 2 ГБ)
namestringNoНазвание задачи (по умолчанию имя файла без расширения)
durationintegerNoПродолжительность в секундах (мин. 1)
speaker_diarizationbooleanНетapp.tasks.speaker_diarization_api_description

Ответ 201

{
    "message": "File uploaded to the upload server successfully.",
    "task": {
        "id": 1,
        "name": "meeting",
        "path": "2026-03-02/01HQX...mp3",
        "size": 50545869,
        "status": "pending",
        "speaker_diarization": true
    }
}
POST /api/uploads/abort

Тело запроса

ПолеТипОбязательноОписание
pathstringYesПуть загрузки (макс. 2048)
upload_idstringYesID загрузки (макс. 2048)

Ответ

{
    "message": "Multipart upload cancelled successfully."
}

Папки

На основе меток
GET /api/folders

Список всех папок с количеством задач.

Ответ

{
    "folders": [
        {"id": 1, "name": "Work", "count": 5},
        {"id": 2, "name": "Personal", "count": 3}
    ],
    "uncategorized_count": 2,
    "total_count": 10
}
POST /api/folders

Тело запроса

ПолеТипОбязательноОписание
namestringYesИмя папки (макс. 14 символов / 7 китайских символов, уникально для пользователя)

Ответ 201

{
    "id": 1,
    "name": "Work"
}
PATCH /api/folders/{name}

Тело запроса

ПолеТипОбязательноОписание
namestringYesНовое имя папки (те же ограничения, что при создании)

Ответ 200

{
    "id": 1,
    "name": "New Name"
}
DELETE /api/folders/{name}

Response 200

{
    "message": "Folder deleted successfully"
}

Пользователь

GET /api/user

Ответ

{
    "id": 1,
    "name": "Zhang San",
    "email": "[email protected]",
    "avatar": "https://...",
    "balance": {
        "used_seconds": 9000,
        "remaining_seconds": 36000,
        "allowance_remaining_seconds": 30000,
        "top_up_remaining_seconds": 6000,
        "total_seconds": 45000,
        "usage_percent": 20
    },
    "subscription": {
        "plan": "year",
        "plan_key": "max_yearly",
        "tier": "max",
        "billing_interval": "yearly",
        "active": true,
        "access_tier": "max"
    },
    "queue": {
        "pending_count": 1,
        "running_count": 1,
        "failed_count": 0
    }
}

Поля баланса

ПолеТипОписание
used_secondsintИспользовано секунд с последнего месячного начисления
remaining_secondsintОставшиеся секунды
total_secondsintВсего секунд
usage_percentintПроцент использования (0-100)
PUT /api/user

Тело запроса

ПолеТипОбязательноОписание
namestringNoОтображаемое имя (макс. 255)
emailstringНетНовый email (должен быть уникальным)
avatarfileNoФайл изображения (макс. 5 МБ)

Ответ 200

{
    "id": 1,
    "name": "New Name",
    "email": "[email protected]",
    "avatar": "https://..."
}

Уведомления

GET /api/notifications

Получить 10 последних уведомлений.

Ответ

[
    {
        "id": "abc123",
        "title": "Task Completed",
        "message": "Meeting Recording has been transcribed.",
        "read_at": null,
        "created_at": "2026-03-02T10:45:00+08:00"
    }
]
POST /api/notifications/mark-all-as-read

Отметить все непрочитанные уведомления как прочитанные.

Response 200

{
    "success": true
}

Оплата

GET /api/checkout/{plan}

Получить URL оформления заказа Paddle для тарифного плана.

Параметры пути

ПараметрОписание
plantest / month / year

Ответ

Возвращает объект параметров оформления заказа Paddle. Возвращает 404 для недействительного тарифа.

GET /api/health

Публичный эндпоинт проверки работоспособности. Не требует аутентификации.

Ответ 200

{
    "status": "ok"
}