<title>KOKO 视频生成 API</title>
<style>
:root{
  --sa-accent:#18745b; --sa-accent-2:#12553f;
  --bg:#fafbfc; --fg:#182433; --muted:#5b6b7c; --line:#e3e8ee;
  --card:#ffffff; --code-bg:#f4f6f8; --code-fg:#1f2933; --tbl-head:#f7f9fb;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#15191e; --fg:#e6edf3; --muted:#9aa7b4; --line:#2a3138;
    --card:#1b2026; --code-bg:#111519; --code-fg:#e6edf3; --tbl-head:#20262c;
  }
}
:root[data-theme="dark"]{
  --bg:#15191e; --fg:#e6edf3; --muted:#9aa7b4; --line:#2a3138;
  --card:#1b2026; --code-bg:#111519; --code-fg:#e6edf3; --tbl-head:#20262c;
}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);
  font-family:-apple-system,"Segoe UI","Microsoft YaHei",system-ui,sans-serif;
  -webkit-font-smoothing:antialiased;line-height:1.7;font-size:15px}
a{color:var(--sa-accent);text-decoration:none}
a:hover{color:var(--sa-accent-2);text-decoration:underline}
header.nav{position:sticky;top:0;z-index:20;background:var(--card);border-bottom:1px solid var(--line);
  backdrop-filter:saturate(180%) blur(8px)}
.nav-in{max-width:1240px;margin:0 auto;padding:12px 20px;display:flex;align-items:center;gap:12px}
.brand-mark{width:34px;height:34px;border-radius:6px;background:var(--sa-accent);display:grid;place-items:center;color:#fff;font-weight:800;font-size:15px}
.brand-name{font-weight:700}
.brand-tag{font-size:11px;color:var(--muted)}
.nav-spacer{flex:1}
.nav-links a{margin-left:16px;font-size:13px;color:var(--muted)}
.wrap{max-width:1240px;margin:0 auto;padding:24px 20px;display:grid;grid-template-columns:250px minmax(0,1fr);gap:32px}
aside.toc{position:sticky;top:72px;align-self:start;max-height:calc(100vh - 90px);overflow:auto;
  font-size:13px;border-right:1px solid var(--line);padding-right:12px}
aside.toc .toc-title{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin:4px 0 8px}
.toc-link{display:block;padding:4px 8px;border-radius:6px;color:var(--muted);line-height:1.5}
.toc-link:hover{background:var(--code-bg);color:var(--fg);text-decoration:none}
.toc-link.lv3{padding-left:20px;font-size:12.5px}
main{min-width:0}
h1{font-size:30px;margin:8px 0 18px;letter-spacing:-.01em}
h2{font-size:21px;margin:0 0 14px;padding-bottom:8px;border-bottom:1px solid var(--line)}
h3{font-size:17px;margin:22px 0 10px}
h4{font-size:15px;margin:18px 0 8px;color:var(--muted)}
.sa-section{background:var(--card);border:1px solid var(--line);border-radius:10px;padding:20px 22px;margin-bottom:20px}
p{margin:10px 0}
ul,ol{margin:10px 0;padding-left:24px}
li{margin:5px 0}
code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  font-size:.9em;background:var(--code-bg);padding:2px 6px;border-radius:5px;color:var(--code-fg);
  border:1px solid var(--line)}
pre{margin:0;overflow:auto}
pre code{background:none;border:0;padding:0;font-size:13px;line-height:1.55;color:var(--code-fg)}
.code-wrap{position:relative;background:var(--code-bg);border:1px solid var(--line);border-radius:8px;
  padding:12px 14px;margin:12px 0}
