YumCut v0.1.0 API 使用详解
YumCut v0.1.0 User API 实测详解:Bearer Key 认证与 read/write 作用域、49 个 OpenAPI 路径按十大域分组,账户/代币/项目生命周期/审批状态机/签名上传授权逐条 curl 实测,含 Idempotency-Key 幂等强制与五类错误码速查排障。
YumCut v0.1.0 API 使用详解
目标:把 YumCut v0.1.0 的 User API 讲透并逐条跑通——认证方式、API Key 作用域、账户/代币/设置、项目全生命周期(创建→审批→下载)、媒体上传授权、目录数据、调度与 Telegram 集成,以及统一错误码。全部示例为 curl 实测,回显逐行照抄(取值日期 2026-10-25,实测环境为部署篇搭建的四服务编排,地址
http://192.168.146.128:8130)。部署与 API Key 开通见《YumCut v0.1.0 Docker Compose 部署指南》,参数含义见《YumCut v0.1.0 配置参数详解》。
一、API 概览
YumCut 对外提供一套面向自动化的 User API(OpenAPI 3.1 文档,标题 YumCut User API),设计目标是让外部工具、定时任务与 AI Agent 端到端完成「建项目 → 审批 → 取成片」:
- Base 路径:
/api/user/v1(OpenAPIservers定义为「当前部署」,即https://<你的域名>/api/user/v1) - 认证:
Authorization: Bearer <API Key>,Key 以ycu_开头 - 规模:实测
openapi.json共 49 个路径,覆盖账户、代币、设置、项目、审批、下载、媒体授权、音色/模板/角色目录、调度器、Telegram 十大域 - 幂等:所有「创建类」端点强制要求
Idempotency-Key头(实测见 5.1)
💡 技术拓展:API 密钥认证不止 Bearer 一种形态。常见方案对比——
方案 特点 适用场景 Bearer Token 一个头搞定,配合 HTTPS 使用 服务端到服务端调用,YumCut 所用 HMAC 签名 请求级签名防重放 高安全开放平台和金融接口 OAuth2 Client Credentials 可轮换、可过期 多租户 SaaS 开放平台 YumCut 选 Bearer + 作用域(read/write)两档,胜在简单;代价是 Key 泄露即全权,务必只放服务端保管。
二、认证与 API Key
2.1 Key 的格式与存储
API Key 明文形如 ycu_ 加 43 位 base64url 随机串(32 字节),只在创建时可见;数据库 UserApiKey 表只存 SHA-256 摘要(tokenHash)与前 12 位前缀(tokenPrefix),泄露数据库不泄露 Key。创建方法见部署篇 5.3。
2.2 作用域(read / write)
Key 创建时可指定 scopes,缺省 ["read","write"] 全开。实测一把只有 read 作用域的 Key:
# 读接口:放行
curl -s -o /dev/null -w 'HTTP %{http_code}\n' \
-H "Authorization: Bearer <read-only-key>" http://192.168.146.128:8130/api/user/v1/projects
实测回显:
HTTP 200
# 写接口:拒绝
curl -s -X PATCH -H "Authorization: Bearer <read-only-key>" \
-H 'Content-Type: application/json' \
http://192.168.146.128:8130/api/user/v1/account/language --data '{"language":"ru"}'
实测回显:
{"error":{"code":"FORBIDDEN","message":"User API key scope is insufficient"}}
不带 Key 与带错误 Key 一律 401:
curl -s -o /dev/null -w 'HTTP %{http_code}\n' http://192.168.146.128:8130/api/user/v1/projects
curl -s -o /dev/null -w 'HTTP %{http_code}\n' -H "Authorization: Bearer wrong-key" http://192.168.146.128:8130/api/user/v1/projects
实测回显:
HTTP 401
HTTP 401
三、账户与代币
3.1 账户信息 GET /account
curl -s -H "Authorization: Bearer $KEY" http://192.168.146.128:8130/api/user/v1/account
实测回显:
{"id":"eb07c821-d05c-11f1-bcea-02755b8cf07b","email":"admin@yumcut.local","name":"admin","image":null,"preferredLanguage":"en","createdAt":"2026-10-25T10:14:52.388Z","tokenBalance":500,"isGuest":false}
tokenBalance 是代币余额,建项目与重生成都从这里扣费。
3.2 语言偏好 GET/PATCH /account/language
界面与产物的默认语言,实测只接受 en/ru:
curl -s -X PATCH -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
http://192.168.146.128:8130/api/user/v1/account/language --data '{"language":"ru"}'
实测回显:
{"language":"ru"}
传非法值返回字段级校验错误(改回 en 的实测回显为 {"language":"en"}):
{"error":{"code":"VALIDATION_ERROR","message":"Invalid account language payload","details":{"formErrors":[],"fieldErrors":{"language":["Invalid option: expected one of \"en\"|\"ru\""]}}}}
3.3 代币余额与价目 GET /tokens
curl -s -H "Authorization: Bearer $KEY" http://192.168.146.128:8130/api/user/v1/tokens
实测回显:
{"balance":500,"perSecondProject":1,"minimumProjectTokens":30,"minimumProjectSeconds":30,"characterProjectTokens":75,"characterProjectTokenCosts":{"high":75,"low":10},"actionCosts":{"scriptRevision":10,"imageGeneration":3,"audioRegeneration":40,"imageRegeneration":1,"characterImage":10},"signUpBonus":90}
解读:余额 500;计费规则为「每秒视频 1 代币、最低 30 秒起(即建项目至少 30 代币)」;角色项目 75 代币;各项重生成单独计价(改脚本 10、重配音 40、重配图 1 等);注册赠送 90。
3.4 代币流水 GET /tokens/history
curl -s -H "Authorization: Bearer $KEY" http://192.168.146.128:8130/api/user/v1/tokens/history
实测回显(输出节选,实测首尾):
{"items":[{"id":"efa7e5a1-29e5-4583-b99f-ffd155e92bbf","delta":30,"balanceAfter":500,"type":"PROJECT_FAILURE_REFUND","description":"Project failed refund","initiator":"system:project-failure-refund","metadata":{"projectId":"38c7b956-1227-4ab6-bf47-ec8f160cb665"},"createdAt":"2026-10-25T10:24:48.385Z"},{"id":"cbce6cb2-a3f0-43d3-a1ed-2eea97fa3bb7","delta":-30,"balanceAfter":470,"type":"PROJECT_CREAT...
这条流水是「建项目扣 30 → 项目失败自动退 30」的完整闭环,type 字段可区分消费(PROJECT_CREATION)与退款(PROJECT_FAILURE_REFUND)。
3.5 全局设置 GET/PATCH /settings
curl -s -H "Authorization: Bearer $KEY" http://192.168.146.128:8130/api/user/v1/settings
实测回显(输出节选):
{"includeDefaultMusic":true,"addOverlay":true,"includeCallToAction":true,"projectEmailsEnabled":true,"autoApproveScript":true,"autoApproveAudio":true,"watermarkEnabled":true,"captionsEnabled":true,"characterCreationSettings":{"addOverlay":false,"watermarkEnabled":false,"captionsEnabled":true,"includeCallToAction":true},"defaultDurationSeconds":null,"sidebarOpen":true,...
解读:autoApproveScript/autoApproveAudio 全开时项目可无人值守跑完;关掉则流水线停在对应审批节点等 API 确认(审批端点见第六章)。
四、项目创建与报价
4.1 报价预检 POST /project-cost
建项目前先问价,不扣费:
curl -s -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
http://192.168.146.128:8130/api/user/v1/project-cost --data '{"durationSeconds":30}'
实测回显:
{"tokenCost":30,"balance":500,"hasEnoughTokens":true,"balanceAfter":470,"detail":{"projectExperience":"story","durationSeconds":30,"languageCount":1,"languages":["en"]}}
hasEnoughTokens 与 balanceAfter 直接给出「能不能建、建完剩多少」。
4.2 创建项目 POST /projects(强制幂等)
该端点必须携带 Idempotency-Key 头,缺少时直接报错:
curl -s -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
http://192.168.146.128:8130/api/user/v1/projects --data '{}'
实测回显:
{"error":{"code":"VALIDATION_ERROR","message":"Idempotency-Key header is required for this endpoint"}}
带上幂等键后再逐项校验请求体(缺 durationSeconds 的实测报错):
curl -s -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
-H 'Idempotency-Key: doc-test-0001' \
http://192.168.146.128:8130/api/user/v1/projects --data '{}'
实测回显:
{"error":{"code":"VALIDATION_ERROR","message":"Duration is required","details":{"formErrors":[],"fieldErrors":{"durationSeconds":["Duration is required"]}}}}
⚠️ 幂等键的用法:同一个
Idempotency-Key重复提交只会创建一次项目,网络重试/超时重发不会产生重复扣费。键值可用 UUID 或「业务单号」,由调用方保证唯一。POST /groups等创建类端点同样强制该头。
4.3 项目查询与状态
列表 GET /projects(游标分页,limit 默认 50):
curl -s -H "Authorization: Bearer $KEY" http://192.168.146.128:8130/api/user/v1/projects
实测回显:
{"items":[{"id":"38c7b956-1227-4ab6-bf47-ec8f160cb665","title":"Explain why self-hosting sa...","status":"error","prompt":"Explain why self-hosting saves money, in a fun story style","finalVideoUrl":null,"finalVoiceoverUrl":null,"createdAt":"2026-10-25T10:16:04.923Z","updatedAt":"2026-10-25T10:24:48.412Z"}],"limit":50,"nextCursor":null}
详情 GET /projects/{projectId} 返回完整字段(含 rawScript、languageVariants 等,节选从略);轻量轮询用 GET /projects/{projectId}/status:
curl -s -H "Authorization: Bearer $KEY" \
http://192.168.146.128:8130/api/user/v1/projects/38c7b956-1227-4ab6-bf47-ec8f160cb665/status
实测回显:
{"status":"error","statusInfo":{"message":"Script generation failed Refunded 30 tokens to user balance due to project failure."},"updatedAt":"2026-10-25T10:24:48.412Z"}
该项目失败于脚本生成(渲染脚本工作区为私有仓库,预期失败,见介绍篇),失败后系统自动退款。进行中的项目可用 POST /projects/{projectId}/stop 主动停止。
五、审批流端点
项目状态机为「脚本 → 配音 → 画面 → 成片」逐级推进,每一级都有对应的 request/approve/regenerate 端点:
| 阶段 | 端点 | 作用 |
|---|---|---|
| 脚本 | POST /projects/{id}/script/request | 请求生成/改写脚本 |
| 脚本 | POST /projects/{id}/script/approve | 批准脚本,进入配音 |
| 脚本 | POST /projects/{id}/script/final | 提交最终脚本定稿 |
| 配音 | GET /projects/{id}/audios、POST .../audios/request、.../audios/approve、.../audios/regenerate | 配音候选、请求、批准、重生成 |
| 画面 | POST /projects/{id}/images/regenerate、.../images/replace | 逐张重生成/替换 |
| 成片 | POST /projects/{id}/video/recreate | 用当前素材重新合成 |
状态不匹配时返回 CONFLICT 而不是静默失败。实测对 error 状态的项目批准脚本:
curl -s -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
http://192.168.146.128:8130/api/user/v1/projects/38c7b956-1227-4ab6-bf47-ec8f160cb665/script/approve --data '{}'
实测回显:
{"error":{"code":"CONFLICT","message":"Project is not awaiting script approval"}}
六、下载与媒体授权
6.1 成片/配图下载
GET /projects/{id}/downloads/video 与 .../downloads/image 返回带时效的下载 URL。成片未产出时返回 404:
curl -s -H "Authorization: Bearer $KEY" \
http://192.168.146.128:8130/api/user/v1/projects/38c7b956-1227-4ab6-bf47-ec8f160cb665/downloads/video
实测回显:
{"error":{"code":"NOT_FOUND","message":"Final video not found"}}
6.2 上传授权 POST /storage/upload-token
向存储服务上传文件前,先向主应用换取一份 RSA 签名授权:
curl -s -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
http://192.168.146.128:8130/api/user/v1/storage/upload-token \
--data '{"kind":"user-image","contentType":"image/png","sizeBytes":1024}'
实测回显(签名值已截断):
{"data":"{\"expiresAt\":\"2026-10-25T10:52:36.240Z\",\"issuedAt\":\"2026-10-25T10:47:36.240Z\",\"maxBytes\":10485760,\"mimeTypes\":[\"image/png\",\"image/jpeg\",\"image/webp\"],\"nonce\":\"aa9efd0cef20bd7ae579524e95851950\",\"purpose\":\"user-character-image\",\"userId\":\"eb07c821-d05c-11f1-bcea-02755b8cf07b\",\"version\":1}","signature":"o6pvXevlwZQNuCkkxiaTahAwqjx5CrZKiEn70+vqqULn/DL2LimiFYv0Vt(已截断)"}
解读:data 是授权明文(5 分钟有效、限 10 MB、限三种图片类型、一次性 nonce),signature 是主应用私钥对它的签名;上传时把两者一并 POST 给存储服务,存储用公钥验签放行。相关角色端点还有 POST /characters/custom/upload(上传自定义角色图)与 POST /characters/custom/generate(生成角色)。
6.3 媒体访问授权 POST /media/grant
为媒体路径换取访问授权;路径不存在时返回:
{"error":{"code":"FORBIDDEN","message":"File not found"}}
七、目录数据端点
以下均为只读目录,供建项目时选音色/模板/角色:
| 端点 | 实测回显(节选) | 说明 |
|---|---|---|
GET /voices | {"voices":[],"providerAvailabilityRules":[{"projectExperiences":["character"],"modes":["idea"],"languages":["ru"],"providers":["inworld"]}]} | 音色列表按服务商可用性规则过滤;未配置 AI 服务商时为空 |
GET /templates | [] | 视频模板,初始为空 |
GET /templates/{id} | 模板详情 | 按 ID 取单条 |
GET /characters | {"global":[{"id":"359d74c2-...","title":"Ada Mentor","description":"Precise host for educational narratives.","variations":[{"id":"3695ecba-...","imageUrl":"http://192.168.146.128:8129/api/media/characters/me-1.png","status":"ready"}]},...]} | 内置全局角色库,含变体与预览图(URL 即存储服务的 STORAGE_PUBLIC_URL 拼接结果) |
GET /characters/catalog | {"categories":[{"id":"brainrot","title":{"en":"Brainrot","ru":"Brainrot"},"subtitle":{"en":"Viral short-form characters with chaotic social energy",...}},...]} | 角色分类目录,多语言文案 |
GET /characters/{slug}、GET /characters/variations/{variationId}/preview-image | 角色详情/变体预览图 | 按标识取单条 |
POST /characters/{slug}/favorite、DELETE 同址 | 收藏/取消收藏 | 写端点,需 write 作用域 |
POST /characters/mine、POST /characters/mine/{id}/variations、DELETE .../variations/{vid} | 我的角色与变体管理 | 写端点 |
GET /image-pranks | {"categories":[]} | 图片恶作剧目录 |
GET /image-pranks/{slug}、GET /projects/{id}/image-prank-reuse | 恶作剧详情/项目复用 | — |
POST /groups | 项目分组创建 | 强制 Idempotency-Key(实测同 4.2) |
八、调度与集成端点
| 端点 | 作用 | 实测 |
|---|---|---|
GET/PATCH/POST /scheduler/settings | 定时发布设置 | 实测返回 {"enabled":false}(ENABLE_PUBLISH_SCHEDULER=0) |
POST /scheduler/channels | 绑定 YouTube 发布频道 | 实测返回 {"error":{"code":"FORBIDDEN","message":"Scheduler is disabled"}} |
DELETE /scheduler/channels/{channelId}、POST .../revoke | 解绑/撤销授权 | 调度器关闭时同样被拦 |
POST /scheduler/projects/{projectId}、POST /scheduler/tasks/{taskId}/cleanup-request | 排期发布/清理任务 | 同上 |
GET/DELETE /telegram/account | Telegram 绑定状态 | 实测返回 {"connected":false,"account":null,"enabled":false} |
POST /telegram/link-token | 生成绑定令牌 | 需配置 TELEGRAM_BOT_TOKEN 后可用 |
这组端点的实测一致说明:调度与 Telegram 属于「配置驱动」能力,对应参数未开启时 API 返回明确的禁用错误而不是超时或 500。
九、错误码速查与排障
把全文实测到的错误归拢成一张速查表:
| HTTP | code | 触发场景 | 处理 |
|---|---|---|---|
| 401 | UNAUTHORIZED | 无 Key / Key 错误(Invalid user API key) | 检查 Authorization: Bearer 头 |
| 403 | FORBIDDEN | 作用域不足(scope is insufficient)、功能未启用(Scheduler is disabled)、媒体路径不存在 | 换 write Key / 开启对应配置 |
| 404 | NOT_FOUND | 成片未产出(Final video not found) | 先查 /status,等流水线完成 |
| 409 | CONFLICT | 状态机不允许当前操作(not awaiting script approval) | 按 /status 的当前状态选正确端点 |
| 400 | VALIDATION_ERROR | 缺 Idempotency-Key、字段缺失/非法 | 按 details.fieldErrors 逐项修正 |
排障通则:先 GET /projects/{id}/status 看状态机位置,再对照上表选端点;扣费疑问用 GET /tokens/history 的流水逐笔核对,失败项目会有 PROJECT_FAILURE_REFUND 自动退款。
十、参考链接
- 主应用仓库(OpenAPI 定义随源码分发,快照 6401fe6,查询日期 2026-10-25):https://github.com/IgorShadurin/app.yumcut.com
- 部署与 API Key 开通:《YumCut v0.1.0 Docker Compose 部署指南》
- 参数与功能开关:《YumCut v0.1.0 配置参数详解》
- 项目定位与选型边界:《YumCut v0.1.0 介绍与选型指南》