Animate a still
Turn one still image into one video.
Animate a still turns one image that your workspace owns into one image-to-video generation. Use it on a product photo, on a static ad, or on any still that you already made with roasOS.
One call makes one video. There is no fan-out, and there is no variants field.
1. Choose the still
Send exactly one source.
| Field | Use it for |
|---|---|
image_url | A still on https://cdn.roasos.com that your workspace owns |
upload_id | The id that POST /v1/uploads gave you |
The still must be 10 MB or smaller. Use image/jpeg, image/png or image/webp. Refer to Reference media and uploads.
Add an optional product_id to hold a saved product steady. Its images ride as style references.
2. Write a prompt, or let roasOS write one
Send a prompt that says what moves. Name one primary movement.
The bottle stays still. The steam rises slowly from the cup behind it. The light moves a little across the label.Set auto_prompt: true to skip that step. roasOS then analyzes the still first and derives the prompt from the analysis.
auto_prompt bills one still analysis on top of the video. That is 1 extra credit. Refer to Analyze an ad.
Send prompt, or set auto_prompt to true. A request with neither is refused.
3. Choose the model
The default is seedance-2.5 (since 2026-10-04). Set model to change it.
| Model | Use it for |
|---|---|
seedance-2.5 | The default. It takes its shape from the still, accepts a still that shows a person, and renders one take of up to 30 seconds with sound. |
kling-4 | A still with product references (product_id), or a length that Seedance does not offer. |
When you send no model, roasOS uses seedance-2.5. Two exceptions use kling-4: a request with product_id, because Seedance cannot combine a first frame with product references, and a duration_seconds that Seedance does not offer (for example 7). roasOS never changes a model that you sent. With no duration_seconds, the clip is 5 seconds.
The two models accept different options.
| Field | kling-4 | seedance-2.5 |
|---|---|---|
duration_seconds | Each whole second from 3 to 30 | 4, 5, 6, 8, 10, 12, 15, 20, 25, 30 |
aspect_ratio | Taken from the still; with product_id: 9:16, 16:9, 1:1, 21:9 | Taken from the still |
resolution | 720p, 1080p; the default is 1080p | 480p, 720p, 1080p; the default is 720p |
prompt length | 2,500 characters | 10,000 characters |
4. Quote
curl -X POST https://api.roasos.com/v1/workflows/static-to-video \
-H "Authorization: Bearer roasos_sk_..." \
-H "Idempotency-Key: animate-serum-hero-001" \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://cdn.roasos.com/workspaces/.../serum-hero.png",
"prompt": "The bottle stays still. The steam rises slowly behind it.",
"duration_seconds": 5,
"quote_only": true
}'{
"data": {
"kind": "quote",
"quote_id": "f70b2d51-...",
"credits": 15,
"expires_at": "2026-08-21T12:09:04.000Z",
"pricing_version": "customer-pricing@2026-10-30.v14",
"confirmation": {
"model": "seedance-2.5",
"mode": "image-to-video",
"duration_seconds": 5,
"generate_audio": true
}
}
}A 5-second Seedance 2.5 clip at 720p costs 15 credits, and a 10-second clip costs 30. On kling-4 at 1080p, the same clips cost 15 and 29 (10 and 19 at 720p). The full table is on the Kling 4.0 page and on the Seedance 2.5 page.
5. Confirm
Send the same body with the quote_id. Use the same idempotency key.
curl -X POST https://api.roasos.com/v1/workflows/static-to-video \
-H "Authorization: Bearer roasos_sk_..." \
-H "Idempotency-Key: animate-serum-hero-001" \
-H "Content-Type: application/json" \
-d '{
"image_url": "https://cdn.roasos.com/workspaces/.../serum-hero.png",
"prompt": "The bottle stays still. The steam rises slowly behind it.",
"duration_seconds": 5,
"quote_id": "f70b2d51-..."
}'The answer is 201 with the standard job envelope.
{
"data": {
"id": "1e9c4a70-...",
"kind": "video",
"model": "seedance-2.5",
"status": "queued",
"credits_reserved": 15,
"created_at": "2026-08-21T11:59:41Z",
"links": {
"self": "/v1/jobs/1e9c4a70-...",
"status": "/v1/jobs/1e9c4a70-.../status",
"result": "/v1/jobs/1e9c4a70-.../result",
"events": "/v1/jobs/1e9c4a70-.../events"
}
}
}6. Poll the job
curl https://api.roasos.com/v1/jobs/1e9c4a70-.../status \
-H "Authorization: Bearer roasos_sk_..."Animate a still is an ordinary job, so it carries the five job statuses. Poll every few seconds until the status is completed, failed or canceled. Send a webhook_url in the confirm request when you do not want to poll. Refer to Jobs and to Webhooks.
7. Read the result
curl https://api.roasos.com/v1/jobs/1e9c4a70-.../result \
-H "Authorization: Bearer roasos_sk_..."{
"data": { "url": "https://cdn.roasos.com/workspaces/.../serum-hero.mp4" }
}Errors
| Code | Cause |
|---|---|
invalid_request | Two sources, no source, or no prompt and no auto_prompt |
reference_media_not_workspace_owned | The still is not workspace-owned media |
provider_rejects_face_references | The provider of seedance-2.5 refused a face in the images it received. roasOS refunds the reservation in full. |
insufficient_credits | The balance does not cover the quote |
quote_expired | The quote is older than 10 minutes; quote again under a new idempotency key |
Refer to Errors.
From an agent
The MCP tool is roasos_static_to_video. The quote rule is the same. Refer to Connect an AI agent (MCP).