📖 标准文档🤖 接单版(V1)🏪 代理版(V2)🔒
本文档⬇ .mdAgent 文档⬇ .md
本文档 = 标准接口参考(人看);Agent 文档 = 自包含引导,粘给任意 AI 让它生成前后端。

API 接入文档(v1 · 已实现版)

> 2026-11-04 · 本文与线上实际接口一致,可直接照着写代码。

一、基础

项值
Base URLhttp://<你的域名>/v1
鉴权Authorization: Bearer sk-live-xxxx
内容类型application/json(上传资产支持 multipart)
可选头X-Sub-User: 你的客户标识(用量归集用)
可选头Idempotency-Key: 任意字符串(24 小时内重放返回同一任务,不重复扣点)

怎么拿 key:登录网页 → 点「充值」→ 底部「API 接入」→ 新建 key(明文只显示一次)。

二、9 个功能(kind)

kind说明同步参数
script写剧本✅input.text
video视频提示词✅input.text
storyboard分镜提示词✅input.text
drama文戏提示词✅input.text
fight武戏提示词✅input.text
edit改图提示词✅input.text、input.asset(必填)、input.model(建议指定)
wan3_prompt全能视频短剧·写提示词✅input.text、input.sec、input.resolution
t2i文生图❌ 异步input.text
reverse图片反推❌ 异步input.asset(必填)
drama_gen短剧生成❌ 异步input.text、input.target_sec
wan3全能视频短剧·出片❌ 异步input.prompt、input.prompt_job(必填)、input.sec、input.resolution

实时单价一律从 GET /v1/caps 读,不要硬编码。

关于 input.model(改图 / 文生图)

两个模型的提示词格式不一样,必须告诉接口你打算用哪个:

model应用图片引用格式说明
模型B模型B-Image 2.1<image1> <image2>尖括号标记(官方规范)
模型A模型A(改图)「图1」「图2」K2 不认尖括号,写了也无效
模型C模型C「图1」同 模型A 口径
模型A(t2i)模型A 文生图—文生图默认就是这个

不传 model 就走站内默认;传了但匹配不到应用会返回 400 并列出可用值。

POST /v1/jobs
{ "kind": "edit",
  "input": { "text": "把背景换成雪夜街道,人物不动",
             "asset": "ast_xxx",
             "model": "模型A" } }

返回(模型A 口径,注意是「图1」不是 <image1>):

保持图1中人物的身份、五官、发型、姿势、表情、视线、服装、肢体动作和画面位置完全不变,
只替换人物身后的背景。把原背景整体换成雪夜街道……

三、接口

1. 创建任务

POST /v1/jobs
{
  "kind": "script",
  "input": { "text": "一个外卖骑手在暴雨里接单,到了地址发现客户是前女友" },
  "wait": 45
}
字段说明
kind见上表
input按 kind 不同
wait0(默认,立即返回)/ 1~60(最多等这么多秒)

响应(已完成)

{
  "id": "20261104_180521_747680",
  "kind": "script",
  "status": "done",
  "points": 17,
  "points_raw": 18,
  "created": 1793786721.4,
  "elapsed_ms": 40120,
  "result": { "text": "【场景1】……" }
}

响应(异步,wait=0)

{
  "id": "20261104_180742_0783c6",
  "kind": "wan3",
  "status": "queued",
  "points": 100,
  "points_raw": 100,
}

points_raw 是估点数,points 是实际要扣的点数(已经算好,直接按它扣)。

2. 查询任务

GET /v1/jobs/{id}
{
  "id": "20261104_180742_0783c6",
  "kind": "wan3",
  "status": "done",
  "points": 100,
  "elapsed_ms": 188230,
  "result": {
    "text": "已出片:1 个文件 · 1 段 · 扣 100 点",
    "videos": [
      {
        "url": "/v1/files/20261104_180742_0783c6/0",
        "type": "video",
        "name": "20261104_180742_0783c6_seg01.mp4",
        "bytes": 1162369
      }
    ]
  }
}

