POST
https://vidbudget.com/v1/videos/generations
异步视频生成 · 按秒计费 · 失败不扣费
快速开始:提交 → 查询 → 下载
这是异步视频接口。提交成功返回 HTTP 202 和任务 ID,视频生成及素材处理在后台完成;不要等待提交请求直接返回视频。
保存任务 ID,每 5–10 秒查询一次。请求中断后继续查询原任务;需要重发提交时使用同一个幂等键和完全相同的参数。
curl https://vidbudget.com/v1/videos/generations \
-H "Authorization: Bearer $VIDBUDGET_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: YOUR_UNIQUE_REQUEST_ID" \
-d '{
"model": "seedance-2.0",
"prompt": "湖面泛起微光,镜头缓缓向前推进",
"duration": 5,
"resolution": "720P",
"aspect_ratio": "16:9"
}'
curl https://vidbudget.com/v1/videos/jobs/TASK_ID -H "Authorization: Bearer $VIDBUDGET_API_KEY"
import os, time, uuid, requests
BASE = "https://vidbudget.com"
headers = {"Authorization": "Bearer " + os.environ["VIDBUDGET_API_KEY"]}
response = requests.post(BASE + "/v1/videos/generations", headers={**headers,
"Idempotency-Key": str(uuid.uuid4())}, json={'model': 'seedance-2.0', 'prompt': '湖面泛起微光,镜头缓缓向前推进', 'duration': 5, 'resolution': '720P', 'aspect_ratio': '16:9'}, timeout=85)
response.raise_for_status()
job = response.json()
print("保存任务 ID,断线后继续查询:", job["id"])
deadline = time.monotonic() + 7200
while job["status"] not in ("succeeded", "failed") and time.monotonic() < deadline:
time.sleep(5)
response = requests.get(BASE + "/v1/videos/jobs/" + job["id"], headers=headers, timeout=85)
response.raise_for_status()
job = response.json()
if job["status"] == "succeeded":
url = job["data"][0]["url"]
if not url.startswith("https://media.vidbudget.com/videos/"):
raise RuntimeError("Unexpected media URL")
with requests.get(url, stream=True, timeout=85) as media:
media.raise_for_status()
with open("video.mp4", "wb") as output:
for chunk in media.iter_content(1024 * 1024):
output.write(chunk)
elif job["status"] == "failed":
print("失败,预扣已退回:", job["error"])
else:
print("尚未完成,请继续查询原任务:", job["id"])
// Node.js 18+; save the task ID before polling.
const base = "https://vidbudget.com";
const headers = {Authorization: `Bearer ${process.env.VIDBUDGET_API_KEY}`};
async function request(path, options = {}) {
const response = await fetch(base + path, {...options, signal: AbortSignal.timeout(85000)});
const data = await response.json();
if (!response.ok) throw new Error(JSON.stringify(data.error));
return data;
}
let job = await request('/v1/videos/generations', {method: 'POST', headers: {...headers,
'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID()},
body: JSON.stringify({"model": "seedance-2.0", "prompt": "湖面泛起微光,镜头缓缓向前推进", "duration": 5, "resolution": "720P", "aspect_ratio": "16:9"})});
console.log('Task ID:', job.id);
const deadline = Date.now() + 7200000;
while (!['succeeded', 'failed'].includes(job.status) && Date.now() < deadline) {
await new Promise(resolve => setTimeout(resolve, 5000));
job = await request('/v1/videos/jobs/' + job.id, {headers});
}
console.log(job.status === 'succeeded' ? job.data[0].url : job);
认证与请求头
在控制台创建 API 密钥。密钥仅创建时显示一次,不放入浏览器公开代码、URL 或日志。
Authorization: Bearer YOUR_API_KEY Content-Type: application/json Idempotency-Key: YOUR_UNIQUE_REQUEST_ID
规格与适用范围
参考图片用来描述人物、场景、商品和风格,不是指定首帧或尾帧。请确保拥有输入素材及人物肖像的使用权。
模型规格和可接单的通道组合不同;无可用配置时返回 503,不能仅凭模型出现在列表中认定可以生成。
| 项目 | 支持范围 |
|---|---|
| 时长 | 5 / 6 / 7 / 8 / 9 / 10 / 11 / 12 / 13 / 14 / 15 秒 |
| 分辨率 | 720P |
| 画幅 | 16:9 / 9:16 / 1:1 / 4:3 / 3:4 |
| 参考图片 | 9 张以内 |
| 参考视频 | 3 段以内 |
| 参考音频 | 不支持 |
| 提示词 | 最多 5000 UTF-8 字节(汉字通常占 3 字节) |
| 计费 | 按生成秒数 |
| 视频保留 | 7 天,请及时下载 |
请求参数
Content-Type 为 application/json。不要把未支持的参数当作生效设置:当前不提供 callback_url、n 多条生成、指定首尾帧或流式输出。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| model | string | 是 | seedance-2.0 |
| prompt | string | 是 | 视频描述;素材按 @Image1 / @Video1 / @Audio1 引用,序号对应各数组顺序。 |
| duration | integer | 否 | 默认 5 秒;范围见规格。Clip 竖屏必须显式指定 15 秒。 |
| resolution | string | 否 | 默认 720P;可选 720P |
| aspect_ratio | string | 否 | 默认 16:9;别名 size、ratio;不能互相冲突。 |
| images | array<string> | 否 | HTTPS 图片 URL 数组;别名 reference_images、image_url、image,同一类型只传一个字段。 |
| video_references | array<string> | 否 | HTTPS 视频 URL 数组;本模型不支持时不要传。别名 video_reference、video_url。 |
| audio_references | array<string> | 否 | HTTPS 音频 URL 数组;本模型不支持时不要传。别名 audio_reference、audio_url。 |
| audio | boolean | 否 | 按条产品禁止传此参数;其他产品默认 true。false 不保证能关闭成片音轨,取决于模型本身。别名 generate_audio。 |
| seconds | integer | 否 | duration 的别名;同时传时必须相同。 |
| image_role | string | 否 | 只接受 reference / reference_images / ref;不支持首尾帧。 |
价格与扣费
下面读取当前价格配置,与实际扣费函数使用同一来源。提交预扣与任务入库在同一事务完成;成功结算,最终失败退回预扣金额。
| 分辨率 | 单价 USD | 示例费用 |
|---|---|---|
| 720P | 0.15 / 秒 | 5 秒:$0.75 |
参考素材与示例
先上传素材并查询上传任务,拿到 media.vidbudget.com 链接后填入相应数组;也可使用可公开下载的 HTTPS 素材 URL。不接受 base64 或 data: URI。
图片可用于角色与风格参考,视频可用于动作和运镜参考,音频可用于声音节奏参考。是否支持各类型及数量以本模型规格为准。
素材下载与验证在后台进行;无法读取、格式不合法或违反内容规则可能导致任务失败。失败时退回预扣余额。
真人照片可能受到生成服务的内容限制;不能保证每次接受或每次输出符合主观预期。
视频保留 7 天,请及时下载。上传素材也保留 7 天,不要把临时链接用作永久存储。
当前接入通道只接 720P。虽然模型基础规格含 480P/1080P,当前不能提交这两档。
{
"model": "seedance-2.0",
"prompt": "湖面泛起微光,镜头缓缓向前推进",
"duration": 5,
"resolution": "720P",
"aspect_ratio": "16:9",
"images": [
"https://media.vidbudget.com/inputs/YOUR_IMAGE_UUID.png"
]
}
响应结构
提交响应同样使用此结构,但 status 为 queued,completed_at 为 null、data 为空数组。error 在失败时是错误码字符串,成功或进行中为 null。
{
"id": "TASK_UUID",
"object": "task",
"kind": "video",
"model": "seedance-2.0",
"status": "succeeded",
"created_at": 1793354400,
"completed_at": 1793354700,
"elapsed_seconds": 300,
"retry_count": 0,
"error": null,
"data": [
{
"url": "https://media.vidbudget.com/videos/VIDEO_UUID.mp4"
}
]
}
任务状态与重试
retry_count 只记录额外提交次数,初次为 0,最多额外重试 2 次;查询次数不计入。completed_at 仅在最终成功或失败时写入,耗时包含排队、重试和媒体转存。
同通道自动重试仅针对可确认的可重试失败;提交结果未知时不会盲目重复购买。最终失败只退款一次,每笔余额变化有流水。
| 状态 | 含义 |
|---|---|
| queued | 已入库等待后台处理 |
| processing | 素材处理、生成、轮询或转存进行中 |
| succeeded | 已完成,读取 data[0].url |
| failed | 最终失败,读取 error;预扣自动退回 |
生成耗时与超时
视频生成可能需要数分钟或更久,时长、分辨率和排队都会影响完成时间。新站尚无真实生成耗时统计,不把原站实测值当作本服务承诺。
HTTP 请求时限为 85 秒,超时返回 JSON 504;生成总任务时限当前为 7200 秒。浏览器关闭不会取消后台任务。
503 表示当前没有匹配的已配置通道;先修复配置或等待服务可用,不要持续重复提交。
错误与处理方式
HTTP 错误结构为 {"error":{"code":"..."}},message 不保证存在。任务失败则通过任务对象的 error 字符串读取。
| HTTP / 任务 | 错误码 | 处理 |
|---|---|---|
| 400 | invalid_request | 检查参数、类型、素材字段和模型约束 |
| 401 | invalid_api_key / login_required | 检查密钥或登录状态 |
| 402 | insufficient_balance | 充值后再提交 |
| 404 | task_not_found | 确认任务属于当前用户,ID 正确 |
| 409 | conflict | 模型关闭或幂等键参数冲突 |
| 413 | payload_too_large | 大文件使用预签名直传 |
| 415 | unsupported_media_type | 仅上传图片/视频/音频 |
| 429 | upload_rate_limit | 等待窗口恢复 |
| 503 | channel_not_configured_or_unavailable | 没有可用通道,稍后重试 |
| 504 | request_timeout | 查询原任务,避免重复购买 |
| 任务 | media_processing_failed | 检查素材能否读取及实际文件格式 |
| 任务 | generation_timeout | 任务达到总时限,预扣退回 |
| 任务 | generation_failed 等安全错误码 | 检查内容与参数,再决定是否新建任务 |
素材上传与大文件直传
每 API key 每小时默认限制当前为 150 次。普通上传上限为 90000000 字节;超过此值使用预签名 PUT。直传上限 1000000000 字节,签名有效期 15 分钟。
支持图片、视频、音频 MIME,并在后台解码验证实际内容。推荐 PNG/JPEG/WebP,MP4,MP3/WAV/M4A。批量上传时每个文件单独请求,建议最多 6 路并发,保留添加顺序作为素材编号。
PUT 到 upload_url 时只带返回的上传 headers,不发送 VidBudget API key。上传完成后调用 complete,再查询任务取得最终素材 URL。
curl https://vidbudget.com/v1/uploads -H "Authorization: Bearer $VIDBUDGET_API_KEY" -F "[email protected]"
POST /v1/uploads/presign
{"content_type":"video/mp4","size":100000000}
PUT <upload_url> (原始文件字节,使用返回的 headers)
POST /v1/uploads/<upload_id>/complete
GET /v1/tasks/<task_id>
Webhook 与兼容性
当前 VidBudget 未实现生成结果 Webhook,不要传 callback_url 并期待通知。请使用 GET /v1/videos/jobs/{id} 或 GET /v1/tasks/{id} 轮询。
原版同步上传、其他支付方式、其他模型及旧站特有响应字段不适用于本接口。账户接口:GET /v1/balance、GET /v1/tasks、GET /v1/models。