.code-lang{position:absolute;top:6px;right:10px;font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.tbl-wrap{overflow:auto;margin:12px 0;border:1px solid var(--line);border-radius:8px}
table{border-collapse:collapse;width:100%;font-size:13.5px}
th,td{border-bottom:1px solid var(--line);padding:8px 12px;text-align:left;vertical-align:top}
th{background:var(--tbl-head);font-weight:600;white-space:nowrap}
tr:last-child td{border-bottom:0}
blockquote{margin:14px 0;padding:10px 16px;border-left:3px solid var(--sa-accent);
  background:var(--code-bg);border-radius:0 8px 8px 0;color:var(--muted)}
hr{border:0;border-top:1px solid var(--line);margin:24px 0}
footer{max-width:1240px;margin:0 auto;padding:20px;color:var(--muted);font-size:12.5px;border-top:1px solid var(--line)}
@media (max-width:900px){
  .wrap{grid-template-columns:1fr;gap:16px}
  aside.toc{position:static;border-right:0;border-bottom:1px solid var(--line);padding:0 0 12px}
}
</style>
<header class="nav"><div class="nav-in">
  <div class="brand-mark">K</div>
  <div><div class="brand-name">KOKO 视频生成 API</div><div class="brand-tag">OpenAPI 文档</div></div>
  <div class="nav-spacer"></div>
  <div class="nav-links"><a href="https://pay.kokoai.online/">返回 KOKO Studio</a></div>
</div></header>
<div class="wrap">
  <aside class="toc">
    <div class="toc-title">目录</div>
      <a class="toc-link lv2" href="#s-1-api-key">1. API Key</a>
      <a class="toc-link lv2" href="#s-2-查看模型和价格">2. 查看模型和价格</a>
      <a class="toc-link lv2" href="#s-3-创建视频任务">3. 创建视频任务</a>
      <a class="toc-link lv3" href="#s-参数规则">参数规则</a>
      <a class="toc-link lv3" href="#s-幂等键和请求编号">幂等键和请求编号</a>
      <a class="toc-link lv3" href="#s-参考图">参考图</a>
      <a class="toc-link lv3" href="#s-minimax-h3-参考视频和音频">MiniMax H3 参考视频和音频</a>
      <a class="toc-link lv2" href="#s-4-查询任务">4. 查询任务</a>
      <a class="toc-link lv2" href="#s-5-提取视频地址与下载原文件">5. 提取视频地址与下载原文件</a>
      <a class="toc-link lv3" href="#s-5-1-推荐方式-查询任务-提取-video_url-再下载">5.1 推荐方式：查询任务，提取 video_url，再下载</a>
      <a class="toc-link lv3" href="#s-5-2-下载鉴权-域名与有效期">5.2 下载鉴权、域名与有效期</a>
      <a class="toc-link lv3" href="#s-5-3-另一入口-bearer-content">5.3 另一入口：Bearer content</a>
      <a class="toc-link lv3" href="#s-5-4-head-range-与断点续传">5.4 HEAD、Range 与断点续传</a>
      <a class="toc-link lv3" href="#s-5-5-错误排查">5.5 错误排查</a>
      <a class="toc-link lv2" href="#s-6-查询账号">6. 查询账号</a>
      <a class="toc-link lv2" href="#s-7-错误格式">7. 错误格式</a>
      <a class="toc-link lv2" href="#s-8-扣费和退款">8. 扣费和退款</a>
      <a class="toc-link lv2" href="#s-9-客户端建议">9. 客户端建议</a>
      <a class="toc-link lv2" href="#s-10-new-api-第三方网关对接">10. New API / 第三方网关对接</a>
  </aside>
  <main id="doc-main">
<h1 id="s-koko-视频生成-api">KOKO 视频生成 API</h1>
<blockquote>最后更新：2026-10-28。模型启停状态、账号实时积分价格和参考素材限制以 <code>GET /models</code> 返回为准。公开 API 只允许调用模型列表中当前启用并开放 OpenAPI 的模型；已删除/停用/退役的模型不能再调用（返回 <code>MODEL_NOT_SUPPORTED</code>）。</blockquote>
<blockquote>站点已上架（OpenAPI 暂未开放）：<code>gyk-sd25-903</code>（UUseedance2.5 903 满血稳定版 720P）已出现在主站/代理站，主站 50 积分、代理拿货 42 积分、代理站默认零售 50 积分；OpenAPI 暂不返回，30 秒上游稳定性仍在观察。</blockquote>
<p>Base URL：</p>
<div class="code-wrap"><div class="code-lang">text</div><pre><code>https://pay.kokoai.online/openapi/v1</code></pre></div>
<p>当前公开 API 提供以下模型（价格以 <code>GET /models</code> 实时返回为准）：</p>
<ul>
<li><code>mm-h3-768-stable</code>（minimaxh3 稳定版 参数903）：15 / 30 秒 · 768p · 比例 16:9 / 9:16 / 1:1 · 最多 9 张参考图 + 3 个参考音频 · 20 / 40 积分/条</li>
<li><code>oo-sd25-1080p</code>（OOseedance2.5 1080p超分 903参数）：固定 30 秒 · 1080p · 比例 16:9 / 9:16 / 1:1 / 3:4 · 最多 9 张参考图 + 3 个参考音频 · 40 积分/条</li>
<li><code>pp-sd25-stable</code>（PPseedance2.5 稳定满血版）：固定 30 秒 · 720p / 1080p 可选 · 比例 16:9 / 9:16 / 1:1 / 3:4 · 最多 10 张参考图（不支持参考音频/参考视频）· 提示词不限长度 · 65 积分/条</li>
<li><code>minimax-h3-933</code>（minimax-h3 1k 933）：固定 15 秒 · 1K · 最多 9 张参考图 · 20 积分/条</li>
<li><code>dp-sd20</code>（seedance2.0 满血版）：5 / 15 秒 · 720p · 比例 16:9 / 9:16 / 1:1 · 最多 9 张参考图 · 25 积分/条</li>
</ul>
<p>图片生成、音频生成、文本生成及已下线模型不在本接口范围内。已从模型列表删除/停用/退役的模型不能再调用。</p><section class="sa-section" id="s-1-api-key"><h2>1. API Key</h2>
<p>客户登录 KOKO Studio 后，在账号 API Key 管理入口创建密钥。完整密钥只在创建成功时返回一次，后续只能查看前缀。</p>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>curl -X POST https://pay.kokoai.online/api/account/api-keys \
  -H "Content-Type: application/json" \
  -H "Cookie: koko_session=客户登录后的会话 Cookie" \
  -d '{"name":"我的 Seedance 服务"}'</code></pre></div>
<p>管理接口：</p>
<ul><li><code>GET /api/account/api-keys</code>：查看密钥列表和当前账号 API 价格。</li><li><code>POST /api/account/api-keys</code>：创建密钥。</li><li><code>DELETE /api/account/api-keys/{key_id}</code>：停用密钥。</li></ul>
<p>公开 API 请求头：</p>
<div class="code-wrap"><div class="code-lang">http</div><pre><code>Authorization: Bearer koko_live_xxxxxxxxx</code></pre></div>
<p>API Key 等同于账号访问凭证，只应保存在服务端环境变量中。</p>
</section><section class="sa-section" id="s-2-查看模型和价格"><h2>2. 查看模型和价格</h2>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>curl https://pay.kokoai.online/openapi/v1/models \
  -H "Authorization: Bearer koko_live_xxxxxxxxx"</code></pre></div>
<p>返回结构示例（完整字段及当前账号价格请实时查询）：</p>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{
  "models": [
    {
      "id": "mm-h3-768-stable",
      "name": "minimaxh3 稳定版 参数903",
      "type": "video",
      "durations": [15, 30],
      "duration_prices": {"15": 20, "30": 40},
      "reference_images": {"supported": true, "max": 9, "formats": ["jpeg", "png", "webp"]},
      "reference_audios": {"supported": true, "max": 3},
      "ratio": ["16:9", "9:16", "1:1"],
      "resolutions": ["768p"],
      "points": 40,
      "max_prompt_length": 12000,
      "enabled": true,
      "maintenance": false
    },
    {
      "id": "oo-sd25-1080p",
      "name": "OOseedance2.5 1080p超分 903参数",
      "type": "video",
      "durations": [30],
      "duration_prices": {"30": 40},
      "reference_images": {"supported": true, "max": 9, "formats": ["jpeg", "png", "webp"]},
      "reference_audios": {"supported": true, "max": 3},
      "ratio": ["16:9", "9:16", "1:1"],
      "resolutions": ["1080p"],
      "points": 40,
      "max_prompt_length": 8000,
      "enabled": true,
      "maintenance": false
    },
    {
      "id": "pp-sd25-stable",
      "name": "PPseedance2.5 稳定满血版",
      "type": "video",
      "durations": [30],
      "duration_prices": {"30": 65},
      "reference_images": {"supported": true, "max": 10, "formats": ["jpeg", "png", "webp"]},
      "reference_audios": {"supported": false, "max": 0},
      "ratio": ["16:9", "9:16", "1:1"],
      "resolutions": ["720p", "1080p"],
      "points": 65,
      "max_prompt_length": 0,
      "enabled": true,
      "maintenance": false
    },
    {
      "id": "minimax-h3-933",
      "name": "minimax-h3 1k 933",
      "type": "video",
      "durations": [15],
      "duration_prices": {"15": 20},
      "reference_images": {"supported": true, "max": 9, "formats": ["jpeg", "png", "webp"]},
      "ratio": ["16:9", "9:16", "1:1", "4:3", "3:4"],
      "resolutions": ["1K"],
      "points": 20,
      "max_prompt_length": 10000,
      "enabled": true,
      "maintenance": false
    },
    {
      "id": "dp-sd20",
      "name": "seedance2.0 满血版",
      "type": "video",
      "durations": [5, 15],
      "duration_prices": {"5": 25, "15": 25},
      "reference_images": {"supported": true, "max": 9, "formats": ["jpeg", "png", "webp"]},
      "ratio": ["16:9", "9:16", "1:1"],
      "resolutions": ["720p"],
      "points": 25,
      "max_prompt_length": 8000,
      "enabled": true,
      "maintenance": false
    }
  ]
}</code></pre></div>
<p><code>duration_prices</code>、<code>points</code> 的单位都是积分；<code>max_prompt_length: 0</code> 表示不限制提示词长度。实际价格和可用状态以当前账号 <code>GET /models</code> 的实时返回为准，不应硬编码示例价格。</p>
</section><section class="sa-section" id="s-3-创建视频任务"><h2>3. 创建视频任务</h2>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>curl -X POST https://pay.kokoai.online/openapi/v1/videos \
  -H "Authorization: Bearer koko_live_xxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: customer_order_20261028_001" \
  -d '{
    "model": "dp-sd20",
    "prompt": "一只小狗在草地上奔跑，镜头缓慢推进，阳光自然，画面稳定",
    "duration": 5,
    "ratio": "9:16",
    "resolution": "720p",
    "count": 1
  }'</code></pre></div>