status:queued / running / done / failed / canceled

result 结构

3. 取消任务

POST /v1/jobs/{id}/cancel

只有 queued 能取消(running 返回 409)。

4. 下载产物

GET /v1/files/{job_id}/{index}?key=sk-live-xxxx

index 就是 result.videos[0] / result.images[0] 里的序号(从 0 开始)。

为什么要 ?key=:<video src> / <img src> 带不了 Authorization 头,所以这个接口额外接受 query 里的 key。

5. 能力清单

GET /v1/caps
{
  "kinds": {
    "script": { "group": "prompt", "sync": true, "available": true, "points": 18 },
    "wan3": {
      "group": "video", "sync": false, "available": true,
      "sec_range": [2, 30],
      "resolutions": {
        "480P": { "points_per_sec": 20 },
        "720P": { "points_per_sec": 34 },
        "1080P": { "points_per_sec": 65 }
      },
      "require": "prompt_job"
    }
  },
  "is_agent": false,
  "balance": 2900,
  "user": { "id": 1, "name": "admin" }
}

points / points_per_sec 就是最终要扣的点数,直接按它扣,不用自己再换算。

6. 余额

GET /v1/balance
→ { "points": 2900, "today_used": 0, "day_limit": 0, "is_agent": false }

7. 上传资产

POST /v1/assets

方式 A:JSON base64

{ "data": "data:image/png;base64,iVBORw0...", "name": "参考图", "media": "image" }

方式 B:multipart

curl -X POST http://<域名>/v1/assets \
  -H "Authorization: Bearer sk-live-xxxx" \
  -F "[email protected]" -F "media=image"
{ "id": "ast_dd0ff6857e", "name": "参考图", "media_type": "image", "bytes": 139982,
  "url": "/api/asset-image/ast_dd0ff6857e" }

拿到 id 后,reverse / t2i / wan3 的 input.asset 传它。

8. 用量

GET /v1/usage?from=2026-11-01&to=2026-11-04&group=kind
{
  "from": "2026-11-01", "to": "2026-11-04", "group": "kind",
  "total_jobs": 8, "total_points": 285,
  "groups": [
    { "key": "wan3", "jobs": 2, "points": 200 },
    { "key": "script", "jobs": 1, "points": 18 }
  ]
}

group 可选 day / kind / sub_user。

9. 流水

GET /v1/ledger?limit=50
{
  "items": [
    { "kind": "consume", "points": -100, "job_id": "20261104_180742_0783c6",
      "api_kind": "wan3", "status": "done", "created": 1793786862.4 }
  ],
  "limit": 50, "offset": 0
}

kind = consume(消耗)/ refund(失败退回,points 为 0 表示已退回)。

10. 自己管理 key

GET    /v1/keys            列 key
POST   /v1/keys            新建({"name":"生产"})→ 返回明文一次
DELETE /v1/keys/{kid}      吊销

> 第一个 key 必须在网页上建(「充值」→「API 接入」),之后可以用 API 管理。

四、完整示例:全能视频短剧(两步)

import requests, time

BASE = "http://your-domain/v1"
H = {"Authorization": "Bearer sk-live-xxxx"}

# 第①步:写 视频提示词(这一步扣提示词费)
p = requests.post(f"{BASE}/jobs", headers=H, json={
    "kind": "wan3_prompt",
    "input": {"text": "一个女孩站在暴雨的街口,抬头看路灯", "sec": 5, "resolution": "480P"},
    "wait": 60,
}, timeout=120).json()

print(p["status"], p["points"])          # done 15
prompt = p["result"]["text"]

# 客户可以随便改这段提示词
prompt = prompt.replace("路灯", "钠灯")

# 第②步:出片(必须带 prompt_job,扣出片费)
v = requests.post(f"{BASE}/jobs", headers=H, json={
    "kind": "wan3",
    "input": {
        "prompt": prompt,
        "prompt_job": p["id"],
        "sec": 5,
        "resolution": "480P",
    },
    "wait": 0,
}).json()

