OpenQiao Native API: Generate Videos
Troubleshooting
Encountering errors? See the API Error Codes Reference for a complete list of error types and troubleshooting solutions.
Submit a generation request:
POST https://openqiao.com/api/v1/videosPoll task status:
GET https://openqiao.com/api/v1/videos/{jobId}This endpoint generates videos using the native (original-vendor) protocol: the request body adopts the vendor's native content array structure directly — no SDK required, authenticated with a standard Authorization: Bearer header. If you'd rather call the same models through the Google Vertex AI protocol, see Generate Videos (Vertex AI Protocol).
Asynchronous calls
Video generation is an asynchronous process with three steps:
- Submit (
POST /api/v1/videos): returns the taskidand initialstatus. - Poll (
GET /api/v1/videos/{jobId}): check the status periodically, recommended every 15 seconds. - Retrieve result: when
statusissucceeded, read the video fromcontent.
Video generation usually takes 30 seconds to 3 minutes — be patient and don't poll too frequently.
Polling right after submit
You can poll immediately after submit — the task record is persisted synchronously, so GET /api/v1/videos/{jobId} returns queued (it will not 404 due to write lag). A 404 is only returned for an unknown or expired jobId.
Supported models
| Model | Resolution | Max duration | Audio |
|---|---|---|---|
bytedance/doubao-seedance-2.0 | 480p / 720p / 1080p | 10s | ✅ Supported |
More models
Visit the OpenQiao model list to search all available video generation models.
Authentication
Authorization string *
Request header in the form Bearer $OPENQIAO_API_KEY, using your OpenQiao API key for authentication.
Submit request body
model string *
The model slug used for generation, in the form {provider}/{model}, e.g. bytedance/doubao-seedance-2.0.
content array *
An array of content items. Each item is distinguished by type and may contain a text prompt and various reference media.
type string *
Content item type. One of: text | image_url | video_url | audio_url.
text string
Used when type is text; the text prompt describing the video. Multiple text items are concatenated in order.
role string
Role of the media item, by type:
image_url:first_frame(the default whenroleis omitted),last_frame, orreference_image.video_url:reference_video.audio_url:reference_audio(supported by some models).
image_url / video_url / audio_url object
Container object for the corresponding media, with a single field url:
urlstring: the media address. Accepts an http(s) URL, or adata:<mime>;base64,<data>Data URI.
resolution string Optional
Video resolution, e.g. 480p, 720p, 1080p.
ratio string Optional
Aspect ratio, e.g. 16:9, 9:16, adaptive.
duration integer Optional
Video duration in seconds, e.g. 5.
seed integer Optional
Random seed; -1 means random.
generate_audio boolean Optional
Whether to also generate an audio track.
callback_url string Optional
URL notified via callback when the task finishes.
return_last_frame boolean Optional
Whether to also return the video's last frame in the result (content.last_frame_url).
tools array Optional
Native tools / capability toggles, passed through to the provider.
frames integer Optional
Number of frames to generate (supported by some models/modes).
watermark boolean Optional
Whether to add a watermark to the generated video.
Field passthrough
These optional fields — and any other unlisted native fields — are passed through to the provider as-is and validated by the provider per model/mode; unsupported fields return a native error.
Path parameters (poll)
jobId string *
The task id returned by the submit request.
Response
Submit response
{
"id": "fff8799f449e4ada8ceebe0079f7c01c",
"status": "queued",
"model": "bytedance/doubao-seedance-2.0"
}id string
Task identifier, used for subsequent polling.
status string
Task status. Usually queued right after submit.
model string
The model slug used for this task.
Poll response
status is one of queued | running | succeeded | failed.
In progress (queued / running):
{
"id": "fff8799f449e4ada8ceebe0079f7c01c",
"status": "running",
"model": "bytedance/doubao-seedance-2.0"
}Succeeded (succeeded):
{
"id": "fff8799f449e4ada8ceebe0079f7c01c",
"status": "succeeded",
"model": "bytedance/doubao-seedance-2.0",
"content": {
"video_url": "https://.../result.mp4",
"last_frame_url": "https://.../last_frame.jpg"
}
}content.video_urlstring: download URL of the generated video.content.last_frame_urlstring: download URL of the video's last frame (returned whenreturn_last_framewas set).contentis the native result passed through as-is and may include additional native fields beyond those above.
Failed (failed):
{
"id": "fff8799f449e4ada8ceebe0079f7c01c",
"status": "failed",
"model": "bytedance/doubao-seedance-2.0",
"error": {
"code": "generation_failed",
"message": "<reason>"
}
}Task not found (HTTP 404):
{
"error": {
"code": "404",
"type": "not_found",
"message": "Video task '<jobId>' not found"
}
}# Step 1: Submit a video generation request
curl -X POST "https://openqiao.com/api/v1/videos" \
-H "Authorization: Bearer $OPENQIAO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bytedance/doubao-seedance-2.0",
"content": [
{ "type": "text", "text": "a cat reading a book under soft morning light" }
],
"resolution": "720p",
"ratio": "16:9",
"duration": 5,
"seed": -1,
"generate_audio": true
}'
# The response contains the task id, used for polling
# {"id": "fff8799f449e4ada8ceebe0079f7c01c", "status": "queued", "model": "bytedance/doubao-seedance-2.0"}
# Step 2: Poll task status (every 15 seconds)
curl "https://openqiao.com/api/v1/videos/fff8799f449e4ada8ceebe0079f7c01c" \
-H "Authorization: Bearer $OPENQIAO_API_KEY"# Pass a first-frame image, reference video, or reference audio via the content array
curl -X POST "https://openqiao.com/api/v1/videos" \
-H "Authorization: Bearer $OPENQIAO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bytedance/doubao-seedance-2.0",
"content": [
{ "type": "text", "text": "The singer performs on stage in sync with the music" },
{ "type": "image_url", "role": "first_frame", "image_url": { "url": "https://example.com/first.png" } },
{ "type": "audio_url", "role": "reference_audio", "audio_url": { "url": "https://example.com/ref.mp3" } }
],
"resolution": "720p",
"ratio": "16:9",
"duration": 5,
"generate_audio": true
}'// Returned after submit (in progress)
{
"id": "fff8799f449e4ada8ceebe0079f7c01c",
"status": "queued",
"model": "bytedance/doubao-seedance-2.0"
}
// Returned after polling completes
{
"id": "fff8799f449e4ada8ceebe0079f7c01c",
"status": "succeeded",
"model": "bytedance/doubao-seedance-2.0",
"content": {
"video_url": "https://.../result.mp4",
"last_frame_url": "https://.../last_frame.jpg"
}
}