<p>PP2.5 示例（固定 30 秒，720p/1080p 可选）：</p>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>curl -X POST https://pay.kokoai.online/openapi/v1/videos \
  -H "Authorization: Bearer koko_live_xxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pp_order_20261028_001" \
  -d '{
    "model": "pp-sd25-stable",
    "prompt": "雨后的城市街道倒映霓虹，一辆复古汽车缓慢驶过，镜头平稳跟拍",
    "duration": 30,
    "ratio": "9:16",
    "resolution": "1080p",
    "image_urls": ["https://your-cdn.example.com/reference.png"]
  }'</code></pre></div>
<p>参考音频示例（minimaxh3 稳定版，最多 9 图 + 3 音频）：</p>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>curl -X POST https://pay.kokoai.online/openapi/v1/videos \
  -H "Authorization: Bearer koko_live_xxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: mm_audio_20261028_001" \
  -d '{
    "model": "mm-h3-768-stable",
    "prompt": "根据参考图和参考音频生成自然连贯的视频，人物口型与音频同步",
    "duration": 15,
    "ratio": "16:9",
    "resolution": "768p",
    "image_urls": ["https://your-cdn.example.com/reference.png"],
    "audio_urls": ["https://your-cdn.example.com/reference.mp3"]
  }'</code></pre></div>
