API 文档

面向音频和视频转录的 REST API。付费客户可使用在账户设置中创建的 API 密钥鉴权第三方集成。

基础地址

https://scribe.uustudio.cc

鉴权

第三方集成必须在 Authorization 请求头中携带付费账户的 API 密钥。

Authorization 请求头

Authorization: Bearer {token}

请在账户设置的 API 密钥页面创建和吊销密钥。App 鉴权接口仅供第一方客户端使用。

错误响应

所有错误都会返回包含 message 字段的 JSON 响应体。

标准错误响应

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

校验错误(422)

{
    "message": "The name field is required.",
    "errors": {
        "name": ["The name field is required."]
    }
}
状态码说明
401未认证(token 缺失或无效)
403无权限或超出套餐限制
404资源不存在
422校验失败
429请求过于频繁或并发任务过多
500服务器内部错误

限流规则

已认证 API 接口按每个 token 每分钟 10 次限流。

使用限制

API 可用性

免费版不提供第三方 REST API。升级到 Pro 或 Max,或购买按需付费套餐后,才可创建和使用 API 密钥。

最大文件大小
2 GB
并发任务数
最多 3 个
每个任务最大重试次数
3

付费套餐对比

功能项按需付费ProMax
每日上传次数不限不限不限
导出格式全部全部全部
任务优先级中中高

工作流

上传音频/视频文件

  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

使用邮箱和密码登录,返回 Sanctum token。

请求体

字段类型必填说明
emailstringYes用户邮箱(最多 255 字符)
passwordstringYes用户密码

响应 200

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

按邮箱每分钟最多允许 5 次尝试。

POST /api/register

创建新账号,返回 Sanctum token。

请求体

字段类型必填说明
namestringYes显示名称(最多 255 字符)
emailstringYes唯一邮箱(最多 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 支持的提供商
codestringYesOAuth 授权码

响应 200

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

撤销当前访问 token。

响应 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免费用户不能通过 API 提交 YouTube 链接。
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|nullAI 生成的摘要
mindmapstring|nullAI 生成的思维导图
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 - 返回音频或视频文件的二进制流。如果文件不存在或不在 R2 磁盘上,则返回 404。

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

刷新并返回最新的 AI 摘要和思维导图。

响应

{
    "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 GB)
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_idstringYes上传 ID(最多 2048 字符)
part_numberintegerYes分片编号(1-10000)

响应

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

请使用返回的 URL 和 headers 发起 PUT 以上传该分片。

POST /api/uploads/complete

完成分片上传。该操作会自动创建转录任务;如果 API 不可用或超出套餐限制,会返回 403。

请求体

字段类型必填说明
pathstringYes上传路径(最多 2048 字符)
upload_idstringYes上传 ID(最多 2048 字符)
original_namestringYes原始文件名(必须为支持的格式)
content_typestringYesMIME 类型(必须与文件扩展名匹配)
sizeintegerYes文件字节大小(最大 2 GB)
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_idstringYes上传 ID(最多 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否新邮箱(必须唯一)
avatarfileNo图片文件(最大 5 MB)

响应 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}

获取订阅套餐对应的 Paddle 结算 URL。

路径参数

参数说明
plantest / month / year

响应

返回 Paddle checkout options 对象。若套餐无效则返回 404。

GET /api/health

公开健康检查接口,无需认证。

响应 200

{
    "status": "ok"
}