Purpose
The FAL.ai fallback for Higgsfield's nano_banana_2. Same Nano Banana model (Google Gemini 2.5 Flash Image) routed through fal's pay-per-call gateway. Used by:
video-orchestrator/create-clipsPhase 0 (cartoon style anchor)video-orchestrator/create-clipsPhase 1 (cartoon per-scene keyframes)video-orchestrator/lock-character(when ad uses cartoon-style character — rare)- The orchestrator's
generate_with_fallback.pyrouter on Higgsfield failure
Inputs identical to the Higgsfield path: prompt + optional reference image(s) → PNG out.
Pricing (as of 2026-05)
- $0.039 per image at 1k resolution (FAL Nano Banana). Cheaper than most fal image models.
- Pricing source: fal.ai/models/fal-ai/nano-banana
Inputs
Required:
prompt— text prompt. No brand text — same hard rule as the Higgsfield path; UI / wordmarks get composited in post.output_path— local PNG destination.
Optional:
aspect_ratio—9:16(default for ad pipeline),16:9,1:1, etc.resolution—1k(default) or2k.ref_image— one or more local image paths used as style/content reference. Uploaded to fal storage before generation.
Credentials:
FAL_API_KEY(orFAL_KEY) in.env.
Preflight
test -n "$FAL_API_KEY" || test -n "$FAL_KEY" || { echo "Missing FAL_API_KEY / FAL_KEY in .env"; exit 1; }
python3 -c "import fal_client" || pip3 install fal_client
Workflow
python3 skills/atoms/image-generation/create-image-nano-banana-fal/scripts/generate.py \
--prompt "..." \
--output /path/to/scene-NN.png \
--aspect-ratio 9:16 \
--resolution 1k \
[--ref-image /path/to/anchor.png ...]
The script:
- Loads FAL key via the shared
fal_helpers.load_fal_key(). - Uploads any
--ref-imagefiles to fal storage (returnshttps://v3.fal.media/...URLs). - Calls
fal_client.subscribe("fal-ai/nano-banana", {prompt, image_urls?, aspect_ratio, num_images: 1}). - Downloads the first result image to
--output. - Writes
<output>.meta.jsonwith{gateway: "fal", model: "fal-ai/nano-banana", request, image_url, cost_estimate, ...}.
Output
<output_path>— PNG (≥ 1 KB; smaller indicates an error payload was returned).<output_path>.meta.json— request + result metadata + cost.
Quality Checks
- Output file exists and is > 1 KB.
- Aspect ratio matches the request (use ffprobe or PIL to verify).
meta.jsonincludesgateway: "fal"andmodel: "fal-ai/nano-banana".- No readable text in the prompt that should appear in the image. Nano Banana mangles short brand text, URLs, code tokens, captions, and wordmarks even with explicit prompting. Examples observed:
"ffmpeg"→"ffmmg";"klarify"→"clarify";"therapists"→"therapits". Use PIL orffmpeg drawtextfor any overlay containing readable text. Reserve image gen for purely visual content (characters, scenes, backgrounds). Repeats LEARNINGS L4.
Failure Modes
| Symptom | Likely cause | Fix |
|---|---|---|
401 Unauthorized |
Bad / missing FAL_API_KEY |
Verify env var. |
429 Too Many Requests |
Account RPS limit | Drop concurrency to 2-3. |
403 Forbidden on storage/auth/token |
Exhausted FAL balance — persists through cooldowns; not a rate limit | Top up at fal.ai/dashboard/billing, then re-run. Distinguish from 429 (true rate limit, which backs off cleanly). |
| Image returns gibberish text | Asked Nano Banana to render brand text | Strip brand text from prompt; overlay in post via PIL. |
| Output drifts from style anchor | Reference image style is ambiguous | Upload a stronger anchor; adjust prompt to call out style verbatim. |
When this fires
This atom is called by the orchestrator's generate_with_fallback.py router when the primary Higgsfield path fails. It can also be called directly by passing <provider_override>=fal to create-clips or lock-character. Otherwise the Higgsfield path is preferred.
References
- fal.ai/models/fal-ai/nano-banana
- Sibling Higgsfield path:
mcp__higgsfield__generate_imagewithmodel="nano_banana_2" - Shared helpers:
skills/atoms/_shared/fal_helpers.py