<p>也可以分别使用 <code>audio_urls</code> / <code>reference_audios</code>；参考音频最多 3 个。当前模型不支持参考视频，参考素材数量以 <code>GET /models</code> 返回的能力为准。</p>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{
  "id": "upstream_task_id",
  "status": "running",
  "model": "dp-sd20",
  "prompt": "一只小狗在草地上奔跑，镜头缓慢推进，阳光自然，画面稳定",
  "prompt_complete": true,
  "points": 25,
  "balance": 185,
  "video_url": null,
  "failure_reason": null,
  "created_at": "2026-09-17T12:00:00.000Z",
  "updated_at": "2026-09-17T12:00:00.000Z"
}</code></pre></div>
<h3 id="s-参数规则">参数规则</h3>
<div class="tbl-wrap"><table><thead><tr><th>模型</th><th>时长（秒）</th><th>分辨率</th><th>比例</th><th>参考图</th><th>参考音频</th><th>积分/条</th></tr></thead><tbody>
<tr><td><code>mm-h3-768-stable</code></td><td>15 / 30</td><td>768p</td><td>16:9 / 9:16 / 1:1</td><td>最多 9 张</td><td>最多 3 个</td><td>20 / 40</td></tr>
<tr><td><code>oo-sd25-1080p</code></td><td>30</td><td>1080p</td><td>16:9 / 9:16 / 1:1 / 3:4</td><td>最多 9 张</td><td>最多 3 个</td><td>40</td></tr>
<tr><td><code>pp-sd25-stable</code></td><td>30</td><td>720p / 1080p</td><td>16:9 / 9:16 / 1:1 / 3:4</td><td>最多 10 张</td><td>不支持</td><td>65</td></tr>
<tr><td><code>minimax-h3-933</code></td><td>15</td><td>1K</td><td>16:9 / 9:16 / 1:1 / 4:3 / 3:4</td><td>最多 9 张</td><td>不支持</td><td>20</td></tr>
<tr><td><code>dp-sd20</code></td><td>5 / 15</td><td>720p</td><td>16:9 / 9:16 / 1:1</td><td>最多 9 张</td><td>不支持</td><td>25</td></tr>
</tbody></table></div>
<p><code>prompt</code> 必填。提示词上限：<code>pp-sd25-stable</code> 不限制（0），<code>oo-sd25-1080p</code> 8000，<code>mm-h3-768-stable</code> 12000，<code>minimax-h3-933</code> 10000，<code>dp-sd20</code> 8000；超过上限会在扣费前返回 400。</p>
<h3 id="s-幂等键和请求编号">幂等键和请求编号</h3>
<ul><li><code>Idempotency-Key</code> 长度为 8-100，只允许字母、数字、下划线和横线。</li><li>无法设置请求头时，可在 JSON 中传同规格的 <code>request_id</code>。</li><li>两者都未提供时平台会自动生成任务编号，但客户端无法用自己的订单号安全重试。</li><li>可选请求头 <code>X-Request-Id</code> 使用相同格式，响应会在 <code>X-Request-Id</code> 和错误体中回传。</li></ul>
<h3 id="s-参考图">参考图</h3>
<p>参考图上限：<code>pp-sd25-stable</code> 10 张，<code>mm-h3-768-stable</code>/<code>oo-sd25-1080p</code>/<code>minimax-h3-933</code>/<code>dp-sd20</code> 各 9 张。三种字段只能选一种：</p>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{"reference_images":[{"url":"https://example.com/a.jpg"}]}</code></pre></div>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{"image_urls":["https://example.com/a.jpg"]}</code></pre></div>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{"images":["https://example.com/a.jpg"]}</code></pre></div>
<p>对象写法也兼容 <code>image_url</code>。提示词里用 <code>@图片1</code>、<code>@图片2</code> 指代第 1/2 张参考图。Seedance 2.0/2.5 的人物参考必须这样绑定；只写“图片1=…”可能被模型当成普通文字，人物会变成随机脸。平台提交前会自动把“图片N / 图N / 参考图N”规范为 <code>@图片N</code>；超出本次实际上传数量的编号会按纯文本处理，不会因此报“缺少参考图”。</p>
<p><strong>图片有两种给法，任选其一，也可以混用：</strong></p>
<ol><li><strong>公网 HTTPS 链接</strong>（上面的写法）—— 需上游能直接访问到。</li><li><strong>直接传图片内容（base64）</strong> —— 本地软件不必先上传到公网：</li></ol>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{"image_urls":["data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..."]}</code></pre></div>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{"image_urls":[{"base64":"iVBORw0KGgoAAAANSUhEUg...","mime":"image/png"}]}</code></pre></div>
<p>图片限 JPG、PNG、WebP，单张不超过 50 MB；参考音频支持 MP3/WAV/M4A/AAC/FLAC（单个不超过 50 MB）；当前模型不支持参考视频。平台会把外部素材镜像/落盘成公网链接再提交，外部图片地址应保持可访问。任一图片下载或上传失败会终止提交并自动退回积分（<code>400 INVALID_REFERENCE_MEDIA</code>）。</p>
<h3 id="s-minimax-h3-参考音频">参考音频说明</h3>
<ul><li>当前支持的参考音频模型：<code>mm-h3-768-stable</code> 最多 3 个，<code>oo-sd25-1080p</code> 最多 3 个；其它模型不支持参考音频或参考视频。</li><li>音频可以用公网 HTTPS URL，也可以直接传 base64（MP3/WAV/M4A/AAC/FLAC，单个不超过 50 MB）。</li><li>平台会把参考素材统一落盘成公网链接再提交；外部图片地址应保持可访问。</li><li>参考图与参考音频合计数量以对应模型 <code>GET /models</code> 返回的能力为准。</li></ul>
</section><section class="sa-section" id="s-4-查询任务"><h2>4. 查询任务</h2>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>curl https://pay.kokoai.online/openapi/v1/videos/upstream_task_id \
  -H "Authorization: Bearer koko_live_xxxxxxxxx"</code></pre></div>
