视频生成
与 OpenAI Videos 接口兼容。不走对话协议——它是独立的视频端点, 按秒计费,没有流式返回。
官方语义是「提交拿任务,自己轮询」。本平台的上游轮询由网关内部做完,
POST 返回时任务已经是终态,status 直接是
completed。视频生成动辄数分钟,
请把客户端超时设成 0 或至少 30 分钟,否则会在出片前被自己的
SDK 掐断。轮询型 SDK 照样能用:它拿到的第一个响应就是终态,随后的
retrieve 会命中任务记录。
请求头
Bearer sk-routercode-…。此端点同样只读这一个鉴权头。
来源应用标识,会记入调用日志。不填时按 User-Agent 自动识别。
自定义业务标识,会写入调用日志,便于你按自己的业务维度对账。
指定走哪家厂商。不填由网关按全局优先级选路。
请求参数
application/json 与 multipart/form-data 两种请求体都认。
带参考图时用 multipart(input_reference 是文件字段),纯文生视频用 JSON。
支持视频生成的平台模型 ID。可在
定价接口里按 support_features
含 video 筛选。写一个不是视频模型的 ID 会直接返回
40401,不会掉进对话链路。
画面描述。
时长秒数,字符串,如 "8"。它同时是计费口径——
按声明秒数乘 video_price 计费,不按实际产出长度。
各家支持的档位不同,越界时由上游按自己的默认值处理。
分辨率,如 1280x720。网关会按目标厂商的形态换算成它认识的
ratio / resolution;换不出来就不下发,由上游用默认值。
图生视频的参考图(首帧)。multipart 里是文件字段;JSON 里可以给公网 URL 或
data: URL。推荐直接上传文件或用 data: URL——
模型生成的第三方临时链接上游经常拉不动。
不在上表的顶层字段原样透传给上游:
ratio、resolution、negative_prompt、
generate_audio、reference_images、image_tail
这类厂商专属旋钮由各家自己识别,网关不做删改,也不保证每家都支持。
响应
{
"id": "video_9f2c1ab84d7e4c1fa0b3d5e7",
"object": "video",
"model": "your-video-model",
"status": "completed",
"progress": 100,
"created_at": 1757462400,
"completed_at": 1757462712,
"expires_at": 1757548800,
"seconds": "8",
"size": "1280x720",
"url": "https://.../generated-video.mp4"
}
url 是平台加的字段
官方的 video 对象里没有地址,取片只能走 /content。
平台的成品本来就是可直接引用的地址,所以额外给出 url:
拿到就能用,省掉一次经网关的整片回源。不认识这个字段的 SDK 会忽略它,不影响兼容。
任务记录保留 24 小时(expires_at),过期后
retrieve 与 content 都返回 40402。
成品地址本身也可能更早失效。需要长期保存就立刻下载转存,
别把这个 URL 直接写进数据库当永久地址。
取片、查询与删除
| 接口 | 作用 | 返回 |
|---|---|---|
| GET /v1/videos/{id} | 查任务 | video 对象 |
| GET /v1/videos/{id}/content | 下载成品 | 视频字节流(video/mp4) |
| DELETE /v1/videos/{id} | 删任务记录 | {"deleted": true} |
- 任务只对创建它的那把 Key 可见。换一把 Key 查同一个 id 返回
40402,与不存在同样对待。 DELETE只删平台侧的任务记录。上游的成品不归平台管,删不掉也不会因此退费。- 未完成的任务取
/content返回409。
上游协议转换
你发出的永远是这一套请求体;各家上游的差异由网关抹平。
同一个 prompt + seconds + size + input_reference,网关会按目标模型
实际绑定的厂商协议,转成对方要的官方请求体、按对方的节奏轮询、
再把终态归一化成上面那个 video 对象。
| 上游协议 | 形态 | 成品 |
|---|---|---|
| openai_videos | POST /v1/videos → 轮询 → /content | 字节流,网关转存后交付 |
| xai_videos | 提交 + 5s 轮询 | 直链 |
| volc_videos / jimeng_videos | 提交 + 轮询(即梦为 AK/SK 签名) | 直链 |
| kling_videos | 按文生/图生/多图分端点提交 + 轮询 | 直链 |
| wan_videos / happyhorse_videos | DashScope 异步任务 | 直链(24h 过期) |
| minimax_videos | 提交 + 轮询,V1 还要换一次取件地址 | 直链 |
| zhipu_videos / luma_videos / runway_videos / vidu_videos | 提交 + 轮询 | 直链 |
目标厂商没有的能力,网关丢弃而不是硬塞——例如尾帧、参考视频、 参考音频在只认单张参考图的上游那里会被裁掉。硬塞未知字段只会换来一个 400,少一个能力但请求打得通更有价值。想确认某个模型支持到哪一步, 看模型列表里的能力位。
与 /v1/chat/completions 的关系
视频模型也可以继续用 Chat Completions 端点调用,
请求体里带 prompt 与时长即可,返回的是
{"status":"done","video":{"url":…}}。
两条路走的是同一条上游链路、同一套计费,区别只在客户端表面:
- 用标准 SDK 的选
/v1/videos。client.videos.create()直接能用。 - 已经接好 chat 端点的不必改。行为一字未变。
调用示例
# 视频要跑几分钟,关掉 curl 的超时
curl --max-time 0 https://www.apigoto.com/v1/videos \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $APIGOTO_API_KEY" \
-d '{
"model": "your-video-model",
"prompt": "一只橘猫跳上窗台,阳光穿过纱帘",
"seconds": "8",
"size": "1280x720"
}'
# 不要手写 Content-Type,让 curl 自己带 boundary
curl --max-time 0 https://www.apigoto.com/v1/videos \
-H "Authorization: Bearer $APIGOTO_API_KEY" \
-F "model=your-video-model" \
-F "prompt=让这张照片里的猫动起来" \
-F "seconds=8" \
-F "input_reference=@cat.png"
import os
from openai import OpenAI
client = OpenAI(
base_url="https://www.apigoto.com/v1",
api_key=os.environ["APIGOTO_API_KEY"],
# 出片要几分钟,SDK 默认 10 分钟超时不一定够
timeout=1800,
)
video = client.videos.create(
model="your-video-model",
prompt="一只橘猫跳上窗台,阳光穿过纱帘",
seconds="8",
size="1280x720",
)
print(video.status, video.id)
# 成品地址在扩展字段 url 上;也可以走 content 取字节
content = client.videos.download_content(video.id)
content.write_to_file("out.mp4")
your-video-model 是占位符
请以 模型列表里的实际 model_id 为准。
写不存在的模型名会返回 50201 no available upstream for this model。
限流与计费
- 视频有独立的限流维度。策略里的「视频数量」与请求次数、Token、图片各自独立计窗, 锚点也是独立的——见 限流、配额与并发。
-
超限返回
42902。视频维度没有专属错误码, message 是rpm limit exceeded,别被误导。 -
按秒计价,不按 token。价格取
video_price乘seconds,倍率链与对话调用一致,见 计费、Credits与订阅。 - 计费按声明秒数,不按实际产出。调用日志里另记实际产出时长,两者可能不同。
- 断线不退费。任务一提交上游就开始消耗,客户端中途断开时网关会继续把它跑完并如实记账。
可能的错误
| HTTP | code | 原因 |
|---|---|---|
| 400 | 40002 | 请求体里没有 model(JSON 与 multipart 都会查) |
| 400 | 40000 | 缺 prompt,或请求体不是合法 JSON |
| 400 | 40003 | 请求体为空或读取失败 |
| 401 | 40001 | 没有 Authorization: Bearer |
| 404 | 40401 | 这个模型不是视频模型,走错端点了 |
| 404 | 40402 | 任务不存在、已过期,或不属于当前 Key |
| 409 | 40000 | 任务还没完成就取 /content |
| 410 | 50210 | 成品在上游已经失效,取不回来了 |
| 413 | 41301 | 上传的参考图让请求体超过 100 MiB |
| 429 | 42902 | 视频数量限额用尽 |
| 429 | 42910 | 凭证的视频秒数窗口已用满 |
| 502 | 50201 | 模型名写错,或该模型没有可用上游 |
完整清单见 错误码总表。