# 轮询
while True:
    j = requests.get(f"{BASE}/jobs/{v['id']}", headers=H).json()
    if j["status"] in ("done", "failed", "canceled"):
        break
    time.sleep(5)

print(j["status"], j["points"])
video = j["result"]["videos"][0]
url = f"http://your-domain{video['url']}?key=sk-live-xxxx"
open("out.mp4", "wb").write(requests.get(url).content)

五、限流与错误

项默认
QPS10 次/秒
并发任务5 个
单文件≤ 20MB

错误结构

{ "detail": { "code": "insufficient_points", "message": "需要 100 点,当前 40 点" } }
codeHTTP含义
invalid_api_key401key 无效/吊销
account_blocked403账号被封
insufficient_points402点数不足
rate_limited429超出并发/QPS
invalid_input400参数错误
not_ready501该 kind 还没开放
job_not_found404任务/产物不存在
job_not_cancelable409已开始跑,不能取消

六、数据模型

6.1 Job 对象

字段类型说明
idstring任务 ID,形如 20261104_180521_747680
kindstring功能名,见第二节
statusstringqueued / running / done / failed / canceled
pointsinteger实扣点数(直接按它扣)
points_rawinteger创建时的估点数,仅创建时返回
creatednumber创建时间,Unix 秒(带小数)
elapsed_msinteger从开始执行到结束的毫秒数,未完成时为 null
resultobject见 6.2,仅 done 时有
errorstring失败原因,仅 failed 时有

6.2 Result 对象

字段类型说明
textstring提示词 / 剧本内容。出片类也可能有一句说明
videosarray视频产物,见 6.3
imagesarray图片产物,见 6.3

三个字段至少有一个。

6.3 Media 对象

字段类型说明
urlstring相对路径,如 /v1/files/xxx/0,必须拼域名 + ?key=
typestringvideo / image
namestring原始文件名
bytesinteger文件大小
secnumber\null视频时长(秒),图片为 null

6.4 Kind 枚举

值中文分组同步
script写剧本prompt✅
video视频提示词prompt✅
storyboard分镜提示词prompt✅
drama文戏提示词prompt✅
fight武戏提示词prompt✅
edit改图提示词prompt✅
wan3_prompt全能视频短剧·写提示词prompt✅
t2i文生图image❌
reverse图片反推image❌
drama_gen短剧生成video❌
wan3全能视频短剧·出片video❌

6.5 错误对象

{ "detail": { "code": "insufficient_points", "message": "需要 100 点,当前 40 点" } }

⚠️ 注意:错误体是 detail 包裹的。你的后端要给前端用,记得先解包

(body.detail.code / body.detail.message)。

七、幂等与重试

7.1 幂等

POST /v1/jobs
Idempotency-Key: <你生成的唯一字符串,建议 UUID>

7.2 什么情况可以重试

情况能不能重试怎么做
网络超时、连接被重置✅带同一个 Idempotency-Key 重发
429 rate_limited✅按 Retry-After 退避(没这个头就等 5 秒)
502 upstream_error✅等 10 秒重试,最多 3 次
504 timeout✅任务还在跑,转成轮询 GET /jobs/{id}
401 / 402 / 403 / 400❌改配置或充值,重试无用

7.3 轮询建议

间隔:5 秒
上限:10 分钟(出片类一般 3~6 分钟能出)
超过上限:判超时,不要再等,去后台看任务状态

不要用 1 秒间隔轮询——会撞 QPS 限流(429)。

八、变更日志

日期变更
2026-11-04首次发布 v1。11 个 kind,6 个接口。新增 wan3 两步流程(prompt_job 校验)、edit 的 model 参数、/v1/files 下载
—后续变更按「日期 + 改了什么 + 影不影响调用方」补在这里