<p>状态：</p>
<ul><li><code>submitting</code>：已接收，正在处理参考素材或向上游提交，不代表生成排队。</li><li><code>queued</code>：兼容历史任务状态；上游自身的排队无法由本站取消。</li><li><code>running</code>：上游生成中。</li><li><code>completed</code>：生成完成，可以读取 <code>video_url</code>。</li><li><code>failed</code>：生成失败，积分已自动退回，原因在 <code>failure_reason</code>。</li></ul>
<p>上游明确返回余额不足、审核拒绝等错误时，任务结束并按失败规则退款，不会伪装成无限排队。网络超时等结果不确定的情况仍使用同一幂等键恢复，避免重复生成。</p>
<p>任务只能由创建它的账号查询。</p>
<p>创建任务、幂等重试及查询任务的成功响应均返回 <code>prompt</code> 和 <code>prompt_complete</code>。<code>prompt</code> 是本账号提交并被服务接受的完整提示词（沿用提交时去除首尾空白的规则，保留内部换行和中文），不追加上游内部指令。运行中、成功、失败任务查询均支持；已归档的历史提示词会从归档读取。若历史归档缺失、损坏或校验失败，返回 <code>prompt: null, prompt_complete: false</code>，不会将截断摘要冒充完整提示词。此变更不修改计费或生成参数。</p>
</section><section class="sa-section" id="s-5-提取视频地址与下载原文件"><h2>5. 提取视频地址与下载原文件</h2>
<blockquote>下载协议更新：2026-10-07（原文件下载改为直连上游 CDN）。适用于本平台公开视频 API，包括 Seedance 与 MiniMax H3；不是上游供应商的接口文档。</blockquote>
<h3 id="s-5-1-推荐方式-查询任务-提取-video_url-再下载">5.1 推荐方式：查询任务，提取 video_url，再下载</h3>
<ol><li>使用 API Key 查询 <code>GET /openapi/v1/videos/{task_id}</code>。</li><li>确认 <code>status</code> 为 <code>completed</code> 且 <code>video_url</code> 非空。</li><li>使用返回的完整 <code>video_url</code> 发起普通 GET，保存二进制响应。</li></ol>
<p>以下是 Bash 示例，需安装 <code>curl</code> 和 <code>jq</code>；<code>KOKO_API_KEY</code> 请通过服务端环境变量配置。示例不会创建新任务或产生生成费用。</p>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>BASE="https://pay.kokoai.online/openapi/v1"
TASK_ID="替换为已有任务ID"
: "${KOKO_API_KEY:?请先配置 KOKO_API_KEY}"

