# 创建视频任务 `POST /v1/video/generations` 提交提示词和可选的图片、视频或音频,创建一个异步生成任务,立即返回任务 ID 和预留金额。HTTP 202 表示任务已受理,随后按任务 ID 查询进度和结果。图片和音频也可以用 base64 内嵌,创建请求体最大 64 MiB;大于 2 MiB 的请求体读取期限为 120 秒,每个团队同时最多处理 2 个,超出返回 429 rate_limited。只有一张图片时可以省略 role,按 first_frame 处理;多张图片省略 role 或角色冲突会被拒绝。 - 在请求头 `Authorization: Bearer` 后面放 API 密钥。 - 必须带 `Idempotency-Key`:结果不明时用同一个键原样重试,只会创建一个任务、扣一次费。 - 生成在后台进行:用「[查询视频任务](./api-docs-zh-api-video-tasks-retrieve.md)」轮询,或用 `callback_url` 接收 `task.completed`。 - 创建时按上限预留金额,完成后按实际用量结算;失败或取消的任务不收费。 ## 请求头 | 字段 | 类型 | 要求 | 说明 | | --- | --- | --- | --- | | `Authorization` | string | 必填 | Bearer 加一个空格和 API 密钥。缺失或无效时返回 401 authentication_failed。 | | `Content-Type` | string | 必填 | 请求体是 JSON:application/json。 | | `X-Request-ID` | string | 可选 | 你自己的请求标识。无效或重复的值会被替换,最终值在响应头 X-Request-ID 返回。 | | `Idempotency-Key` | string | 必填 | 每个新请求生成一个新值并保存,以字母或数字开头。结果不明时用同一个键和原请求体重试,会返回原响应;同一个键配不同的请求体返回 409 idempotency_conflict。键按团队区分,不按 API 密钥区分。 长度:8–128。 字符:A–Z a–z 0–9 . _ : -。 | ## 请求体 · application/json · 必填 请求体只接受下列字段,其他字段会被拒绝。 | 字段 | 类型 | 要求 | 说明 | | --- | --- | --- | --- | | `model` | string | 必填 | 本次使用的模型标识。 `dreamina-seedance-2-0-260128`:Seedance 2.0; `dreamina-seedance-2-0-fast-260128`:Seedance 2.0 Fast; `dreamina-seedance-2-0-mini-260615`:Seedance 2.0 Mini; | | `content` | array | 必填 | 平台限制:最多 9 张图片、3 段视频、3 段音频,共 15 份素材、16 项 content。视频和音频单段均为 2–15 秒,各自合计最多 15 秒。HTTPS 素材由平台下载、扫描、保存并审核后用于生成;准备失败全额释放预留费用,不收生成费。已知素材准备失败时同时返回 content_index。 数量:1–16。 每一项必须且只能符合下列一种结构。 | | `content[] (文本) type` | string | 必填 | 输入项类型。 固定为:text。 | | `content[] (文本) text` | string | 必填 | 生成提示文本。 长度:1–10000。 | | `content[] (图片) type` | string | 必填 | 输入项类型。 固定为:image_url。 | | `content[] (图片) role` | string | 可选 | 素材在输入或结果中的用途。 `reference_image`:参考图片; `first_frame`:首帧; `last_frame`:尾帧; | | `content[] (图片) image_url` | object | 必填 | HTTPS 图片链接、asset:// 平台素材引用,或 JPEG/PNG/WebP 的 base64 data URI。HTTPS 与 base64 可以组合,但不能与 asset:// 引用混用。 必须且只能符合下列一种结构。 | | `content[] (图片) image_url.url (HTTPS 链接)` | string | 必填 | 公网 HTTPS 链接,不含用户信息、字面 IP、本地主机或平台域名;端口省略或为 443,最多 2048 个 UTF-8 字节。 长度:1–2048。 格式:https://。 | | `content[] (图片) image_url.url (素材引用)` | string | 必填 | 使用 asset:// 加本团队已活跃素材的标识,不直接填写来源 HTTPS 地址。 长度:12–128。 格式:asset://ast-…。 | | `content[] (图片) image_url.url (base64 图片)` | string | 必填 | JPEG、PNG 或 WebP 的 base64 data URI。解码后须小于 30 MB,并通过图片头部检查。 长度:≤ 40000023。 格式:data:image/…;base64,…。 | | `content[] (视频) type` | string | 必填 | 输入项类型。 固定为:video_url。 | | `content[] (视频) role` | string | 必填 | 素材在输入或结果中的用途。 固定为:reference_video。 | | `content[] (视频) video_url` | object | 必填 | HTTPS 参考视频链接或 asset:// 平台视频引用;一次请求只能使用同一种来源。 必须且只能符合下列一种结构。 | | `content[] (视频) video_url.url (HTTPS 链接)` | string | 必填 | 公网 HTTPS 链接,不含用户信息、字面 IP、本地主机或平台域名;端口省略或为 443,最多 2048 个 UTF-8 字节。 长度:1–2048。 格式:https://。 | | `content[] (视频) video_url.url (素材引用)` | string | 必填 | 使用 asset:// 加本团队已活跃素材的标识,不直接填写来源 HTTPS 地址。 长度:12–128。 格式:asset://ast-…。 | | `content[] (音频) type` | string | 必填 | 输入项类型。 固定为:audio_url。 | | `content[] (音频) role` | string | 必填 | 素材在输入或结果中的用途。 固定为:reference_audio。 | | `content[] (音频) audio_url` | object | 必填 | HTTPS 参考音频链接、asset:// 平台音频引用,或 WAV/MP3 的 base64 data URI(含 wav、x-wav、mpeg、mp3 别名)。HTTPS 与 base64 可以组合,但不能与 asset:// 引用混用。 必须且只能符合下列一种结构。 | | `content[] (音频) audio_url.url (HTTPS 链接)` | string | 必填 | 公网 HTTPS 链接,不含用户信息、字面 IP、本地主机或平台域名;端口省略或为 443,最多 2048 个 UTF-8 字节。 长度:1–2048。 格式:https://。 | | `content[] (音频) audio_url.url (素材引用)` | string | 必填 | 使用 asset:// 加本团队已活跃素材的标识,不直接填写来源 HTTPS 地址。 长度:12–128。 格式:asset://ast-…。 | | `content[] (音频) audio_url.url (base64 音频)` | string | 必填 | WAV 或 MP3 的 base64 data URI,最大 15 MB、时长 2 至 15 秒;兼容 audio/x-wav 和 audio/mp3。 长度:≤ 20000024。 格式:data:audio/…;base64,…。 | | `resolution` | string | 可选 | 输出分辨率。Seedance 2.0 Fast 和 Mini 只接受 480p 或 720p。 默认:720p。 `480p`:四百八十线分辨率; `720p`:七百二十线分辨率; `1080p`:一千零八十线分辨率; | | `ratio` | string | 可选 | 画面宽高比。 默认:adaptive。 `adaptive`:自适应宽高比; `21:9`:超宽画面; `16:9`:横向宽屏; `4:3`:横向画面; `1:1`:正方形画面; `3:4`:竖向画面; `9:16`:竖向宽屏; | | `duration` | integer | 可选 | 输出时长,4–15 的整数秒,默认 5 秒。 默认:5。 范围:4–15。 | | `generate_audio` | boolean | 可选 | 是否生成音频。 默认:false。 | | `seed` | integer | 可选 | 随机种子,默认 -1,表示随机。 范围:-1–4294967295。 默认:-1。 | | `watermark` | boolean | 可选 | 是否添加水印。 默认:false。 | | `callback_url` | string | 可选 | 任务结束后接收回调的地址。必须与本团队在控制台已验证、未撤销、未过期的回调地址逐字节相同,否则返回 400 callback_target_not_verified。用同一个 Idempotency-Key 重试时不能增加、去掉或更换它,否则返回 409 idempotency_conflict。 长度:1–2048。 格式:https://。 | 暂不支持的参数:`return_last_frame`:设为 `true` 时返回 400 `unsupported_capability`。 `draft`, `output_format`, `omni_reference_task_type`, `execution_expires_after`, `priority`, `safety_identifier`:当前模型不接受,传入即返回 400 `invalid_request`。 ## 返回 · HTTP 202 已受理:任务已创建,金额已预留。响应头 Location 是任务的查询路径。 | 字段 | 类型 | 要求 | 说明 | | --- | --- | --- | --- | | `id` | string | 必填 | 平台任务标识。 长度:4–128。 字符:A–Z a–z 0–9 _ -。 | | `object` | string | 必填 | 对象类型标识。 固定为:video.task。 | | `request_id` | string | 必填 | 请求关联标识。 长度:4–128。 字符:A–Z a–z 0–9 _ -。 | | `billing_correlation_id` | string | 必填 | 费用关联标识。 长度:4–128。 字符:A–Z a–z 0–9 _ -。 | | `model` | string | 必填 | 本次使用的模型标识。 `dreamina-seedance-2-0-260128`:Seedance 2.0; `dreamina-seedance-2-0-fast-260128`:Seedance 2.0 Fast; `dreamina-seedance-2-0-mini-260615`:Seedance 2.0 Mini; | | `status` | string | 必填 | 当前状态,具体含义见对应取值。 固定为:queued。 | | `phase` | string | 可选 | 生成开始前正在准备输入素材。 固定为:preparing_assets。 | | `settlement_status` | string | 必填 | 当前费用结算状态。 固定为:reserved。 | | `quote` | object | 必填 | 接受任务时的预留报价。 | | `quote.currency` | string | 必填 | 金额币种,美元。 固定为:USD。 | | `quote.reserved_amount` | string | 必填 | 接受任务所需的预留金额。 格式:6 位小数。 | | `quote.meter_type` | string | 必填 | 用量计量类型。 固定为:seedance_video_generation。 | | `quote.estimated_usage_upper_bound` | object | 必填 | 预估用量上界。 | | `quote.estimated_usage_upper_bound.video_tokens` | integer | 必填 | 视频计量单位数;实际用量允许为空的情况以字段类型为准。 范围:≥ 1。 | | `quote.price_version` | string | 必填 | 本次报价的价格版本。 长度:4–128。 字符:A–Z a–z 0–9 _ -。 | | `quote.quote_policy_version` | string | 必填 | 预留报价策略版本。 长度:1–128。 字符:A–Z a–z 0–9 . _ : -。 | | `created_at` | integer | 必填 | 创建时间,Unix 整数秒。 范围:≥ 0。 | ### 响应头 | 字段 | 类型 | 要求 | 说明 | | --- | --- | --- | --- | | `X-Request-ID` | string | 必填 | 本次请求的标识:你提供的有效值,或替换后的值。 | | `Location` | string | 必填 | 已接受对象的规范查询路径。 | ## 状态码 每个 `error.code` 的处理办法见「[错误码](./api-docs-zh-api-errors.md)」。 | 状态码 | 说明 | error.code | | --- | --- | --- | | 202 | 已受理:任务已创建,金额已预留。 响应头:`Location` | | | 400 | 请求格式或参数不对,或引用的素材、回调地址不能用。 | asset_not_found, asset_unusable, callback_target_not_verified, input_video_duration_exceeded, invalid_request, unsupported_capability | | 401 | API 密钥缺失或无效。 响应头:`WWW-Authenticate` | authentication_failed | | 409 | 幂等键冲突或重放已过期,API 密钥未就绪,或素材还在处理。 | asset_not_ready, idempotency_conflict, idempotency_replay_expired, key_provisioning_incomplete | | 429 | 余额不足、请求太频繁,或素材存储已满。 响应头:`Retry-After` | asset_storage_quota_exceeded, insufficient_balance, rate_limited | | 500 | 服务内部错误。 | internal_error | | 503 | 服务暂时不可用,或暂停接收新任务。 | dependency_unavailable, funding_intake_closed | ## 相关指南 - [快速开始](./api-docs-zh-quickstart.md) - [生成视频](./api-docs-zh-video-generate.md) - [幂等与重试](./api-docs-zh-idempotency.md) - [处理错误](./api-docs-zh-errors.md) ## 请求示例 ```bash IDEMPOTENCY_KEY=${IDEMPOTENCY_KEY:-$(uuidgen)} printf '%s\n' "保存 IDEMPOTENCY_KEY,重试时原样复用:${IDEMPOTENCY_KEY}" >&2 curl --request POST "${CHENVOYA_BASE_URL}/v1/video/generations" \ --header "Authorization: Bearer ${CHENVOYA_API_KEY}" \ --header "Idempotency-Key: ${IDEMPOTENCY_KEY}" \ --header 'Content-Type: application/json' \ --data '{ "model": "dreamina-seedance-2-0-260128", "content": [ { "type": "text", "text": "A paper boat crossing a moonlit lake." } ] }' ``` ```python import urllib.request import urllib.parse import json import os import sys import re import uuid key = os.environ["CHENVOYA_API_KEY"].strip() if not key or re.search(r"[\x00-\x1f\x7f-\x9f]", key): sys.exit("Set CHENVOYA_API_KEY to a non-empty value without control characters") base = os.environ["CHENVOYA_BASE_URL"].rstrip("/") headers = {"Authorization": "Bearer " + key} idempotency = os.environ.get("IDEMPOTENCY_KEY") or str(uuid.uuid4()) print("保存 IDEMPOTENCY_KEY,重试时原样复用:" + idempotency, file=sys.stderr) headers["Idempotency-Key"] = idempotency path = "/v1/video/generations" body_text = "{\"model\":\"dreamina-seedance-2-0-260128\",\"content\":[{\"type\":\"text\",\"text\":\"A paper boat crossing a moonlit lake.\"}]}" headers["Content-Type"] = "application/json" body = json.dumps(json.loads(body_text)).encode("utf-8") request = urllib.request.Request(base + path, data=body, headers=headers, method="POST") try: with urllib.request.urlopen(request) as response: print(response.read().decode("utf-8")) except urllib.request.HTTPError as error: print(error.read().decode("utf-8")) sys.exit(1) ``` ```javascript // 需要 Node.js 20 及以上版本,保存为 .mjs 文件后运行。 const key = process.env.CHENVOYA_API_KEY?.trim(); if (!key || /[\x00-\x1f\x7f-\x9f]/.test(key)) { console.error("Set CHENVOYA_API_KEY to a non-empty value without control characters"); process.exit(1); } const base = process.env.CHENVOYA_BASE_URL; if (!base) throw new Error("Set CHENVOYA_BASE_URL"); const headers = {Authorization: `Bearer ${key}`}; const idempotency = process.env.IDEMPOTENCY_KEY || crypto.randomUUID(); console.error("保存 IDEMPOTENCY_KEY,重试时原样复用:" + idempotency); headers["Idempotency-Key"] = idempotency; const path = "/v1/video/generations"; let bodyText = "{\"model\":\"dreamina-seedance-2-0-260128\",\"content\":[{\"type\":\"text\",\"text\":\"A paper boat crossing a moonlit lake.\"}]}"; headers["Content-Type"] = "application/json"; const body = JSON.stringify(JSON.parse(bodyText)); const response = await fetch(base.replace(/\/$/, "") + path, {method: "POST", headers, body: body}); console.log(await response.text()); if (!response.ok) process.exitCode = 1; ``` ```go package main import ( "crypto/rand" "fmt" "io" "net/http" "os" "regexp" "strings" ) func main() { key := strings.TrimSpace(os.Getenv("CHENVOYA_API_KEY")) if key == "" || regexp.MustCompile(`[\x00-\x1f\x7f-\x9f]`).MatchString(key) { fail("Set CHENVOYA_API_KEY to a non-empty value without control characters") } base := strings.TrimRight(os.Getenv("CHENVOYA_BASE_URL"), "/") if base == "" { fail("Set CHENVOYA_BASE_URL") } path := "/v1/video/generations" bodyText := "{\"model\":\"dreamina-seedance-2-0-260128\",\"content\":[{\"type\":\"text\",\"text\":\"A paper boat crossing a moonlit lake.\"}]}" request, err := http.NewRequest("POST", base+path, strings.NewReader(bodyText)) if err != nil { fail(err.Error()) } request.Header.Set("Authorization", "Bearer "+key) request.Header.Set("Content-Type", "application/json") idempotency := os.Getenv("IDEMPOTENCY_KEY") if idempotency == "" { idempotency = newOperationKey() } fmt.Fprintln(os.Stderr, "保存 IDEMPOTENCY_KEY,重试时原样复用:"+idempotency) request.Header.Set("Idempotency-Key", idempotency) response, err := http.DefaultClient.Do(request) if err != nil { fail(err.Error()) } text, err := io.ReadAll(response.Body) response.Body.Close() if err != nil { fail(err.Error()) } fmt.Println(string(text)) if response.StatusCode < 200 || response.StatusCode > 299 { os.Exit(1) } } func fail(message string) { fmt.Fprintln(os.Stderr, message) os.Exit(1) } // newOperationKey returns a random UUID; save it to retry with the same value. func newOperationKey() string { var b [16]byte if _, err := rand.Read(b[:]); err != nil { fail(err.Error()) } b[6] = b[6]&0x0f | 0x40 b[8] = b[8]&0x3f | 0x80 return fmt.Sprintf("%x-%x-%x-%x-%x", b[0:4], b[4:6], b[6:8], b[8:10], b[10:16]) } ``` ## 响应示例 202 ```json { "id": "task_32ae2a5177b310d3bc1ec83a98f63889", "object": "video.task", "request_id": "req_6acd96894df9798feb0ddb21e5a52d70", "billing_correlation_id": "billcorr_2f6c57065a4404b27fb9b6b24ea9a0d0", "model": "dreamina-seedance-2-0-260128", "status": "queued", "settlement_status": "reserved", "quote": { "currency": "USD", "reserved_amount": "0.782453", "meter_type": "seedance_video_generation", "estimated_usage_upper_bound": { "video_tokens": 111779 }, "price_version": "price_06c9ad4cf0af577624218747c25fdb37", "quote_policy_version": "seedance2_quote_v1" }, "created_at": 1793167380 } ``` 400 ```json { "error": { "code": "invalid_request", "message": "request parameters are invalid" }, "trace_id": "trace_error_example" } ``` 401 ```json { "error": { "code": "authentication_failed", "message": "authentication failed" }, "trace_id": "trace_error_example" } ``` 409 ```json { "error": { "code": "idempotency_conflict", "message": "the idempotency key was used with a different canonical request" }, "trace_id": "trace_error_example" } ``` 429 ```json { "error": { "code": "insufficient_balance", "message": "available USD balance is below the required reservation", "details": { "currency": "USD", "reserved_amount": "0.782453", "meter_type": "seedance_video_generation", "estimated_usage_upper_bound": { "video_tokens": 111779 }, "price_version": "price_06c9ad4cf0af577624218747c25fdb37" } }, "trace_id": "trace_error_example" } ``` 500 ```json { "error": { "code": "internal_error", "message": "internal server error" }, "trace_id": "trace_error_example" } ``` 503 ```json { "error": { "code": "dependency_unavailable", "message": "service is not ready" }, "trace_id": "trace_error_example" } ```