POST
https://vidbudget.com/v1/videos/generations
异步视频生成 · 统一上传与任务接口 · 失败不扣费
在 Playground 试用 → 下载 OpenAPI 3.1
一套 API,接入全部创作流程
Base URL: https://vidbudget.com。REST / JSON,异步任务。供应商由服务端适配,应用只调用 VidBudget 模型 ID。
流程:上传本地素材 → 查询上传任务取得 URL → 提交生成 → 查询生成任务 → 下载结果。已有可公开下载的 HTTPS 素材可直接提交。
GET /v1/models 的 available、availability、capabilities 是当前可用规格;后台渠道变化无需修改你的上传或查询代码。
| 方法 | 路径 | 作用 |
|---|---|---|
| GET | /v1/models | 模型、价格、可用状态、素材上限 |
| GET | /v1/balance | 余额与积分 |
| POST | /v1/uploads | 上传一份图片、视频或音频 |
| POST | /v1/uploads/presign | 获取大文件直传签名 |
| POST | /v1/uploads/{id}/complete | 确认直传并创建处理任务 |
| POST | /v1/videos/generations | 创建视频生成任务 |
| GET | /v1/tasks/{id} | 查询上传或生成任务 |
| GET | /v1/tasks | 最近 100 个任务 |
| GET | /v1/videos/jobs/{id} | 生成任务查询兼容路径 |
认证、幂等与余额
在 /account/keys 创建自己的 VidBudget API Key。供应商密钥由平台管理,不需要提供给调用者。
认证:Authorization: Bearer YOUR_VIDBUDGET_API_KEY。JSON 请求使用 Content-Type: application/json;文件上传由客户端自动生成 multipart boundary。
每次新的生成使用唯一 Idempotency-Key。同一任务断网重发时,保持幂等键及请求参数完全相同;服务返回原任务,不重复扣费。不要在超时后换新键重购。
普通账户提交时预扣,成功结算,最终失败退回预扣。无可用通道不扣费;请先确认余额。
GET /v1/balance 返回 billing_mode:wallet 为普通余额计费,admin 为服务器确认的管理员调用。管理员通过创作台或本人 API Key 生成时不扣账户余额,上游费用仍由平台承担,每次调用记录审计。请求参数不能指定或覆盖计费身份。
模型和参数范围
图片、视频、音频数量分别计算。请从 capabilities 读取当前 durations、ratios、resolutions、images、videos、audios。
有参考视频时还可能受参考视频时长与输出时长合计限制,见 capabilities.video_and_output_seconds。
上传组件允许一次批量选择 30 张图片;单次生成可接受的数量取决于所选模型的当前规格。
| 模型 ID | 名称 | 可接单 | 参考图 / 视频 / 音频 |
|---|---|---|---|
| seedance-2.5 | Seedance 2.5 | 维护中 | 30 / 10 / 10 |
| seedance-2.5-30s | Seedance 2.5 Special | 是 | 30 / 10 / 10 |
| seedance-2.0 | Seedance 2.0 | 维护中 | 9 / 3 / 0 |
| seedance-2.0-fast | Seedance 2.0 Fast | 维护中 | 9 / 3 / 3 |
本地文件与批量上传
POST /v1/uploads,multipart/form-data,字段名 file。每个请求一个文件,普通上传最多 90000000 字节。支持 PNG/JPEG/WebP/GIF、MP4/WebM、MP3/WAV/M4A,服务端验证实际文件。
返回 HTTP 202 和上传任务 id;查询 GET /v1/tasks/{id},只有 succeeded 时才能取 data[0].url。不要把上传任务 ID 直接填入生成素材数组。
批量上传建议 6 路并发,按原文件顺序收集结果。每个 API Key 每小时当前上限 150 次。
超过普通上限时调用 presign(content_type 和 size),PUT 原始字节到 upload_url,最后调用 complete;最大 1000000000 字节,签名有效 15 分钟。签名 PUT 只带返回的 headers,不带 VidBudget Key。
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>
POST /v1/uploads/<upload_id>/complete
GET /v1/tasks/<returned_task_id>
全参数生成请求
提示词用 @Image1、@Video1、@Audio1 引用每种素材;编号对应各数组的添加顺序。服务端负责转换供应商要求的名称。
duration 为整数秒,resolution 如 720P,aspect_ratio 如 16:9。素材 URL 必须为 HTTPS,不能使用本地路径或 data: URI。
规范字段为 images、video_references、audio_references。也接受 videos / audios 别名,同一素材类型只传一个字段。
audio / generate_audio 是成片音轨开关,不是参考音频。按条特价模型不接受此开关;传音频素材请使用 audio_references。
{
"model": "seedance-2.5-30s",
"prompt": "以 @Image1 的主体为准,参考 @Video1 的镜头运动和 @Audio1 的节奏。",
"duration": 5,
"resolution": "720P",
"aspect_ratio": "16:9",
"images": ["https://media.vidbudget.com/inputs/IMAGE.png"],
"video_references": ["https://media.vidbudget.com/inputs/VIDEO.mp4"],
"audio_references": ["https://media.vidbudget.com/inputs/AUDIO.wav"]
}
Python · 上传、生成、查询、下载
安装 requests。将自己的密钥设为 VIDBUDGET_API_KEY,准备 references/ 中的图片、camera.mp4 和 rhythm.wav 后运行。示例会产生真实生成费用。
示例遇到 HTTP 错误会停止;保留已返回的任务 ID,网络恢复后查询原任务,不要把整个脚本当作自动重试。
import os, time, uuid, mimetypes
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
import requests
BASE = "https://vidbudget.com"
HEADERS = {"Authorization": "Bearer " + os.environ["VIDBUDGET_API_KEY"]}
def wait(job):
deadline = time.monotonic() + 7200
while job["status"] not in ("succeeded", "failed"):
if time.monotonic() > deadline:
raise TimeoutError("Continue querying the original task: " + job["id"])
time.sleep(3)
response = requests.get(BASE + "/v1/tasks/" + job["id"], headers=HEADERS, timeout=85)
response.raise_for_status()
job = response.json()
if job["status"] == "failed":
raise RuntimeError(job["error"])
return job["data"][0]["url"]
def upload(path):
path = Path(path)
mime = mimetypes.guess_type(path.name)[0] or "application/octet-stream"
if path.suffix.lower() == ".m4a": mime = "audio/mp4"
with path.open("rb") as file:
response = requests.post(BASE + "/v1/uploads", headers=HEADERS,
files={"file": (path.name, file, mime)}, timeout=85)
response.raise_for_status()
return wait(response.json())
# executor.map preserves the original file order. Up to 30 images for the full-parameter tier.
files = sorted(Path("references").glob("*.png"))
with ThreadPoolExecutor(max_workers=6) as pool:
images = list(pool.map(upload, files))
video = upload("camera.mp4")
audio = upload("rhythm.wav")
request_id = str(uuid.uuid4()) # Persist this ID and body before submitting.
body = {"model": "seedance-2.5-30s", "prompt": "参考 @Image1、@Video1 和 @Audio1 生成镜头",
"duration": 5, "resolution": "720P", "aspect_ratio": "16:9",
"images": images, "video_references": [video], "audio_references": [audio]}
response = requests.post(BASE + "/v1/videos/generations",
headers={**HEADERS, "Idempotency-Key": request_id}, json=body, timeout=85)
response.raise_for_status()
job = response.json()
print("Save task ID:", job["id"])
url = wait(job)
with requests.get(url, stream=True, timeout=85) as result:
result.raise_for_status()
with open("video.mp4", "wb") as file:
for chunk in result.iter_content(1024 * 1024): file.write(chunk)
任务状态和结果
所有任务共有 id、kind、model、status、created_at、completed_at、elapsed_seconds、retry_count、error、data。初始状态 queued,处理中 processing,完成 succeeded,最终失败 failed。
succeeded 才能读取 data[0].url;视频结果来自 media.vidbudget.com。elapsed_seconds 包含排队、素材处理、生成和结果转存。
浏览器关闭不取消后台任务;GET /v1/tasks 获取自己的任务记录。仅能读取当前用户的任务。素材和成片请及时下载,不作为永久存储。
当前使用轮询,不提供生成 Webhook 或流式视频接口。
错误与处理
HTTP 错误格式:{"error":{"code":"..."}}。最终任务失败时 error 为错误码字符串。
客户端每 3–5 秒查询即可。提交响应不确定时,复用原 Idempotency-Key 与完全相同的参数。
| HTTP | 含义 |
|---|---|
| 400/422 | 参数或类型不符合要求 |
| 401/403 | 密钥或登录校验失败 |
| 402 | 余额不足 |
| 404 | 任务不存在或不属于当前用户 |
| 409 | 模型关闭或幂等键参数冲突 |
| 413 | 文件过大,改用预签名直传 |
| 415 | 文件 MIME 不支持 |
| 429 | 上传额度达到每小时上限 |
| 503 | 当前参数没有可用渠道 |
| 504 | 请求超时,查询或复用原请求,避免重购 |