task_json="$(curl --fail --silent --show-error \
  --connect-timeout 15 --max-time 60 \
  -H "Authorization: Bearer ${KOKO_API_KEY}" \
  "${BASE}/videos/${TASK_ID}")" || exit 1

VIDEO_URL="$(printf '%s' "$task_json" | jq -er \
  'select(.status == "completed") | .video_url | select(type == "string" and length &gt; 0)')" \
  || { printf '任务未完成或尚未返回下载地址\n' &gt;&amp;2; exit 1; }

# 签名下载地址本身已经授权，不再发送 API Key、Cookie 或 Referer。
# 先写临时文件，仅在完整传输成功后改名，避免将中断文件当作成品。
curl --fail --location --show-error \
  --proto '=https' --proto-redir '=https' --max-redirs 5 \
  --connect-timeout 15 --max-time 600 \
  --output "koko-video.mp4.part" "$VIDEO_URL" \
  &amp;&amp; mv -- "koko-video.mp4.part" "koko-video.mp4"</code></pre></div>
<p>下载超时值是客户端示例配置，不是服务端速度或完成时间保证。<code>completed</code> 表示生成成功，不代表所有来源文件在任何网络下都能立即下载；下载失败请重新查询原任务，不要重新创建收费生成任务。</p>
<h3 id="s-5-2-下载鉴权-域名与有效期">5.2 下载鉴权、域名与有效期</h3>
<ul><li>查询任务：需要 <code>Authorization: Bearer &lt;你的 API Key&gt;</code>。</li><li><code>video_url</code>：带短期签名的下载地址，有效期为生成该地址后约1小时；无需额外 Authorization、Cookie 或 Referer。请像临时访问凭证一样保护它。</li><li>原样保留整个 URL，不能删除签名参数、替换域名、截断查询串或修改 <code>media_intent</code>。过期返回401时，用 API Key 重新查询任务取得新地址。</li><li><strong>原文件下载会先返回 307，<code>Location</code> 指向上游 CDN 直链</strong>（<code>*.dola.com</code>、<code>*.douyinvod.com</code>）；</li></ul>
<p>  浏览器与 HTTP 客户端直接连到该 CDN 取流，<strong>视频字节不经过本平台服务器</strong>。调用方不需要调用上游   <code>signed_url</code>，也不需要自行添加 <code>passthrough=1</code>；对非该渠道的任务，平台内部仍按原方式中继，调用方无感。</p>
<ul><li>⚠️ 上游直链<strong>时效很短（约 30 秒）</strong>：必须在拿到 <code>Location</code> 后<strong>立即</strong>发起请求，不要缓存、排队或稍后再下。</li></ul>
<p>  失效后请对同一 <code>/content</code> 重新请求，平台会重新签发一条。</p>
<ul><li>未带签名的 <code>/videos/{task_id}/content</code> 需要 API Key，正常先返回 <strong>307</strong>，<code>Location</code> 是短期签名地址（<strong>可能位于上游 CDN 域名</strong>）；这不是下载失败。HTTP 客户端应正确处理重定向。</li><li>⚠️ <strong>不要把 API Key、Cookie 或任何本平台凭证发往跳转目标域名</strong>，<strong>不要使用 <code>curl --location-trusted</code></strong>。</li></ul>
<p>  跳转目标确为第三方 CDN，携带凭证等于把你的 API Key 泄露给该域名。正确做法：只跟随跳转、不带 Authorization。   需要浏览器播放时，可以使用签名地址作为媒体源，但跨域 JavaScript 读取还取决于该响应的 CORS；下载附件与网页预览并非同一接口契约。</p>
<ul><li>下载目标是原始视频文件，不保证统一转码为 H.264；网页预览可能采用不同版本。不要用网页预览文件大小或哈希校验原文件。</li></ul>
<h3 id="s-5-3-另一入口-bearer-content">5.3 另一入口：Bearer content</h3>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code># GET：自动跟随307取得签名地址并下载原文件
curl --fail --location --show-error \
  --proto '=https' --proto-redir '=https' --max-redirs 5 \
  --connect-timeout 15 --max-time 600 \
  -H "Authorization: Bearer ${KOKO_API_KEY}" \
  --output "koko-video.mp4.part" \
  "${BASE}/videos/${TASK_ID}/content" \
  &amp;&amp; mv -- "koko-video.mp4.part" "koko-video.mp4"</code></pre></div>
