Video Generation
Generate videos from text or images asynchronously, with optional audio, resolution and aspect-ratio control.
/v1/videos/generationsVideo generation runs asynchronously: the endpoint returns a 202 with a job.id immediately, and the video renders in the background. Poll GET /v1/jobs/:id (see Async Jobs) until status becomes completed or failed. The SDK's createAndWait(...) helper does both in one call.
Billing is per second of output and depends on the model and resolution:
| Model | Rates (credits / second) |
|---|---|
veo-3.1-lite | 720p = 72 (120 with audio) · 1080p = 120 (192 with audio) |
hailuo-3-max | 480p = 106 · 768p = 170 |
hailuo-2.3 | 1080p = 173 — 6s or 10s only |
seedance-2-fast | 480p = 180 · 720p = 383 |
veo-3.1-fast | 720p = 192 (240 with audio) · 1080p = 240 (288 with audio) |
seedance-2 | 480p = 226 · 720p = 510 |
wan-2.6 | 720p = 240 · 1080p = 360 |
hailuo-3 | 2K = 276 — audio included at the same rate |
kling-v3-motion-control | 720p = 303 · 1080p = 404 — billed as a reserve, see below |
kling-v3 | 720p = 378 (567 with audio) · 1080p = 504 (756 with audio) · 4K = 945 |
veo-3.1 | 720p and 1080p = 480 (960 with audio) |
Each model's page shows its current rates — the table above is a snapshot. If a job fails after billing (upstream error, timeout), the charged credits are automatically refunded.
Model limits
Every model takes the universal core — prompt, duration, resolution, aspect_ratio, image_url — with its own bounds. The default resolution is the one billed when you omit the field.
| Model | Duration (s) | Resolutions (default first) | Aspect ratios | Audio | Extras |
|---|---|---|---|---|---|
seedance-2 | 1–15, or -1 auto | 480p, 720p | 16:9, 9:16, 1:1, 4:3, 3:4, adaptive | generate_audio, same rate | seed, last_frame_image_url, reference_* arrays |
seedance-2-fast | 1–15, or -1 auto | 480p, 720p | 16:9, 9:16, 1:1, 4:3, 3:4, adaptive | generate_audio, same rate | seed, last_frame_image_url, reference_* arrays |
wan-2.6 | 5–10 | 720p, 1080p | 16:9, 9:16 | generate_audio, same rate | seed; first frame only |
hailuo-3-max | 5–15 | 768p, 480p | 21:9, 16:9, 4:3, 1:1, 3:4, 9:16 | No audio | last_frame_image_url |
hailuo-3 | 5–15 | 2K | 21:9, 16:9, 4:3, 1:1, 3:4, 9:16 | generate_audio, same rate | last_frame_image_url |
hailuo-2.3 | 6 or 10 only | 1080p | 16:9 | No audio | First frame only |
kling-v3 | 3–15 | 720p, 1080p, 4K | 16:9, 9:16, 1:1 | generate_audio, surcharge except at 4K | negative_prompt, last_frame_image_url |
kling-v3-motion-control | Follows reference video | 1080p, 720p | Derived from inputs | keep_original_sound | reference_video_url, character_orientation — see below |
veo-3.1 | 4–8 | 720p, 1080p | 16:9, 9:16 | generate_audio, surcharge | negative_prompt, last_frame_image_url |
veo-3.1-fast | 4–8 | 720p, 1080p | 16:9, 9:16 | generate_audio, surcharge | negative_prompt, last_frame_image_url |
veo-3.1-lite | 4–8 | 720p, 1080p | 16:9, 9:16 | generate_audio, surcharge | negative_prompt, last_frame_image_url |
A parameter a model does not accept returns 400 bad_request naming the parameter — nothing is silently dropped or emulated. hailuo-2.3 accepts only 6 or 10 seconds upstream; other values inside its 6–10 range are rejected by the provider.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
model | string | Yes | Any video model ID from the table above. |
prompt | string | Yes | Text description of the scene and motion. |
duration | integer | No | Seconds, within the model's bounds. Seedance models also accept -1 for auto (billed at 10s). Not accepted by kling-v3-motion-control (output length follows the reference video). Default 5. |
resolution | string | No | One of the model's resolutions. Omitted, the model's default is used and billed. |
aspect_ratio | string | No | One of the model's aspect ratios. Default "16:9". Not accepted by kling-v3-motion-control (framing derives from the inputs). |
generate_audio | boolean | No | Synthesize a soundtrack (dialogue, SFX, music). Default true. Ignored by models without audio; not accepted by kling-v3-motion-control — use keep_original_sound instead. |
negative_prompt | string | No | What to avoid in the output. kling-v3 and the Veo 3.1 models only. |
seed | integer | No | Fixes output for reproducibility. Seedance models and wan-2.6 only. |
image_url | string | No* | First-frame reference (HTTP URL). Enables image-to-video. *Required for kling-v3-motion-control (the character to animate). |
last_frame_image_url | string | No | Last-frame target. Requires image_url. Not accepted by wan-2.6, hailuo-2.3 or kling-v3-motion-control. |
reference_images | string[] | No | Up to 9 URLs. Mutually exclusive with image_url. Referenced in the prompt as [Image1], [Image2], … Seedance models only. |
reference_videos | string[] | No | Up to 3 URLs (combined ≤ 15 s). Referenced as [Video1], … Seedance models only. |
reference_audios | string[] | No | Up to 3 URLs. Requires image_url or reference_images. Referenced as [Audio1], … Seedance models only. |
reference_video_url | string | Yes* | kling-v3-motion-control only: 3–30s motion reference video whose movement is transferred onto the character image. |
character_orientation | string | No | kling-v3-motion-control only: output framing follows "image" (max 10s) or "video" (max 30s). Default "image". |
keep_original_sound | boolean | No | kling-v3-motion-control only: keep the reference video's audio track. Default true. |
Motion control billing
kling-v3-motion-control has no duration parameter — sending one returns a 400. The output length is decided by the reference video (capped at 10s with character_orientation: "image", 30s with "video"), so credits are billed reserve-then-refund:
- At submit, the reference video's length is read and that many seconds × the per-second rate is held (e.g. a 3s reference at 1080p → 3 × 404 = 1,212 credits). If the length cannot be read, the orientation cap is held instead (10 × 404 = 4,040 for
"image"). Your balance must cover the hold. - On completion, the actual output length is measured and the hold is settled both ways: an unused part is refunded, and an overrun is charged before the video is released. If your balance cannot cover an overrun, the job fails with
error.code: "reserve_exceeded", the hold is kept and no video is delivered — this only happens when a reference video's metadata understates its real length. - The completed job reports the net charge:
tchavi.credits_used(net) andtchavi.credits_refunded, withoutput.durationset to the actual length. If the job fails, the full reserve is refunded.
const job = await client.videos.generations.createAndWait({
model: 'kling-v3-motion-control',
prompt: 'The character performs the dance, keeping its exact appearance',
resolution: '1080p',
image_url: 'https://your-host.example.com/character.png',
reference_video_url: 'https://your-host.example.com/motion-reference.mp4',
character_orientation: 'image', // max 10s output
keep_original_sound: true,
// no `duration` — output length follows the reference video
});
console.log(job.output?.duration); // actual seconds rendered
console.log(job.tchavi?.credits_used); // net charge after refund
console.log(job.tchavi?.credits_refunded); // unused part of the reserveExample
import Tchavi from '@tchavi/sdk';
const client = new Tchavi({ apiKey: 'YOUR_API_KEY' });
// One-liner: submit + poll until completed/failed
const job = await client.videos.generations.createAndWait({
model: 'seedance-2',
prompt: 'A cinematic shot of the Cotonou Amazone statue at golden hour',
duration: 5,
resolution: '480p',
aspect_ratio: '9:16',
generate_audio: true,
});
if (job.status === 'completed') {
console.log('Video URL:', job.output?.video_url);
console.log('Credits used:', job.tchavi?.credits_used);
} else {
console.error('Failed:', job.error?.message);
}