Use rb.video() to generate videos. All video generation is asynchronous — submit a task, then poll for results. The SDK's .task() method handles polling automatically.
Quick start
import { RouterBrain } from '@router-brain/sdk';
const rb = new RouterBrain('sk-your-api-key');
// Submit task + auto-poll until complete
const result = await rb.video({
model: 'wan2.1-t2v-turbo',
prompt: 'Cinematic push-in shot of a night city street, neon lights, rain reflections',
resolution: '720p',
ratio: '16:9',
}).task({ pollInterval: 3000 });
console.log(result.task_status); // 'success'
console.log(result.data[0]?.url); // generated video URL
Submit a task only
If you want to handle polling yourself:
const created = await rb.video({
model: 'wan2.1-t2v-turbo',
prompt: 'A robot inspecting a Mars base',
resolution: '720p',
}).json();
console.log(created.task_id); // use this to poll /video/v1/tasks/:task_id
Multi-modal input
rb.video() supports text, image, video, and audio input. Strings are treated as URLs. Objects use the VideoURL structure with a type role.
// Image-to-video
const imageResult = await rb.video({
model: 'kling-v2-1-turbo',
prompt: 'Make the person turn their head and smile',
image: 'https://example.com/portrait.jpg',
resolution: '720p',
}).task();
// Video reference input (Seedance modality_tokens billing uses this)
const videoResult = await rb.video({
model: 'doubao-seedance-1-0-pro-250528',
prompt: 'Continue from the reference video, keep characters and scene consistent',
video: { type: 'reference_video', url: 'https://example.com/clip.mp4' },
resolution: '720p',
}).task();
// Multiple reference images
const multiResult = await rb.video({
model: 'doubao-seedance-1-0-pro-250528',
prompt: 'Smooth transition between two reference frames',
image: ['https://example.com/frame1.jpg', 'https://example.com/frame2.jpg'],
resolution: '720p',
}).task();
Cancel polling
Pass an AbortSignal to stop polling.
const controller = new AbortController();
setTimeout(() => controller.abort(), 120000);
try {
const result = await rb.video({
model: 'wan2.1-t2v-turbo',
prompt: '...',
}).task({ signal: controller.signal });
} catch (err) {
console.error('Task aborted or failed:', (err as Error).message);
}
Available methods
| Method | Returns | When to use |
|---|---|---|
json() | Promise<VideoResponseJson> | Submit a task — get task_id |
task(opts?) | Promise<VideoTaskResponseJson> | Submit + auto-poll until success, failure, or cancellation |
httpStatus() | Promise<number> | Check HTTP status before calling .json() |
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Model code, e.g. wan2.1-t2v-turbo |
prompt | string | Yes | Text prompt |
image | string | string[] | VideoURL | VideoURL[] | No | Reference image(s) |
video | string | string[] | VideoURL | VideoURL[] | No | Reference video(s) |
audio | string | string[] | VideoURL | VideoURL[] | No | Reference audio |
ratio | string | No | Aspect ratio: 16:9, 9:16, 1:1 |
resolution | string | No | Resolution: 480p, 720p, 1080p, 4k |
upstream_options | Record<string, any> | No | Provider-specific parameters |
headers | Record<string, string | string[]> | No | Custom HTTP headers |
Driver-specific parameters
Seedance (upstream_options)
const result = await rb.video({
model: 'doubao-seedance-1-0-pro-250528',
prompt: '...',
upstream_options: {
duration: 5,
watermark: false,
service_tier: 'default',
seed: 42,
generate_audio: true,
},
}).task();
Bailian (upstream_options)
const result = await rb.video({
model: 'kling-v2-1-turbo',
prompt: '...',
upstream_options: {
duration: 5,
watermark: false,
seed: 123,
},
}).task();
Task response structure
interface VideoTaskResponseJson {
task_id: string;
task_status: 'pending' | 'running' | 'success' | 'failed' | 'cancelled';
model: string;
created: number | null; // timestamp (ms)
updated: number | null; // timestamp (ms)
completed: number | null; // timestamp (ms)
data: VideoTaskData[]; // [{ url: "..." }] on success
error: VideoTaskError | null; // { code, message } on failure
}
Billing methods
| Method | Driver | Unit |
|---|---|---|
duration | Bailian | credits/second of output video |
modality_tokens | Seedance | credits/token, with separate prices for requests with vs. without video input |
Use rb.models('video') and rb.endpoints('video', code) to inspect pricing:
const models = await rb.models('video', { q: 'seedance' });
console.log(models.data[0].pricing);
const detail = await rb.endpoints('video', 'doubao-seedance-1-0-pro-250528');
for (const ep of detail.endpoints) {
console.log(ep.billing_method, ep.pricing);
}