# Create a video task `POST /v1/video/generations` Submit a prompt with optional images, videos or audio to create an asynchronous generation task; the task ID and the reserved amount come back at once. HTTP 202 means the task was accepted; then read its progress and result by task ID. Images and audio may also be sent inline as base64, and the create body is limited to 64 MiB. A body over 2 MiB has a 120-second read deadline, and each team can send at most two at a time; more returns 429 rate_limited. One image may omit role to act as first_frame; omitting role among several images, or conflicting roles, is refused. - Put your API key after `Authorization: Bearer` in the request header. - Send an `Idempotency-Key`: when the outcome is unknown, retry with the same key and body to create one task and be charged once. - Generation runs in the background: poll [Retrieve a video task](./api-docs-en-api-video-tasks-retrieve.md) or receive `task.completed` at your `callback_url`. - Funds are reserved for the upper bound at creation and settled on actual usage; failed and cancelled tasks are free. ## Headers | Field | Type | Requirement | Description | | --- | --- | --- | --- | | `Authorization` | string | Required | Bearer, a space and your API key. A missing or invalid key returns 401 authentication_failed. | | `Content-Type` | string | Required | The body is JSON: application/json. | | `X-Request-ID` | string | Optional | Your own request identifier. An invalid or repeated value is replaced; the value used comes back in the X-Request-ID response header. | | `Idempotency-Key` | string | Required | Generate a new value for every new request and save it; it starts with a letter or digit. When the outcome is unknown, retry with the same key and the original body to get the original response; the same key with a different body returns 409 idempotency_conflict. Keys belong to your team, not to one API key. Length: 8–128. Characters: A–Z a–z 0–9 . _ : -. | ## Request body · application/json · Required The body accepts only the fields below; any other field is rejected. | Field | Type | Requirement | Description | | --- | --- | --- | --- | | `model` | string | Required | ID of the model used for this request. `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 | Required | Platform limits: 9 images, 3 videos and 3 audio items, 15 materials and 16 content items. Each video or audio clip lasts 2 to 15 seconds; video and audio totals are each at most 15 seconds. The platform downloads, scans, stores and reviews HTTPS inputs before generation. Preparation failure releases the whole reservation at zero charge. Known preparation failures include their content_index. Items: 1–16. Each item matches exactly one of these shapes. | | `content[] (Text) type` | string | Required | Identifies the kind of input item. Always: text. | | `content[] (Text) text` | string | Required | Prompt describing the video to generate. Length: 1–10000. | | `content[] (Image) type` | string | Required | Identifies the kind of input item. Always: image_url. | | `content[] (Image) role` | string | Optional | How the asset is used in the input or result. `reference_image`: Reference image; `first_frame`: First frame; `last_frame`: Last frame; | | `content[] (Image) image_url` | object | Required | An HTTPS image source, an asset:// platform asset reference, or a JPEG/PNG/WebP base64 data URI. HTTPS and inline inputs may be combined; neither can be mixed with asset:// references. Exactly one of these shapes applies. | | `content[] (Image) image_url.url (HTTPS URL)` | string | Required | Public HTTPS URL with no userinfo, literal IP, local or platform hostname. Port must be omitted or 443; at most 2048 UTF-8 bytes. Length: 1–2048. Format: https://. | | `content[] (Image) image_url.url (Asset reference)` | string | Required | Use asset:// and the ID of an active asset owned by your team. Do not put its original HTTPS source address here. Length: 12–128. Format: asset://ast-…. | | `content[] (Image) image_url.url (Base64 image)` | string | Required | JPEG, PNG or WebP data URI with base64 encoding. The decoded image must be smaller than 30 MB and pass image header checks. Length: ≤ 40000023. Format: data:image/…;base64,…. | | `content[] (Video) type` | string | Required | Identifies the kind of input item. Always: video_url. | | `content[] (Video) role` | string | Required | How the asset is used in the input or result. Always: reference_video. | | `content[] (Video) video_url` | object | Required | An HTTPS video source or an asset:// platform video reference. Use one origin throughout the request. Exactly one of these shapes applies. | | `content[] (Video) video_url.url (HTTPS URL)` | string | Required | Public HTTPS URL with no userinfo, literal IP, local or platform hostname. Port must be omitted or 443; at most 2048 UTF-8 bytes. Length: 1–2048. Format: https://. | | `content[] (Video) video_url.url (Asset reference)` | string | Required | Use asset:// and the ID of an active asset owned by your team. Do not put its original HTTPS source address here. Length: 12–128. Format: asset://ast-…. | | `content[] (Audio) type` | string | Required | Identifies the kind of input item. Always: audio_url. | | `content[] (Audio) role` | string | Required | How the asset is used in the input or result. Always: reference_audio. | | `content[] (Audio) audio_url` | object | Required | An HTTPS audio source, an asset:// platform audio reference, or a WAV/MP3 base64 data URI (wav, x-wav, mpeg and mp3 aliases). HTTPS and inline inputs may be combined; neither can be mixed with asset:// references. Exactly one of these shapes applies. | | `content[] (Audio) audio_url.url (HTTPS URL)` | string | Required | Public HTTPS URL with no userinfo, literal IP, local or platform hostname. Port must be omitted or 443; at most 2048 UTF-8 bytes. Length: 1–2048. Format: https://. | | `content[] (Audio) audio_url.url (Asset reference)` | string | Required | Use asset:// and the ID of an active asset owned by your team. Do not put its original HTTPS source address here. Length: 12–128. Format: asset://ast-…. | | `content[] (Audio) audio_url.url (Base64 audio)` | string | Required | WAV or MP3 data URI with base64 encoding, up to 15 MB and 2 to 15 seconds. The audio/x-wav and audio/mp3 aliases are accepted. Length: ≤ 20000024. Format: data:audio/…;base64,…. | | `resolution` | string | Optional | Output resolution. Seedance 2.0 Fast and Mini accept only 480p or 720p. Default: 720p. `480p`: 480-line resolution; `720p`: 720-line resolution; `1080p`: 1080-line resolution; | | `ratio` | string | Optional | Aspect ratio of the output image. Default: adaptive. `adaptive`: Auto aspect ratio; `21:9`: Ultrawide landscape; `16:9`: Widescreen landscape; `4:3`: Landscape; `1:1`: Square; `3:4`: Portrait; `9:16`: Tall portrait; | | `duration` | integer | Optional | Output duration in whole seconds from 4 to 15; the default is 5. Default: 5. Range: 4–15. | | `generate_audio` | boolean | Optional | Whether to generate audio with the video. Default: false. | | `seed` | integer | Optional | Random seed; the default -1 means random. Range: -1–4294967295. Default: -1. | | `watermark` | boolean | Optional | Whether to add a watermark to the output. Default: false. | | `callback_url` | string | Optional | The address that receives the callback when the task ends. It must match, byte for byte, a callback address of your team that is verified in the console, not removed and not expired; otherwise 400 callback_target_not_verified. A retry with the same Idempotency-Key cannot add, drop or change it; that returns 409 idempotency_conflict. Length: 1–2048. Format: https://. | Not supported yet: `return_last_frame`: Setting it to `true` returns 400 `unsupported_capability`. `draft`, `output_format`, `omni_reference_task_type`, `execution_expires_after`, `priority`, `safety_identifier`: The current models do not take these; sending one returns 400 `invalid_request`. ## Returns · HTTP 202 Accepted: the task is created and the funds are reserved. The Location response header is the task's lookup path. | Field | Type | Requirement | Description | | --- | --- | --- | --- | | `id` | string | Required | Task ID assigned by the platform. Length: 4–128. Characters: A–Z a–z 0–9 _ -. | | `object` | string | Required | Identifies the kind of object returned. Always: video.task. | | `request_id` | string | Required | Request ID used to correlate this task. Length: 4–128. Characters: A–Z a–z 0–9 _ -. | | `billing_correlation_id` | string | Required | Billing correlation ID for this task. Length: 4–128. Characters: A–Z a–z 0–9 _ -. | | `model` | string | Required | ID of the model used for this request. `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 | Required | Current state; see the value notes for its meaning. Always: queued. | | `phase` | string | Optional | The inputs are being prepared before generation starts. Always: preparing_assets. | | `settlement_status` | string | Required | Current progress of billing settlement. Always: reserved. | | `quote` | object | Required | Reservation quote recorded when the task is accepted. | | `quote.currency` | string | Required | Currency of the amounts: USD. Always: USD. | | `quote.reserved_amount` | string | Required | Amount that must be reserved to accept the task. Format: 6 decimal places. | | `quote.meter_type` | string | Required | The meter used to record usage. Always: seedance_video_generation. | | `quote.estimated_usage_upper_bound` | object | Required | Upper estimate of usage for the reservation. | | `quote.estimated_usage_upper_bound.video_tokens` | integer | Required | Number of video tokens. The field type determines whether an actual usage value may be null. Range: ≥ 1. | | `quote.price_version` | string | Required | Version of pricing applied to this quote. Length: 4–128. Characters: A–Z a–z 0–9 _ -. | | `quote.quote_policy_version` | string | Required | Version of the policy used to calculate the reservation quote. Length: 1–128. Characters: A–Z a–z 0–9 . _ : -. | | `created_at` | integer | Required | Creation time as whole seconds since the Unix epoch. Range: ≥ 0. | ### Response headers | Field | Type | Requirement | Description | | --- | --- | --- | --- | | `X-Request-ID` | string | Required | The identifier of this request: the valid value you sent, or its replacement. | | `Location` | string | Required | Canonical relative lookup path for the accepted object. | ## Status codes Each `error.code` and what to do about it is on [Error codes](./api-docs-en-api-errors.md). | Status | Meaning | error.code | | --- | --- | --- | | 202 | Accepted: the task is created and the funds are reserved. Response headers: `Location` | | | 400 | The format or parameters are wrong, or a referenced asset or callback address cannot be used. | asset_not_found, asset_unusable, callback_target_not_verified, input_video_duration_exceeded, invalid_request, unsupported_capability | | 401 | The API key is missing or invalid. Response headers: `WWW-Authenticate` | authentication_failed | | 409 | The idempotency key conflicts or its replay has expired, the API key is not ready, or an asset is still processing. | asset_not_ready, idempotency_conflict, idempotency_replay_expired, key_provisioning_incomplete | | 429 | The balance is too low, requests come too fast, or asset storage is full. Response headers: `Retry-After` | asset_storage_quota_exceeded, insufficient_balance, rate_limited | | 500 | Internal error. | internal_error | | 503 | The service is temporarily unavailable, or new tasks are paused. | dependency_unavailable, funding_intake_closed | ## Related guides - [Quickstart](./api-docs-en-quickstart.md) - [Generate a video](./api-docs-en-video-generate.md) - [Idempotency and retries](./api-docs-en-idempotency.md) - [Handle errors](./api-docs-en-errors.md) ## Request examples ```bash IDEMPOTENCY_KEY=${IDEMPOTENCY_KEY:-$(uuidgen)} printf '%s\n' "Save IDEMPOTENCY_KEY for retries: ${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("Save IDEMPOTENCY_KEY for retries: " + 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 // Needs Node.js 20 or later; save it as a .mjs file and run it. 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("Save IDEMPOTENCY_KEY for retries: " + 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, "Save IDEMPOTENCY_KEY for retries: "+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]) } ``` ## Response examples 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" } ```