Video Tool
Generate video from a text prompt, or animate a photo
Video Generation
Generate a video from a text prompt, or animate a photo into one. Unlike every other Skill, this is submit-then-poll: a generation takes minutes, not seconds, so the call that starts it returns immediately and you read the result from a second endpoint once it lands.
Submit
POST /v1/video/generationscurl https://api.router9.com/v1/video/generations \
-H "Authorization: Bearer sk-r9k-your-key" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A small paper boat gently floating down a calm stream",
"duration_seconds": 6,
"resolution": "720p",
"ratio": "16:9"
}'| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | What the video should show, or how a supplied photo should move |
model | string | No | Override the default video model (must be allowlisted) |
image_url | string | No | An HTTP(S) URL or data: URL used as the first frame. Omit for text-to-video |
image_asset_id | string | No | A picture already in your library, by id, used as the first frame in place of image_url. It is read from your own storage, and recorded on the finished video |
reference_asset_ids | string[] | No | Pictures already in your library, by id, used as style or content references instead of a first frame. Only the Seedance models take them, up to 4; send either these or a first frame, never both. An id that is not yours is refused with a 400 |
duration_seconds | integer | No | Clip length. Range varies by model — see the catalog below |
resolution | string | No | A vendor-specific tier, e.g. 720p, 2K. Varies by model |
ratio | string | No | Aspect ratio, e.g. 16:9, 9:16. Varies by model |
project_id | string | No | Project to file the result into — an id from GET /v1/projects. Omit it, or send one that is not yours, and it lands in your default project |
Duration, resolution and ratio vocabularies are per model, not fixed across
the tool — one vendor's 2K is another's 1080p, and not every model
accepts a reference photo. Call GET /v1/public/video-models to see what
the model you are using actually offers before you submit.
Response
202 Accepted — the job is queued, not finished:
{
"id": "cjunazub3ojykjbwoqm11b6sq",
"status": "QUEUED",
"model": "bytedance/seedance-2.0-mini",
"queuedAt": "2026-09-12T11:39:27.565Z"
}Nothing is billed at submit time. The generation is only charged once it actually succeeds — see Credits.
Poll
GET /v1/video/jobs/{id}curl https://api.router9.com/v1/video/jobs/cjunazub3ojykjbwoqm11b6sq \
-H "Authorization: Bearer sk-r9k-your-key"status is one of QUEUED, SUBMITTED (accepted by the vendor and running),
SUCCEEDED, FAILED, or CANCELLED. Poll every few seconds until it reaches
one of the last three.
{
"id": "cjunazub3ojykjbwoqm11b6sq",
"status": "SUCCEEDED",
"model": "bytedance/seedance-2.0-mini",
"queuedAt": "2026-09-12T11:39:27.565Z",
"startedAt": "2026-09-12T11:39:27.601Z",
"finishedAt": "2026-09-12T11:43:03.545Z",
"resultAssetId": "cjunazub3ojykjbwoqm11b6sq",
"resultUrl": "https://.../generated-media/...",
"resultExpiresAt": "2026-09-13T11:43:03.545Z"
}resultUrl is a signed link, present only once status is SUCCEEDED —
absent on every other status, and gone again after resultExpiresAt. Download
it before then; a new poll after expiry does not mint a fresh one for an
already-terminal job. A FAILED or CANCELLED job carries an error string
instead. resultAssetId is the clip's id in your library, present on the same
condition; unlike the link it does not expire.
Catalog
GET /v1/public/video-models → { "models": [...] }Public. Each model carries a constraints block — whether it accepts a
reference photo, its duration range, and the resolutions and ratios it
actually offers — so a client can discover a limit without having to be
refused by it. A model that accepts only certain lengths inside its range
(4, 6 or 8 seconds, say) also lists them as durations; any other
duration_seconds is refused.
Errors
Every video endpoint answers failures in the shared media error envelope. See Errors.
Credits
Video Skill calls consume credits from your plan's monthly credit allowance — the same allowance used for chat completions. Video is metered per second of finished clip, at a rate that can vary by resolution — a model's higher tiers cost more per second than its default. See Credits & Usage and Tool Usage & Credits.