/omni/media/v1/contents/generations/tasksVideo generation
Video generation is asynchronous: create a task (202 + task id), poll until the status is terminal, then read the signed URL. Same base URL and atp- key as image. The gateway routes your unified model to a video provider with same-name failover.
- POST
…/contents/generations/tasks - GET
…/contents/generations/tasks/{id}
- A succeeded task carries
content.video_url— a signed edge URL with a 30-minute TTL. After expiry the task still reportssucceededbutvideo_urlisnullandexpired: true(re-create to regenerate). - Requests are refused with
402 insufficient_quotawhen the project balance is ≤ 0.
Available video models#
Confirm names with GET /v1/models.
Call GET https://api.atptoken.ai/v1/models with the same key used to create the task. If a model is absent, that project cannot use it; installing a skill or knowing the model name does not bypass allowed models.
Create a task#
curl https://api.atptoken.ai/omni/media/v1/contents/generations/tasks \
-H "Authorization: Bearer atp-..." -H "Content-Type: application/json" \
-H "Idempotency-Key: my-stable-key-123" \
-d '{
"model": "seedance-2-0",
"content": [
{ "type": "text", "text": "a red fox running through snow, cinematic" },
{ "type": "image_url", "image_url": { "url": "https://example.com/first.jpg" }, "role": "first_frame" }
],
"resolution": "720p",
"ratio": "16:9",
"duration": 5
}'
# → 202 { "id": "task_..." }content[] blocks — Each block is { "type": "text" | "image_url" | "video_url" | "audio_url", ... }.
- Text only → text-to-video; include an image → image-to-video.
image_url/video_urltake{ "url": "…" }.roleisfirst_frame/last_frame/reference_image/reference_video.
What url accepts#
The video endpoint accepts public https:// URLs, and on Seedance, asset:// URIs from the asset API.
On the image endpoint, asset:// references fail at generation time with provider_error / generation_failed.
Reference an uploaded file#
To reference something you uploaded, turn the upload into a public URL:
# 1. upload — the response key is `id` (an_<ULID>), not gw_file_id
curl -s https://api.atptoken.ai/v1/files \
-H "Authorization: Bearer atp-..." -F "file=@./first-frame.png"
# → 201 { "id": "an_01H...", "object": "file", "bytes": 152340, ... }
# 2. resolve to a no-auth URL — read the 302 Location, do NOT follow it
curl -sD - -o /dev/null https://api.atptoken.ai/v1/files/an_01H... \
-H "Authorization: Bearer atp-..." | grep -i '^location:'
# → location: https://<object-store>/gateway-files/...?<presigned> (~15-minute TTL)Use that Location value as the url. It needs no authentication, which is what the upstream provider requires — but it expires in about 15 minutes, so resolve it immediately before creating the task rather than caching it.
Reference a registered asset#
Seedance also takes an image registered through the asset API. Register the image, wait until it is Completed, then pass the returned AssetUri (an asset://… URI — use it exactly as returned) as the image block's url:
- POST
/omni/media/v1/asset-groups - POST
/omni/media/v1/assets - POST
/omni/media/v1/assets/get - POST
…/contents/generations/tasks
{ "type": "image_url", "image_url": { "url": "asset://…" }, "role": "reference_image" }The URI goes only in image_url.url; the block has no top-level url. A /v1/files id is not an asset URI.
Poll until terminal#
curl https://api.atptoken.ai/omni/media/v1/contents/generations/tasks/task_... \
-H "Authorization: Bearer atp-..."
# → { "status": "succeeded", "content": { "video_url": "https://media-prod.atptoken.ai/v/...mp4?exp=...&sig=..." } }Alibaba video models#
wan-2-7-t2v / wan-2-7-i2v and the HappyHorse text/image/reference models use the same unified endpoint and content[] shape as every other video model — the notes below are the model-specific parts. happyhorse-1.0-video-edit is the exception: it is served on a separate DashScope-compatible endpoint (see below).
wan-2-7-t2v / wan-2-7-i2v return a 1080P clip even when the request says 720P, and billing follows what was produced — so a 5-second clip costs the 1080P rate. Budget for 1080P, or use happyhorse-1.1-* when you need 720P pricing.
These models support 720P and 1080P. A request for 480P is not rejected — it renders at roughly 1080P and is billed at the 1080P rate. Send 720P when you want 720P pricing.
Text-to-video#
curl https://api.atptoken.ai/omni/media/v1/contents/generations/tasks \
-H "Authorization: Bearer atp-..." -H "Content-Type: application/json" \
-d '{
"model": "happyhorse-1.1-t2v",
"content": [{ "type": "text", "text": "a horse galloping across a green field" }],
"resolution": "720P", "ratio": "16:9", "duration": 5,
"watermark": false
}'Image-to-video#
Add one image block with role: "first_frame":
"content": [
{ "type": "text", "text": "the subject turns slowly toward the camera" },
{ "type": "image_url", "image_url": { "url": "https://example.com/first.jpg" }, "role": "first_frame" }
]Reference-to-video#
happyhorse-1.1-r2v takes 1 to 9 reference images, each with role: "reference_image". Refer to them in the prompt as [Image 1], [Image 2], …:
"content": [
{ "type": "text", "text": "[Image 1] walks into the room shown in [Image 2]" },
{ "type": "image_url", "image_url": { "url": "https://example.com/person.jpg" }, "role": "reference_image" },
{ "type": "image_url", "image_url": { "url": "https://example.com/room.jpg" }, "role": "reference_image" }
]With multiple reference_image inputs, kling-o3-pro-reference may not follow cross-image composition instructions such as placing [Image 1] in [Image 2]. The task can still produce a video and incur charges. Try a short, low-resolution clip before generating a batch.
Video editing#
For happyhorse-1.0-video-edit, use the DashScope-compatible endpoint, not the unified one. The unified endpoint rejects this model with 400 video-edit requires a source video. Create the task with input.media[] and poll GET /omni/media/v1/tasks/{id}:
curl https://api.atptoken.ai/omni/media/v1/services/aigc/video-generation/video-synthesis \
-H "Authorization: Bearer atp-..." -H "Content-Type: application/json" \
-H "Idempotency-Key: my-stable-key-123" \
-d '{
"model": "happyhorse-1.0-video-edit",
"input": {
"prompt": "replace the background with a snowy street",
"media": [
{ "type": "video", "url": "https://example.com/source.mp4" },
{ "type": "reference_image", "url": "https://example.com/style.jpg" }
]
},
"parameters": { "resolution": "720P", "watermark": false }
}'
# → 202 { "output": { "task_id": "cgt_...", "task_status": "PENDING" } }
curl https://api.atptoken.ai/omni/media/v1/tasks/cgt_... -H "Authorization: Bearer atp-..."
# → { "output": { "task_status": "SUCCEEDED", "video_url": "https://media.atptoken.ai/v/..." }, "usage": { … } }input.media[].typeacceptsvideoorreference_imageonly, and the URL key isurl(notvideo_url).- Every URL — source clip and reference images alike — must be publicly downloadable without authentication; if any of them cannot be fetched the task ends
FAILEDwithFailed to download …and is not billed. - This endpoint returns the DashScope response shape (
output.task_status,output.video_url), and the output length follows the source clip rather thanparameters.duration.
Billing#
Per second of output at the requested resolution, metered as video tokens (width × height × seconds × 24 fps ÷ 1024). For -r2v and -video-edit the input clip's seconds are billed too, so a 5-second edit of a 5-second source bills 10 seconds. Failed tasks are not billed. Rates are on the pricing page.
Other model-specific notes#
- Watermark: HappyHorse has the watermark on by default — pass
watermark: falseto disable it. Wan 2.7 defaults to off. - Ratio: HappyHorse also accepts
4:5,5:4,9:21,21:9on top of the shared list. - Prompt length: 5,000 characters (HappyHorse: 2,500 for Chinese text).
generate_audiois not available on these models yet.