Use POST /v2/videos/generations to start a video generation. Video generation is asynchronous, so you submit once, poll for status, and download the finished asset when itβs ready.
POST https://api.getimg.ai/v2/videos/generations
GET https://api.getimg.ai/v2/videos/generations/{id}
The generation flow
Submit a generation request
POST to /v2/videos/generations with your model, prompt, and parameters. The API returns HTTP 202 with a generation ID and status: "pending".
Poll for completion
GET /v2/videos/generations/{id} periodically. The status will be pending, failed, or completed.
Download the video
When status is completed, download the video from the signed download URL in data[0].url.
Step 1: Submit
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const result = await client.videos.generations.create({
model: "seedance-v1-5-pro",
prompt: "A drone shot over a futuristic city skyline at sunset",
aspect_ratio: "16:9",
resolution: "1080p",
duration: 5,
sound: true,
});
const generationId = result.id; // e.g., "req-01HXYZVIDEO1234"
{
"id": "req-01HXYZVIDEO1234",
"status": "pending"
}
Step 2: Poll for status
Poll the status endpoint with your generation ID.
| Status | Meaning | Next action |
|---|
pending | Still processing | Wait and poll again |
failed | Generation failed | Read error.message, then submit a new generation if needed |
completed | Video is ready | Download from data[0].url |
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const result = await client.videos.generations.retrieve("req-01HXYZVIDEO1234");
console.log(result.status);
Completed response:
{
"id": "req-01HXYZVIDEO1234",
"status": "completed",
"model": "seedance-v1-5-pro",
"data": [
{
"url": "https://api.getimg.ai/v2/downloads/req-01HXYZVIDEO1234/0?exp=1760000000&sig=ca4f0f...",
"width": 1920,
"height": 1080,
"duration": 5,
"fps": 24,
"has_sound": true,
"mime_type": "video/mp4",
"deletes_at": "2026-05-02T12:30:00.000Z"
}
],
"usage": {
"total_cost": 0.25,
"billable_unit": "video_second",
"unit_price": 0.05,
"quantity": 5
}
}
Polling strategy
Poll every 5 seconds as a starting point. Set a timeout so your integration stays responsive and does not poll forever.
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
async function pollVideo(generationId, interval = 5000, timeout = 300000) {
const start = Date.now();
while (Date.now() - start < timeout) {
const result = await client.videos.generations.retrieve(generationId);
if (result.status === "completed") return result;
if (result.status === "failed") {
throw new Error(`Generation failed: ${result.error.message}`);
}
await new Promise((r) => setTimeout(r, interval));
}
throw new Error(`Video not ready after ${timeout / 1000}s`);
}
Step 3: Download
The url in each data item is a signed download URL. Download the file before the deletes_at timestamp.
import { writeFile } from "node:fs/promises";
const download = await fetch("https://api.getimg.ai/v2/downloads/req-01HXYZVIDEO1234/0?exp=1760000000&sig=ca4f0f...");
const buffer = Buffer.from(await download.arrayBuffer());
await writeFile("video.mp4", buffer);
Parameters
| Parameter | Type | Default | Description |
|---|
model | string | required | Model identifier. See Models. |
prompt | string | required | Text description of the video to generate. |
aspect_ratio | string | model default | e.g., 16:9, 1:1, 9:16. |
resolution | string | model default | e.g., 720p, 1080p. |
duration | integer | model default | Duration in seconds. |
sound | boolean | false | Generate audio, where supported by the model. |
images | array | β | First frame, last frame, or reference image inputs. |
Using frame and reference images
Video models support multiple image roles in the images array:
first_frame: the opening frame of the video
last_frame: the closing frame of the video. This always requires a first_frame.
reference_image: a style or content reference when you need the output to stay closer to an existing visual direction. You cannot combine it with first_frame or last_frame.
{
"model": "seedance-v1-5-pro",
"prompt": "Transition from sunrise to dusk over mountain landscape",
"images": [
{
"url": "https://your-bucket.s3.amazonaws.com/sunrise.png",
"role": "first_frame"
},
{
"url": "https://your-bucket.s3.amazonaws.com/dusk.png",
"role": "last_frame"
}
],
"aspect_ratio": "16:9",
"resolution": "720p",
"duration": 10
}
Not all models support all roles. Unsupported roles return 400 with code invalid_parameter.
Failure states
Video generations can fail after submission.
- If polling returns
status: "failed", treat that generation as terminal.
- Read
error.message for the reason.
- Fix the input, wait if the problem is temporary, or submit a new generation.
Set sound: true to generate audio. Supported models are listed on the Models page.
{
"model": "seedance-v1-5-pro",
"prompt": "Ocean waves crashing on a rocky shore",
"duration": 10,
"sound": true
}
Full example
import { writeFile } from "node:fs/promises";
import GetimgAI from "getimg-ai";
const client = new GetimgAI();
const { id } = await client.videos.generations.create({
model: "seedance-v1-pro",
prompt: "A timelapse of clouds rolling over a mountain peak",
aspect_ratio: "16:9",
resolution: "1080p",
duration: 10,
sound: true,
});
console.log(`Submitted: ${id}`);
let result = await client.videos.generations.retrieve(id);
while (result.status === "pending") {
await new Promise((r) => setTimeout(r, 5000));
result = await client.videos.generations.retrieve(id);
console.log(`Status: ${result.status}`);
}
if (result.status === "failed") {
throw new Error(`Failed: ${result.error.message}`);
}
const video = result.data[0];
const download = await fetch(video.url);
const buffer = Buffer.from(await download.arrayBuffer());
await writeFile("output.mp4", buffer);
console.log(`Saved output.mp4 (${video.width}x${video.height}, ${video.duration}s, ${video.fps}fps)`);
console.log(`Sound: ${video.has_sound}`);
console.log(`Cost: ${result.usage?.total_cost} (${result.usage?.quantity} ${result.usage?.billable_unit})`);
Related pages