<p>也可以关闭客户端的自动跳转，读取307响应的 <code>Location</code>，再用<strong>不带 Authorization</strong>的新请求下载签名地址。不要把307响应体保存成MP4。</p>
<h3 id="s-5-4-head-range-与断点续传">5.4 HEAD、Range 与断点续传</h3>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code># 查看长度、类型、ETag等；HEAD没有视频响应体
curl --fail --head --location --show-error "$VIDEO_URL"

# 只取前1024字节，用于连通性探测，不是完整视频
curl --fail --location --show-error \
  -H "Range: bytes=0-1023" \
  --output "koko-video-prefix.bin" "$VIDEO_URL"</code></pre></div>
<ul><li>完整GET通常返回 <code>200</code>；单段Range被接受时返回 <code>206</code>，检查 <code>Content-Range</code> 和本段实际字节数。</li><li>示例 <code>bytes=0-1023</code> 正常应为1024字节。不能把它保存为“完整视频”后判定视频损坏。</li><li>无效或越界范围可能返回 <code>416</code>。若请求Range却返回200，应按完整文件处理，不能直接追加到旧文件。</li><li>断点续传应保存同一文件的强ETag或Last-Modified，配合 <code>If-Range</code>；仅在响应范围、校验标识一致时追加。标识不可用、已改变或服务端返回完整200时，重新完整下载，避免拼接不同文件版本。</li><li>完整传输结束后，若有 <code>Content-Length</code>，实际字节数必须一致；必要时用播放器或 <code>ffmpeg</code> 验证完整可解码。响应可能使用 <code>video/mp4</code>、<code>application/octet-stream</code> 或 <code>binary/octet-stream</code>，不能只依赖扩展名判断。</li></ul>
<h3 id="s-5-5-错误排查">5.5 错误排查</h3>
<div class="tbl-wrap"><table><thead><tr><th>现象/状态</th><th>处理</th></tr></thead><tbody><tr><td><code>307</code></td><td>读取Location继续请求，或开启自动跳转。</td></tr><tr><td><code>401</code></td><td>无签名入口检查API Key；签名地址检查过期/参数是否完整，重新查询任务。</td></tr><tr><td><code>404</code></td><td>检查任务ID以及是否属于当前API Key账号。来源文件不可用时也可能收到相应错误。</td></tr><tr><td><code>409 VIDEO_NOT_READY</code></td><td>任务尚未完成，继续查询原任务。</td></tr><tr><td><code>416</code></td><td>Range越界或格式不支持，先HEAD核对长度。</td></tr><tr><td><code>429</code></td><td>降低请求频率，按响应提示退避重试。</td></tr><tr><td><code>502 / 503 / 504</code>、连接超时</td><td>记录时间、任务ID和请求ID，重新查询并有限次数重试；不要重新提交生成或认为已自动退款。</td></tr><tr><td>返回JSON/HTML而非视频</td><td>读取错误内容，不要把错误响应保存成MP4。</td></tr><tr><td>下载中断/长度不足</td><td>保留为临时文件，核验同一版本后续传或重新下载，不要宣布成功。</td></tr></tbody></table></div>
<p>定位问题时提供：任务ID、发生时间及时区、客户端出口IP、HTTP状态码、响应的 <code>X-Request-Id</code>（如有），以及DNS/连接/首字节/总耗时。不要公开 API Key、Cookie、完整签名URL或客户提示词。</p>
</section><section class="sa-section" id="s-6-查询账号"><h2>6. 查询账号</h2>
<div class="code-wrap"><div class="code-lang">bash</div><pre><code>curl https://pay.kokoai.online/openapi/v1/account \
  -H "Authorization: Bearer koko_live_xxxxxxxxx"</code></pre></div>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{
  "user": {
    "id": "usr_xxx",
    "username": "customer",
    "balance": 185,
    "status": "active"
  },
  "balance": 185,
  "currency": "points"
}</code></pre></div>
</section><section class="sa-section" id="s-7-错误格式"><h2>7. 错误格式</h2>
<div class="code-wrap"><div class="code-lang">json</div><pre><code>{
  "error": {
    "code": "INSUFFICIENT_POINTS",
    "message": "积分不足，本次需要 20 积分",
    "request_id": "req_xxx"
  }
}</code></pre></div>
<div class="tbl-wrap"><table><thead><tr><th>HTTP</th><th>code</th><th>含义</th></tr></thead><tbody><tr><td>400</td><td><code>INVALID_JSON</code></td><td>请求体不是有效 JSON</td></tr><tr><td>400</td><td><code>MODEL_NOT_SUPPORTED</code></td><td>模型不受支持</td></tr><tr><td>400</td><td><code>INVALID_PROMPT</code></td><td>提示词为空或超过该模型 <code>max_prompt_length</code></td></tr><tr><td>400</td><td><code>INVALID_DURATION</code></td><td>时长不符合模型规格</td></tr><tr><td>400</td><td><code>INVALID_RATIO</code></td><td>比例不受支持</td></tr><tr><td>400</td><td><code>INVALID_RESOLUTION</code></td><td>清晰度不受支持</td></tr><tr><td>400</td><td><code>INVALID_MODE</code></td><td>mode 不受支持</td></tr><tr><td>400</td><td><code>INVALID_COUNT</code></td><td>count 不是 1</td></tr><tr><td>400</td><td><code>INVALID_IDEMPOTENCY_KEY</code></td><td>幂等键格式无效</td></tr><tr><td>400</td><td><code>INVALID_REFERENCE_MEDIA</code></td><td>参考素材字段、数量、URL 或 base64 不符合要求</td></tr><tr><td>400</td><td><code>REFERENCE_UPLOAD_FAILED</code></td><td>参考图处理失败，积分已退回</td></tr><tr><td>400</td><td><code>CHARGE_REJECTED</code></td><td>当前账号价格或扣费规则不允许提交</td></tr><tr><td>401</td><td><code>INVALID_API_KEY</code></td><td>API Key 无效或已停用</td></tr><tr><td>402</td><td><code>INSUFFICIENT_POINTS</code></td><td>积分不足</td></tr><tr><td>404</td><td><code>TASK_NOT_FOUND</code></td><td>任务不存在或不属于当前账号</td></tr><tr><td>404</td><td><code>NOT_FOUND</code></td><td>API 路径不存在</td></tr><tr><td>429</td><td><code>RATE_LIMITED</code></td><td>单个 API Key 超过每分钟 120 次请求</td></tr><tr><td>502</td><td><code>UPSTREAM_ERROR</code></td><td>上游提交、查询或视频处理失败，失败任务自动退款</td></tr><tr><td>503</td><td><code>MODEL_MAINTENANCE</code></td><td>模型维护中，未扣积分</td></tr><tr><td>504</td><td><code>UPSTREAM_TIMEOUT</code></td><td>上游提交超时，积分已退回</td></tr></tbody></table></div>
</section><section class="sa-section" id="s-8-扣费和退款"><h2>8. 扣费和退款</h2>
<ol><li>创建任务前检查积分。</li><li>每个幂等键最多成功扣费一次。</li><li>上游提交失败、参考图处理失败或任务最终失败时自动退款。</li><li>维护模型和参数校验失败不会扣积分。</li><li>只有任务成功完成才保留扣费。</li></ol>
</section><section class="sa-section" id="s-9-客户端建议"><h2>9. 客户端建议</h2>
<ul><li>创建任务后保存 <code>id</code>，每 5-10 秒查询一次状态。</li><li>网络超时后使用相同 <code>Idempotency-Key</code> 重试。</li><li>只在 <code>completed</code> 时下载 <code>video_url</code>。</li><li>不要保存或直连上游临时文件地址。</li><li>不要把平台 API Key 当作上游厂商密钥使用。</li></ul>
</section><section class="sa-section" id="s-10-new-api-第三方网关对接"><h2>10. New API / 第三方网关对接</h2>
<p>New API（new-api）在「渠道」里填写 KOKO 的 Base URL 时，不要带最后的 <code>/v1</code>（new-api 会自己追加）：</p>
<div class="code-wrap"><div class="code-lang">text</div><pre><code>Base URL: https://pay.kokoai.online/openapi</code></pre></div>
<p>new-api 实际请求的是：</p>
<div class="code-wrap"><div class="code-lang">text</div><pre><code>GET https://pay.kokoai.online/openapi/v1/models
Authorization: Bearer koko_live_xxxxxxxxx</code></pre></div>
<p>如果网关要求填写完整的 OpenAPI 根地址，也可以直接填 <code>https://pay.kokoai.online/openapi/v1</code>。 服务端同时兼容 <code>.../openapi/v1/v1/models</code> 和根路径 <code>.../v1/models</code>，上述两种 Base URL 都能获取模型列表。</p>
<p>使用 API CDN 时，把域名换成 <code>https://api.kokoaii.top/openapi</code>，路径规则相同。</p>
<p>返回的 <code>data[].id</code> 就是渠道里应填的模型名，例如 <code>mm-h3-768-stable</code>、<code>oo-sd25-1080p</code>、<code>pp-sd25-stable</code>、<code>minimax-h3-933</code>、<code>dp-sd20</code>。模型是否可用以当前 API Key 调用 <code>GET /models</code> 的实时返回为准。</p>
</section>
  <section class="sa-section" id="s-download-ttl"><h2>下载有效期</h2><p>成片下载地址有有效期，请尽快保存；具体时长以 <code>GET /models</code> 返回的 <code>downloadTtlHours</code> 为准。</p><p>过期后再请求 <code>/content</code> 会返回错误；请重新查询原任务或联系平台，不要为此重新创建收费生成任务。</p></section></main>
</div>
<footer>以 <code>GET /models</code> 返回为准 · 本文档随线上接口更新</footer>
