文档从 Key 到第一条视频
完成第一次生成需要的一切:一个 Key、一次请求、查任务、收回调。
开发者 API 需申请开通。
概览
基于 HTTPS 的 REST 接口,请求和返回都是 JSON。所有生成都是异步的。
- 接口地址
https://api.pershot.app/v1- 认证
- Authorization: Bearer 加上你的 Key。Key 以 sk_test_ 或 sk_live_ 开头,完整内容只显示一次,我们只保存哈希。
- Key 权限
- 每个 Key 都有权限范围,还可以在创作台设一份可用清单,只放行其中的型号和工具。工具也算在内:图片放大、去背景、视频增强、对口型、扩图和 AI 改图都要在清单里才能用,其他的返回 403 forbidden_model。生成 1080p 或 4K 并增强,视频型号和视频增强都要在清单里。
- 错误格式
{ "error": { "code", "message", "param", "request_id" } }- ID
- 按类型加前缀:job_、qt_、key_、up_。
- OpenAPI
- /api/v1/openapi.json
- 给 AI 智能体
- 给 AI 智能体读的纯文本:输入、可用取值、每种设置的价格和请求示例
seedance-2.0-fastseedance-2.0-miniqwen-image-2512-lightningqwen-image-2512qwen-image-edit-2511-lightningqwen-image-edit-2511
真实生成还没开放。在模型页留下邮箱,开放时我们写信通知你,只发一次。
快速开始
四步,每一步都附上你应该看到的返回。
- 01
获取 Key
开发者 API 需申请开通:在创作台的 API Key 页面申请。开通后在那里新建 Key 并马上复制,完整的 Key 只显示一次。
export API_KEY="sk_test_…" - 02
发送请求
提交镜头时带上 Idempotency-Key 和 max_credits 上限。立即返回 202 和排队中的任务,积分同时冻结。
curl https://api.pershot.app/v1/videos/generations \ -H "Authorization: Bearer $API_KEY" \ -H "Idempotency-Key: $(uuidgen)" \ -H "Content-Type: application/json" \ -d '{ "model": "seedance-2.0-fast", "prompt": "Perfume mist in hard side light. Slow push-in, black background, grain.", "duration": 5, "resolution": "720p", "aspect_ratio": "16:9", "generate_audio": true, "max_credits": 34 }'{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "video", "status": "queued", "money_status": "reserved", "queue_position": 2, "requested_model": "seedance-2.0-fast", "credits_quoted": 34, "credits_charged": null } - 03
查询任务
轮询任务直到状态变为 succeeded。输出链接是带签名的,会过期,需要的文件请及时下载。
curl https://api.pershot.app/v1/jobs/job_01J9ZK4T8W \ -H "Authorization: Bearer $API_KEY"{ "id": "job_01J9ZK4T8W", "object": "job", "kind": "video", "status": "succeeded", "money_status": "settled", "requested_model": "seedance-2.0-fast", "resolved_model": "seedance-2.0-fast", "credits_quoted": 34, "credits_charged": 34, "outputs": [ { "kind": "video", "url": "https://…/job_01J9ZK4T8W.mp4?sig=…", "width": 1280, "height": 720, "duration_s": 5 } ], "error": null } - 04
接收回调
传入 webhook_url,每次状态变化我们都会 POST 过去,带时间戳签名。请返回 2xx;投递失败会按退避策略重试。
{ "id": "evt_01J9ZKB1QX", "type": "job.succeeded", "created_at": "2026-09-29T14:02:31Z", "data": { "job": { "id": "job_01J9ZK4T8W", "object": "job", "status": "succeeded", "money_status": "settled", "credits_charged": 34, "outputs": [ { "kind": "video", "url": "https://…/job_01J9ZK4T8W.mp4?sig=…", "width": 1280, "height": 720, "duration_s": 5 } ] } } }
接口
路径都相对于接口地址。
| 方法 | 路径 | 作用 |
|---|---|---|
| GET | /v1/models | 当前账户可用的型号、能力和状态 |
| GET | /v1/pricing | 公开价;登录后返回账户实际价 |
| POST | /v1/quotes | 执行计划、分项费用、最高扣费和有效期(10 分钟) |
| POST | /v1/videos/generations | 生成视频;返回 202 和任务 |
| POST | /v1/images/generations | 生成或编辑图片;返回 202 和任务 |
| GET | /v1/jobs/{id} | 状态、签名下载链接、实际费用 |
| GET | /v1/jobs | 你的任务列表,最新的在前 |
| POST | /v1/jobs/{id}/cancel | 请求取消;模型还没受理时,冻结的积分退回 |
| GET | /v1/balance | 可用和冻结的积分,按类别列出 |
| GET | /v1/usage | 按日期或型号的用量,JSON 或 CSV |
| POST | /v1/uploads | 上传不超过 10 MB 的 JPEG、PNG 或 WebP |
报价与上限
每次生成都要带 quote_id 或 max_credits 上限,二选一。带 quote_id 时按该报价执行;带 max_credits 时,只有价格不超过上限才执行。
model 为 "auto" 时必须带 max_credits。报价 10 分钟内有效,过期返回 quote_expired。
幂等
每个生成请求都要带 Idempotency-Key 请求头(1 到 255 个可见 ASCII 字符)。
24 小时内使用同一个键,返回同一个任务(HTTP 200 而不是 202),超时后重试不会创建或扣费第二个任务。
回调
在生成请求(或批量请求)里传入 webhook_url,即可接收状态变化。每个事件都是一个 POST,JSON 内容包含 id、type、created_at 和 data:任务事件是 data.job,batch.completed 是 data.batch。
事件
job.queuedjob.processingjob.succeededjob.failedjob.cancelledbatch.completed
- 每次投递都带事件 ID、时间戳和签名,请先验签再处理内容。
- 你的地址在 10 秒内返回 2xx 才算送达。否则会在 1 分钟、5 分钟、30 分钟、2 小时、6 小时后重试,之后标为失败;客服可以重放。不跟随重定向。
- 回调地址必须是 https。指向内网、本机或保留地址的主机会被拒绝,提交时和我们连接时都会检查。
请求头
X-Signaturet=<unix>,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>X-Event-Id- 事件 ID,和内容里的 id 相同。重试和重放都沿用同一个 ID,请记录下来,已处理过的 ID 直接跳过。
- 签名密钥
- 每个账户一个 whsec_… 密钥,在创作台的 API Key 页面查看。HMAC 的密钥就是整个字符串,包括前缀。
- 轮换
- 轮换之后的 24 小时内,旧密钥会作为第二个 v1 继续签名。只要任意一个 v1 匹配,就可以接受这次投递。
请用收到的原始内容计算 HMAC,不要用重新序列化后的 JSON;用常量时间比较;拒绝时间戳超过 5 分钟的请求。
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received, before any JSON parsing.
export function verifyWebhook(header, rawBody, secret, toleranceSec = 300) {
let t = null;
const signatures = [];
for (const item of (header ?? "").split(",")) {
const [key, value] = item.split("=", 2);
if (key === "t") t = Number(value);
if (key === "v1") signatures.push(Buffer.from(value, "hex"));
}
if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
return signatures.some((s) => s.length === expected.length && timingSafeEqual(s, expected));
}
// verifyWebhook(req.headers["x-signature"], rawBody, process.env.WEBHOOK_SECRET)
// Answer 2xx quickly, and skip an X-Event-Id you have already handled.错误码
错误码和 HTTP 状态是固定的,message 供人阅读。
| 错误码 | HTTP | 何时出现 |
|---|---|---|
invalid_request | 400 | 字段缺失或超出范围 |
unauthorized | 401 | 没有 Key、Key 已撤销或签名错误 |
insufficient_credits | 402 | 余额不够冻结本次费用 |
forbidden_model | 403 | 这个 Key 的可用清单里没有该型号或工具 |
region_not_supported | 403 | 该型号在你所在的地区不提供 |
developer_api_closed | 403 | 开发者 API 未开通时使用开发者 Key;需申请开通 |
member_connections_paused | 403 | 连接自己的 AI 智能体暂停期间使用会员凭据(MCP、连接码或命令行) |
not_found | 404 | 你的账户里没有这个任务、报价或上传 |
quote_expired | 409 | 报价已超过 10 分钟 |
price_changed | 409 | 价格超出了你的上限 |
content_rejected | 422 | 内容被拒绝,不扣费 |
rate_limited | 429 | 这个 Key 的请求太频繁 |
concurrency_limited | 429 | 这个账户同时运行的任务太多 |
internal_error | 500 | 我们这边出了问题 |
upstream_unavailable | 503 | 模型暂时不可用,请稍后重试 |
模型的结果不确定时不返回错误:任务状态标为 unknown,先查询确认,不会重新提交。
限额
- 请求数
- 默认每个 Key 每分钟 60 次。
- 并发
- 每个账户默认同时跑 3 个任务,可申请提高。
- 上限
- 模型的总容量是硬上限,多开 Key 不会增加并发。
图片
POST /v1/images/generations 使用相同的请求头。按档位和操作选型号 ID;改图模型还要传 image_url,出图模型不接受它。
| 档位 | 出图 | 改图 |
|---|---|---|
| Image Mini经济 · 草稿 | qwen-image-2512-lightning | qwen-image-edit-2511-lightning |
| Image Fast推荐 | qwen-image-2512 | qwen-image-edit-2511 |
各型号参数限制
每个型号的 API 页都有完整的表:取值、单位、由谁检查、超出后会怎样。GET /v1/models 以 JSON 返回同样的限制。
- 平台校验我们检查,不符合就返回 400,不报价也不冻结积分。
- 供应商校验由供应商检查。被拒的任务会失败,不收费。
- 建议值没有人检查。控制在范围内,效果更好。
| 型号 | 主要限制 | 完整表格 |
|---|---|---|
seedance-2.0-fastSeedance 2.0 Fast | 提示词 2 至 2,000 个字符 · 4 至 15 秒 · 最多 9 张参考图 · 图片每边 300 至 6,000 像素 | 查看表格 |
seedance-2.0-miniSeedance 2.0 Mini | 提示词 2 至 2,000 个字符 · 4 至 15 秒 · 最多 9 张参考图 · 图片每边 300 至 6,000 像素 | 查看表格 |
qwen-image-2512Qwen-Image-2512 | 提示词 2 至 2,000 个字符 · 1K 或 2K · 不接受原图 | 查看表格 |
qwen-image-2512-lightningQwen-Image-2512 · Lightning 4-step | 提示词 2 至 2,000 个字符 · 1K 或 2K · 不接受原图 | 查看表格 |
qwen-image-edit-2511Qwen-Image-Edit-2511 | 提示词 2 至 2,000 个字符 · 1K 或 2K · 一张原图,JPEG、PNG 或 WebP,不超过 10 MB | 查看表格 |
qwen-image-edit-2511-lightningQwen-Image-Edit-2511 · Lightning | 提示词 2 至 2,000 个字符 · 1K 或 2K · 一张原图,JPEG、PNG 或 WebP,不超过 10 MB | 查看表格 |
上传
POST /v1/uploads 按文件内容判断类型。上传链接 7 天有效。
| 文件 | 格式 | 最大 | 最长 |
|---|---|---|---|
| 图片:首帧、参考图或改图原图 | JPEG, PNG, WebP | 10 MB | – |
| 视频:对口型 | MP4 | 50 MB | 60 秒 |
| 音频:对口型 | MP3, WAV, M4A | 10 MB | 60 秒 |
其他网站上的图片我们不会去下载。这类链接由供应商检查尺寸,被拒的任务不收费。 同样的限制也能以 JSON 读取:GET /v1/models 为每个型号返回 limits 对象。
从 fal、Replicate 或 WaveSpeed 迁移
只换接口地址和 Key 是不够的:每个请求还要把型号 ID 放进请求体,带上 Idempotency-Key 请求头和价格上限(max_credits 或 quote_id)。迁移指南逐个字段对照 Seedance 2.0 和 Qwen-Image,并列出不能直接沿用的部分。