Kling v3: image to video
Give it a first frame, a prompt, optionally a last frame and up to three elements
(reference pictures of a character or a product); get a 1080p clip that opens exactly
on the frame (frame 0 at about 0.996 SSIM) with smooth motion (jerk about 0.05, like
source footage). It is the dependable middle option: low-to-mid priced, steady on simple
motion, and it keeps photographic texture where H3 Max and Flux 3 Max smooth it, so
reach for it on close-ups with simple motion. It wins no single category: H3 Max is
faster, and Seedance does complex motion and native 1080p realism. For paper, cloth or liquid in the air, use
seedance-2-5-image-to-video; for fast, cheap drafts, h3-max-image-to-video; to keep
an existing take's performance, h3-max-recast.
Inputs
- The first frame at the output size: 1920×1080 for 16:9 (
python-conform-to-1080pfrom a 2K still). - A last frame (optional) to force an end pose the model keeps skipping. It must be
continuous with the first (hair, cuffs, props, eyes): derive it from the locked first
frame (
nano-banana-derive-last-frame), never edit the two independently, and crop it to the source's push-in when the shot has one (python-match-push-in), or the clip loses the push-in. Look at the two back to back before rendering. - Elements (optional): per character or product, a frontal picture plus 1 to 3 more views. Use single views cut from a character sheet, not the whole sheet. For a product in a busy shot, use a crop of the source frame's prop or a pre-hazed product photo (lower contrast, warm, slight blur and grain), never a raw studio photo.
- The shot's length in frames and fps.
Run it
Call describe("fal/fal-ai/kling-video/v3/pro/image-to-video") before the first run in
a job. Before that first run, a test included, show the person the still that will move
and ask (core skill: the person decides every look).
run("fal/fal-ai/kling-video/v3/pro/image-to-video", {
"start_image_url": "<job>/video/shot08_first_1080p.jpg",
"end_image_url": "<job>/video/shot08_last_1080p.jpg",
"prompt": "<Kling prompt, see below>",
"duration": "4",
"generate_audio": true,
"elements": [
{"frontal_image_url": "<job>/refs/nora_front.jpg",
"reference_image_urls": ["<job>/refs/nora_three_quarter.jpg", "<job>/refs/nora_profile.jpg"]},
{"frontal_image_url": "<job>/refs/tumbler_hazed.jpg",
"reference_image_urls": ["<job>/refs/tumbler_hazed.jpg"]}
]
}, into="<job>/video/raw", unit="shot08_kling", tag="shot08")
- The first frame is
start_image_url, notimage_url: fal silently drops a field the schema doesn't declare, and the clip comes back unpinned. durationis a string,"3"to"15"whole seconds: the shot's length rounded up, at least 3.- No
seedand noresolution: Pro renders 1080p, and takes differ by sampling alone. Run 3 takes per shot as separate calls. elementsin the same order as the prompt's@Element1,@Element2; at most 3, each with at most 4 pictures. Every element needs at least one reference besides the frontal one, so a single picture fills both slots.- Element pictures must be 300 to 2,048 px a side with an aspect between 0.4 and 2.5, or fal rejects the whole request. Pad an image that is out of range with its most common edge colour; never crop (a wide logo loses its lettering).
generate_audiogives the clip its own sound effects. A shot cut over the source's soundtrack drops them at the edit; leave narration and music out of the prompt.
Prompt
Load kling-v3-prompt-format first. For this mode:
- Real time, then hold. Every model spreads the action over the whole clip, even when told to finish early. When the clip runs longer than the shot, open the direction with: "The shot's action lasts 2.1 seconds; play it at natural real-time speed, then hold the final moment with only small natural movement until the clip ends."
- Spell out counts and amounts: "blinks exactly once", "lowers it a third of the way, base below her chin", "walks left in profile, never turning toward the camera". Unqualified, Kling doubles the blink, overshoots the lift and turns people to camera.
- With a pinned last frame, describe the end pose it shows.
What you get
An MP4 at 1080p, at least 3 s, opening on the first frame. Kling idles in the opening pose before acting, even with "inside the first second", so the action often starts some frames in.
Tips and traps
- Trim, never speed up. Retiming a clip to fit reads badly. Pick the trim's start
from a frame strip of the opening to skip the idle (0 to 24 frames on a 24 fps shot),
then cut to the shot's length (
ffmpeg-frame-exact-trim). A shot file keeps a 0.5 s tail; the cut uses the exact length. Keep the untrimmed render inraw/. - A pinned last frame lands at the end of the whole clip, so trimming to the shot stops short of it. When the end pose must be on screen and the clip runs long, the only way to reach it is speeding up, which reads badly; drop the last frame and spell the beat out step by step instead (an explicit lift, beat by beat, won that shot).
- On a slow connection, queue takes one at a time: each request uploads megabytes of images.
Check it
- Frame 0 against the first frame, and the last frame against the pinned end:
python-check-pinned-frames(frame_alignment, not raw SSIM). - Judder:
python-measure-judder(source footage about 0.05). - Then put the takes on a review page beside the original shot.


