Animate a still
Turn one still your workspace owns into one video. Send exactly one source (`image_url` or `upload_id`) and a `prompt`, or set `auto_prompt: true` to analyze the still first and derive the prompt from it — that analysis is billed on top of the video. The default model is seedance-2.5 (the animate-still role); `kling-4` is the other choice. roasOS never switches the model for you. One call makes one video. There is no fan-out.
Turn one still your workspace owns into one video. Send exactly one source (image_url or upload_id) and a prompt, or set auto_prompt: true to analyze the still first and derive the prompt from it — that analysis is billed on top of the video.
The default model is seedance-2.5 (the animate-still role); kling-4 is the other choice. roasOS never switches the model for you.
One call makes one video. There is no fan-out.
Authorization
bearerAuth API key authentication. Use your API key as the bearer token: Authorization: Bearer roasos_sk_...
In: header
Header Parameters
A unique string that makes retries safe. Any value 16-255 characters; reuse it only when retrying the exact same request.
^[A-Za-z0-9._:-]+$16 <= length <= 255Optional label to group this request under one of your projects. Appears in your usage records.
^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$1 <= length <= 64Optional label to attribute this request to a cost center. Appears in your usage records.
^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$1 <= length <= 64Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/workflows/static-to-video" \ -H "Idempotency-Key: stringstringstri" \ -H "Content-Type: application/json" \ -d '{}'{ "data": { "kind": "quote", "quote_id": "3c071a1d-db86-46a7-9dc8-72ba3fbca992", "credits": 0, "expires_at": "string", "pricing_version": "string", "confirmation": { "property1": null, "property2": null } }}Recast a video
Recast one video with your own person and product. Send exactly one source (`source_video_url` or `source_generation_id`), a `prompt`, and at least one target: `avatar_id`, `product_id`, `references` (on the seedance-2.5-edit lane) or `elements` (Kling only). Without a target this is a plain video edit and the call is refused with `recast_target_required`. The source must be workspace-owned media or a Discover creative (`discover/items/v2/...`): a Discover ad can be recast on purpose. Any other URL is refused with `reference_media_not_workspace_owned`. The default model is seedance-2.5-edit (the preserve-video role). A body that sends `elements` and no `model` runs on kling-4, because only Kling takes elements. Other choices: kling-4, seedance-2.5-edit. Quoting, idempotency, the job envelope, webhooks and refunds are the same as the chosen model's own endpoint.
Extend a video
Continue one video from its last frame and get ONE longer clip: the source, then the new footage. Send exactly one source (`video_url` or `source_generation_id`), a `prompt` for what happens next, and `duration_seconds` for the added length (one of the model's own lengths). The default model is seedance-2.5 (the animate-still role). Any image-to-video model is allowed: kling-4, seedance-2.5, gemini-omni-flash, wan-2.7, veo-3.1, seedance-2, seedance-2-pro, grok-imagine, h3-max, flux-3-max. The shape follows the source, so there is no `aspect_ratio`. When you send no `resolution`, the model resolution closest to the source is used. The server makes two ordinary jobs: the continuation (this response) and, when the continuation completes, one merge that joins the source and the continuation. The quote is both: the continuation plus one merge credit, in `credits_breakdown`. The source plus the continuation must fit in 180 seconds. A `webhook_url` is delivered for the stitched clip. Read the run, and the stitched clip, at `/v1/workflows/extend/{id}` with the job id this call returns. If the merge cannot start, the continuation stays charged and usable, and the stage is `merge_failed`.