The CLI exposes six subcommands: animate, models, loop, prep, fetch, extend.
Global flags (before the subcommand):
| Flag | Description |
|---|---|
-v, --verbose |
Enable DEBUG-level logging — shows full API payloads (image URL redacted). |
Run the full pipeline: prepare the poster image → upload → generate video → post-process into a seamless loop.
python postanimate_cli.py animate <image> [options]
Positional
| Arg | Description |
|---|---|
image |
Path to the poster image file (jpg, jpeg, png, webp — others converted to JPEG). |
Core options
| Flag | Default | Description |
|---|---|---|
-p, --prompt |
"" |
Motion description. See the Prompt Guide. |
-n, --negative-prompt |
"blurry, distorted, low quality, jittery" |
Elements to avoid (Kling / generic support). |
--model |
kling (or PIAPI_MODEL) |
One of kling, luma, hunyuan, hailuo, wan, wan2.6, veo3, veo3.1, skyreels, framepack, seedance. |
--loop-mode |
crossfade |
crossfade, boomerang, or none. |
--crossfade |
1.0 |
Seconds of crossfade blend at the loop point. |
--num-loops |
1 |
Number of loop repetitions baked into the output file. |
--duration |
5 |
Clip length in seconds. Valid values depend on model (see Models). |
--skip-prep |
off | Skip image preparation (use the image as-is). |
--name |
input stem | Base name for output files. |
-o, --output-dir |
output/ |
Destination directory for all output files. |
--env |
.env |
Path to an alternate .env file. |
Kling-specific
| Flag | Default | Description |
|---|---|---|
--version |
2.6 (or KLING_VERSION) |
1.5, 1.6, 2.1, 2.1-master, 2.5, 2.6. |
--mode |
std (or KLING_MODE) |
std (standard, cheaper) or pro (professional, higher quality). |
--cfg-scale |
0.5 (or KLING_CFG_SCALE) |
Prompt adherence, 0.0–1.0. Lower = more subtle. |
--tail-image |
(none) | Path to an end-frame image for pseudo-looping. Pass the same poster for a return-to-start effect. |
Luma-specific
| Flag | Default | Description |
|---|---|---|
--luma-loop |
off | Request Luma's "native loop". In practice the model appears to just reverse the first half of the clip — equivalent to a built-in boomerang. Skips crossfade post-processing when set. |
--aspect-ratio |
3:4 |
16:9, 9:16, 1:1, 3:4, 4:3, or 21:9. Also applies to Hunyuan. |
Hunyuan-specific
| Flag | Default | Description |
|---|---|---|
--hunyuan-mode |
replace |
replace (faithful to source) or concat (more creative motion). |
Show model details and examples.
python postanimate_cli.py models # summary table of every model
python postanimate_cli.py models <name> # deep-dive on one model
| Arg | Description |
|---|---|
name (optional) |
One of the 11 model keys. Omit for a summary table. |
See Models for the full written-up guidance on each model.
Apply crossfade or boomerang post-processing to a video you already have (e.g. a previous raw render).
python postanimate_cli.py loop <video> [options]
| Flag | Default | Description |
|---|---|---|
video |
(required) | Path to the input video. |
--loop-mode |
crossfade |
crossfade or boomerang. |
--crossfade |
1.0 |
Crossfade duration in seconds. |
--num-loops |
1 |
Number of loop repetitions in the output. |
-o, --output |
(auto) | Output path. Defaults to <input>_loop.mp4 / _boomerang.mp4. |
Resize and pad/crop a poster to the 27:40 ratio at your chosen resolution. Useful for inspecting what PostAnimate will actually send to the API.
python postanimate_cli.py prep <image> [options]
| Flag | Default | Description |
|---|---|---|
image |
(required) | Path to the poster image. |
-o, --output |
(auto) | Output path. Defaults to <input>_prepared.jpg. |
--resolution |
1920 |
Target pixel count for the long side. Width is computed from the 27:40 ratio. |
--fit |
contain |
contain (letterbox with black bars), cover (crop to fill), stretch (distort to fit). |
Grab the final video for a previously submitted task (e.g. if the polling timed out or you want to re-download).
python postanimate_cli.py fetch <task_id> [options]
| Flag | Default | Description |
|---|---|---|
task_id |
(required) | The PiAPI task ID. |
-o, --output |
output/<task_id>.mp4 |
Output path. |
--env |
.env |
Path to an alternate .env file. |
Kling-only. Submit one or more extend_video tasks chained from an existing completed clip. Currently unreliable on PiAPI (often returns 500) — see Troubleshooting.
python postanimate_cli.py extend <task_id> [options]
| Flag | Default | Description |
|---|---|---|
task_id |
(required) | Task ID of the completed video to extend. |
--times |
1 |
Number of extensions to chain. Each extension adds ~5 s. |
-p, --prompt |
"" |
Motion description for the extended portion. |
-n, --negative-prompt |
"blurry, distorted, low quality, jittery" |
Elements to avoid. |
--mode |
(from config) | Override quality mode. |
--version |
(from config) | Override Kling version. |
-o, --output |
(auto) | Output file path. |
--env |
.env |
Path to an alternate .env file. |
# Default — Kling, 5 s, crossfade loop
python postanimate_cli.py animate input/poster.jpg \
-p "subtle floating particles, gentle light flickers"
# Kling pro mode, 10 s clip, tighter prompt adherence
python postanimate_cli.py animate input/poster.jpg \
--model kling --mode pro --duration 10 --cfg-scale 0.4 \
-p "flickering flames, embers floating upward"
# Kling with tail-image pseudo-loop (pass same image as start and tail)
python postanimate_cli.py animate input/poster.jpg \
--tail-image input/poster.jpg \
-p "slow drifting fog"
# Luma — solid atmospheric alternative to Kling
python postanimate_cli.py animate input/poster.jpg \
--model luma --aspect-ratio 3:4 \
-p "atmospheric particle effects"
# Hailuo, 6 s natural motion
python postanimate_cli.py animate input/poster.jpg \
--model hailuo --duration 6 \
-p "gentle rain falling, fog drifting"
# Hunyuan, faithful-to-source replace mode
python postanimate_cli.py animate input/poster.jpg \
--model hunyuan --hunyuan-mode replace \
-p "subtle ambient motion"
# Veo 3 — premium hero render
python postanimate_cli.py animate input/poster.jpg \
--model veo3 --duration 8 \
-p "cinematic light rays, drifting dust motes"
# FramePack — 20 s ambient clip at $0.03/sec
python postanimate_cli.py animate input/poster.jpg \
--model framepack --duration 20 \
-p "slow drifting mist, gentle light shifts"
# Wan — cheapest iteration loop
python postanimate_cli.py animate input/poster.jpg \
--model wan \
-p "slow dramatic camera push-in"
# Seedance — character-heavy poster
python postanimate_cli.py animate input/poster.jpg \
--model seedance --duration 10 \
-p "subtle breathing, hair moving in breeze, fabric rustling"
# Boomerang loop (forward+reverse) — guarantees seamless loop
python postanimate_cli.py animate input/poster.jpg \
--loop-mode boomerang \
-p "slow dramatic zoom"
# Skip image prep, custom output name + directory, 3 loops baked in
python postanimate_cli.py animate input/poster.jpg \
--skip-prep --name hero_01 -o output/campaign --num-loops 3 \
-p "ambient glow pulsing"
# Verbose mode (DEBUG logs, full API payload)
python postanimate_cli.py -v animate input/poster.jpg \
-p "subtle particles"
# Model info
python postanimate_cli.py models
python postanimate_cli.py models framepack
# Re-loop an existing raw video with a longer crossfade
python postanimate_cli.py loop output/poster_raw.mp4 --crossfade 1.5
# Boomerang an existing video, 3 cycles
python postanimate_cli.py loop output/poster_raw.mp4 \
--loop-mode boomerang --num-loops 3
# Prep a poster without generating
python postanimate_cli.py prep input/poster.jpg # letterbox
python postanimate_cli.py prep input/poster.jpg --fit cover # crop to fill
python postanimate_cli.py prep input/poster.jpg --resolution 1080 # smaller output
# Fetch a completed task by ID
python postanimate_cli.py fetch 5f3a...abcd -o output/video.mp4
# Extend a Kling task 3 times (~15 s added total)
python postanimate_cli.py extend 5f3a...abcd --times 3 \
-p "continued drifting motion"