fal Seedance
Use this skill when a task involves fal.ai Seedance, reference-to-video, image-to-video, or Seedance canaries for storyboard/style exploration.
Default Lane
- ref2v endpoint:
bytedance/seedance-2.0/reference-to-video(full quality, supports 1080p, multi-action shots, director-level camera control). Pass--endpoint bytedance/seedance-2.0/fast/reference-to-videofor the cheaper/faster variant when iterating on prompts cheaply. - i2v (image-to-video, deterministic start→end morph) supports both Seedance and Kling families:
- Seedance:
bytedance/seedance-2.0/image-to-video(default),bytedance/seedance-2.0/fast/image-to-video - Kling O3:
fal-ai/kling-video/o3/standard/image-to-video(clean baseline),fal-ai/kling-video/o3/pro/image-to-video(higher quality, recommended when standard output looks soft/weird),fal-ai/kling-video/o3/4k/image-to-video(highest tier) - Kling V3:
fal-ai/kling-video/v3/standard/image-to-video,fal-ai/kling-video/v3/pro/image-to-video - Kling endpoints don't accept
--resolutionor--generate-audio; the CLI strips them automatically. - Switch from Seedance to Kling when Seedance shows chroma-noise on smooth/cream backgrounds.
- Seedance:
- Default resolution:
1080p(Seedance only). Drop to720por480pfor cheaper canaries on the full endpoint, or use the fast endpoint (capped at 720p). - Secret lane: machine-local shared integration
fal - Secret mapping:
/Users/dobby/GitHub/scripts/sync/machine-secrets/fal.env.map - Generated secret file:
~/.secrets/fal/env - CLI:
python3 .agents/skills/fal-seedance/scripts/fal_seedance_ref2v.py(Python, uses the officialfal-clientPyPI SDK) - Client contract:
.agents/skills/fal-seedance/references/client.md
The CLI reads ~/.secrets/fal/env directly. Do not pass fal keys through flags, tracked files, or chat-visible shell commands.
If fal-client isn't installed: python3 -m pip install --user --break-system-packages fal-client.
Workflow
- Start with
--dry-runfor every new prompt or reference set. - Use
--project <id>so outputs stay underprojects/<id>/seedance/. - Pass local reference images with repeated
--ref; the CLI uploads them to fal CDN during real runs. - Refer to inputs in prompts as
@Image1,@Image2, etc. - For visual canaries, default to
--no-generate-audioand a restrained prompt. Resolution defaults to 1080p — drop to 720p or 480p (or use--endpoint .../fast/...) when iterating cheaply on prompts. - Keep each successful run's JSON receipt with the MP4; use the receipt to regenerate or compare drift.
Commands
Validate the local secret bootstrap:
python3 .agents/skills/fal-seedance/scripts/fal_seedance_ref2v.py validate
Verify fal provider connectivity without video inference:
python3 .agents/skills/fal-seedance/scripts/fal_seedance_ref2v.py doctor --remote
Dry-run a canary:
python3 .agents/skills/fal-seedance/scripts/fal_seedance_ref2v.py run \
--project <project-id> \
--name portrait-motion-canary \
--ref projects/<project-id>/storyboard/frame-01.png \
--prompt "Animate @Image1 as a calm studio portrait. Gentle smile, subtle breathing, one natural blink, tiny head turn, soft key light, locked camera, no face reshaping." \
--duration 4 \
--aspect-ratio 1:1 \
--dry-run
Run after the dry-run looks right by removing --dry-run.
Image-to-video (deterministic start→end morph) on Kling O3 Pro:
python3 .agents/skills/fal-seedance/scripts/fal_seedance_ref2v.py i2v \
--project <project-id> \
--name <beat-name> \
--start-image projects/<project-id>/keyframes/start.png \
--end-image projects/<project-id>/keyframes/end.png \
--endpoint fal-ai/kling-video/o3/pro/image-to-video \
--duration 5 --aspect-ratio 1:1 \
--prompt "<phased timing prompt>" \
--dry-run
Drop --dry-run to render. Use o3/standard for cheaper iterations and o3/pro once the prompt is locked and you want production quality. Long prompts can be passed via --prompt-file instead of --prompt.
Multi-reference storyboard canary:
python3 .agents/skills/fal-seedance/scripts/fal_seedance_ref2v.py run \
--project <project-id> \
--name anchored-portrait-motion \
--ref projects/<project-id>/storyboard/primary-frame.png \
--ref projects/<project-id>/storyboard/identity-anchor-01.png \
--ref projects/<project-id>/storyboard/style-anchor-01.png \
--prompt "Animate @Image1 as the primary frame. Use @Image2 and @Image3 only as identity and style anchors. Subtle breathing, one natural blink, tiny head turn, soft studio light, locked camera, no face reshaping, no outfit change." \
--duration 4 \
--aspect-ratio 1:1 \
--dry-run
Prompt Rules
- Use
@ImageNhandles, matching fal's Seedance schema. @Image1should usually be the primary frame to animate. Additional image refs should be described as identity, style, object, or environment anchors so Seedance does not treat them as a morph target by accident.- Explicitly assign every reference a role in the prompt: primary frame, character identity, style, outfit, environment, camera movement, action choreography, rhythm, or sound.
- Describe the exact camera move and the amount of motion.
- For identity canaries, explicitly say no age change, no outfit change, no face reshaping, and locked or near-locked camera.
- For longer clips, write timed segments (
[0-2s] ... [2-5s] ...). The full Seedance 2.0 endpoint handles continuous multi-action shots within one take (e.g. open object → camera dolly → action → state change). Reserve the "atomic canary, then stitch" approach for cases where the model demonstrably struggles with the continuous shot — don't pre-fragment by default. - For deterministic morph between two specific states (e.g. real photo → illustrated portrait), pass the start state as
@Image1(primary frame) and the target state as@Image2(style/end-state anchor). Describe the transformation explicitly in the prompt. - Do not copy Replicate examples directly; fal uses
image_urls/video_urls/audio_urlsand@Image1handles.
Output Contract
The CLI prints one JSON object to stdout by default:
status:okorerrordata.video.url: fal output URL on successdata.local_video.path: downloaded MP4 path when download is enableddata.receipt_path: JSON receipt patherror.code: stable error code on failure
Progress and provider logs go to stderr only.