Guide
Query a Video Task
Querying task progress and results, status handling, reference asset read failures, and billing
Query a Video Task
After creating a task, use the id from the creation response to query progress and results; see Create a Video Task for how to create one.
Query status: GET /v1/video/generations/{task_id}
Download the finished video: GET /v1/videos/{task_id}/content
After the task completes, the query API returns the video URL in metadata.url. The platform prefers the upstream original video URL and falls back to a platform artifact URL with the access capability only when the upstream has no usable URL. Upstream original URLs may carry a signature and expiration time and can be opened directly in a browser or player; platform artifact URLs work as well. You can also call /v1/videos/{task_id}/content with the API key to download the video file.
Authentication
Authorization: Bearer <API_KEY>.
Request parameters · path
| Parameter | Type | Required | Description |
|---|---|---|---|
task_id | string | Yes | The id from the creation response |
Request example
curl "$LOCOPAL_API_ORIGIN/v1/video/generations/$LOCOPAL_TASK_ID" \
-H "Authorization: Bearer $LOCOPAL_API_KEY"Download the video
After the task status becomes completed, use the metadata.url from the query response directly:
curl -L "$LOCOPAL_API_ORIGIN/v1/videos/$LOCOPAL_TASK_ID/content" \
-H "Authorization: Bearer $LOCOPAL_API_KEY" \
-o "$LOCOPAL_TASK_ID.mp4"Response parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Public task ID |
task_id | string | Compatibility field identical to id |
object | string | Always video |
model | string | Video model ID |
status | string | queued, in_progress, completed, failed, or unknown |
progress | integer | Current progress, ranging from 0 to 100 |
created_at | integer | Creation time (Unix seconds) |
completed_at | integer | Completion time; not returned while incomplete |
metadata.url | string | Video URL, returned on success; preferably the upstream original URL, or the platform artifact URL when necessary |
metadata.upstream_created | boolean | Whether the task has been created upstream |
duration_secs | integer | Video duration (seconds); provided when returned by the upstream |
expires_at | integer | Upstream URL expiration time (Unix seconds); provided only when explicitly returned by the upstream |
framespersecond | integer | Video frame rate; provided when returned by the upstream |
generate_audio | boolean | Whether synchronized audio is generated; provided when returned by the upstream |
ratio | string | Output aspect ratio; provided when returned by the upstream |
resolution | string | Output resolution; provided when returned by the upstream |
seed | integer | Random seed; provided when returned by the upstream |
output_format | string | Output format, for example mp4; provided when returned by the upstream |
execution_expires_after | integer | How long the task result is retained; provided when returned by the upstream |
usage | object | Actual usage and cost after the task is settled; not returned while the task is unsettled (queued, generating, or just accepted) |
usage.prompt_tokens | integer | Number of video tokens billed for this request (matches the number on the left of the "Tokens" column in the bill) |
usage.completion_tokens | integer | Video/image tasks do not report output tokens separately; always 0 |
usage.total_tokens | integer | Total usage, equal to usage.prompt_tokens |
usage.quota | integer | Credits actually consumed by this task |
usage.amount | number | Amount for this task (CNY), converted from usage.quota according to the platform's settlement basis, with 6 decimal places; the console bill displays the same charge with 4 decimal places |
usage.currency | string | Currency of the amount; always CNY |
error.code | string | Failure error code, returned only on failure. For platform video tasks, a final failure is usually video_generation_failed; upstream errors that cannot be normalized may retain the upstream error code |
error.message | string | Failure reason, returned only on failure. The platform first strips multiple layers of JSON and gateway HTML wrappers and returns readable text that can be displayed directly; clients must not parse this text as JSON again |
Response body
In progress:
{
"id": "task_XVCPphL5ZWOr2iMpGhNkV32qRTj7MSUO",
"task_id": "task_XVCPphL5ZWOr2iMpGhNkV32qRTj7MSUO",
"object": "video",
"model": "doubao-seedance-2.0-A",
"status": "in_progress",
"progress": 50,
"created_at": 1787299277
}Generation succeeded:
{
"id": "task_XVCPphL5ZWOr2iMpGhNkV32qRTj7MSUO",
"task_id": "task_XVCPphL5ZWOr2iMpGhNkV32qRTj7MSUO",
"object": "video",
"model": "doubao-seedance-2.0-A",
"status": "completed",
"progress": 100,
"created_at": 1787299277,
"completed_at": 1787299581,
"duration_secs": 5,
"expires_at": 1790578352,
"framespersecond": 24,
"generate_audio": true,
"ratio": "9:16",
"resolution": "480p",
"seed": 20260409,
"output_format": "mp4",
"execution_expires_after": 172800,
"metadata": {
"url": "https://upstream.example.com/task_XVCPphL5ZWOr2iMpGhNkV32qRTj7MSUO.mp4?signature=...",
"upstream_created": true
},
"usage": {
"prompt_tokens": 141034,
"completion_tokens": 0,
"total_tokens": 141034,
"quota": 2789652,
"amount": 5.579304,
"currency": "CNY"
}
}usage is returned only after the task completes and is settled, and its values exactly match the charge for this task in the bill: usage.quota is the credits consumed this time, usage.amount is the CNY amount converted from the same credits at the current site exchange rate, and usage.total_tokens is the number of video tokens billed this time. usage is not returned while the task is still queued or generating, so do not judge the cost from the query response at that point; to verify the charge, compare usage.quota and usage.amount in the console bill using the same id.
metadata.url may be a signed upstream URL or a fallback from the platform artifact API. Treat it as a credential and do not share it publicly. Once the video is generated, download it or copy it to your own object storage before expires_at.
Video artifacts and previews
In addition to reading metadata.url directly, you can also query the platform artifact list:
curl "$LOCOPAL_API_ORIGIN/v1/tasks/$LOCOPAL_TASK_ID/artifacts" \
-H "Authorization: Bearer $LOCOPAL_API_KEY"After the task completes, it returns:
{
"task_id": "task_XVCPphL5ZWOr2iMpGhNkV32qRTj7MSUO",
"artifacts": [
{
"key": "video",
"type": "video",
"content_url": "https://locopalai.com/v1/tasks/task_XVCPphL5ZWOr2iMpGhNkV32qRTj7MSUO/artifacts/video/content?access=..."
}
]
}Artifact content URLs support Range requests and can be used directly by players, browser previews, and resumable downloads. If a client only reads metadata.url, it can keep its existing logic and does not need to switch to the artifact API.
Generation failed:
{
"id": "task_NlersigX6rIqiOjCwTFlgNmGMTwqt39K",
"object": "video",
"model": "doubao-seedance-2.0-D",
"status": "failed",
"progress": 100,
"created_at": 1789971935,
"error": {
"code": "video_generation_failed",
"message": "音频素材缓冲失败: 音频地址必须是 http(s)"
},
"metadata": {
"submission_stage": "submitting",
"upstream_created": false
}
}error.message is the final failure text prepared by the platform. Even if a historical task originally stored nested JSON, queries return the normalized text; callers can display this field to users directly, and should not concatenate or parse the raw upstream JSON on the client.
Error response
Querying a non-existent task ID (or a task that does not belong to the current account) returns HTTP 400:
{ "code": "task_not_exist", "message": "task_not_exist", "data": null }| HTTP | Response | Handling |
|---|---|---|
400 | {"code":"task_not_exist","message":"task_not_exist","data":null} | Verify the task ID and the account that created the task |
401 | Invalid token | API key missing, incorrect, or expired |
500 | Task query failed | Save the request ID and keep querying the original task later |
Status handling
| Status | Client handling |
|---|---|
queued | The task has entered the queue; keep querying the same task ID |
in_progress | Generation is in progress; update the progress and waiting time, and do not create a new task |
completed | Read metadata.url, or call /v1/videos/{task_id}/content to download the finished video; copying it promptly is recommended |
failed | Show error.code and error.message once and let the user decide whether to resubmit |
unknown | The status cannot be determined temporarily; keep the task ID and query again later |
Clients should not use a fixed number of seconds to judge completion, nor create duplicate tasks because of a single network timeout; querying every 5–15 seconds is recommended.
Reference asset read failures
When the error points to content[n].image_url or video_url, or contains resource download failed, first locate the specific element by its array index, then check:
- Whether the URL can be
GETdirectly from the public internet and returns200; - Whether it redirects to a login page or depends on cookies, Referer, or an IP allowlist;
- Whether
Content-Typematches the file's actual format; - Whether a temporary signed URL is still valid during download and processing;
- Whether the
asset://asset belongs to the current account and has statusActive; - Whether the current model supports that asset type and count.
Fix the asset and create the task again. Show the readable reason from the error message to the user once; do not repeatedly concatenate and display multiple layers of escaped JSON.
Concurrency, retries, and billing
- Different video tasks can be created concurrently;
- The same creation response must be queried with the same task ID;
- Only when a task has explicitly failed and the user actively retries should a new creation request be made;
- Billing is itemized by model, resolution, duration, and reference video input; refer to the model marketplace and the final bill. A parameter validation failure (
400) means the request was not accepted and usually incurs no generation task cost.
Related documents
| What you want to see | Which page to visit |
|---|---|
| Capability boundaries and common questions for multiple images, reference videos, and depth videos | Multiple Images and Reference Videos |
| The complete flow from adding assets to the library to submitting a video | Portrait Assets and Reference Video Integration Workflow |
| Asset groups, asset status, portrait authorization | Asset Library API |
| Error code quick reference | Error Codes and Troubleshooting |
