Nodes/comfyui-jz/jz fal Image
ComfyUI Node

jz fal Image

1,500 fal models inside your own graph, checked before they bill you

By j-zhang19·Created 3 months ago·Updated 14 days ago· 3
jz fal Image
  • image
  • images
  • urls
  • info
◄modelfal-ai/flux/schnell►
◄prompta photo of a cute dog►
◄params{}►
◄custom_model►
◄api_key►
◄poll_timeout900►
◄poll_interval3►

What it's actually for

You have a graph that works. Then one step needs a model that isn't on your disk - Nano Banana Pro for a relight, flux.2-pro for a version you can't download, or frankly any Flux at all because your card is a 2060. jz fal Image is a single HTTP client that calls fal.ai and drops the result back into your graph as a normal IMAGE, indistinct from anything a local sampler produced.

The reason to use this instead of Comfy's own Partner Nodes is boring and real: your billing. The official API nodes run on prepaid Comfy credits, which is the usual complaint whenever someone wants to drive a closed model with their own fal account. This node uses your key, your balance, your dashboard.

How it works

fal runs asynchronous jobs through a queue API, and the node walks the whole thing for you: POST https://queue.fal.run/{model} returns a request_id plus status and response URLs, the node polls the status URL (IN_QUEUE → IN_PROGRESS → COMPLETED), then fetches the finished payload and downloads each image URL into an IMAGE batch. Auth is Authorization: Key <FAL_KEY>. poll_timeout defaults to 900 seconds, polling every 3.

Here's the part that makes it worth using over a five-line Python node. fal has roughly 1,500 endpoints and they all take different arguments, so model-specific options live in a params JSON widget rather than a fixed set of widgets. What keeps that from being a minefield: fal publishes every model's OpenAPI schema, free and unauthenticated, so the node validates your params against the real schema before anything billable is sent. A typo'd key, a bad enum value, a missing required field or the wrong type raises locally and prints what the model actually accepts. On an API with no published schema you'd discover the same typo by paying for it.

The inputs that matter

  • model - a curated shortlist (schnell, dev, nano-banana-pro and its edit variant) pinned above fal's live catalogue. The list is cached to a gitignored models_cache.json for 24 hours and refreshed on a background thread, so a slow fal can't stall ComfyUI startup.
  • prompt - plain text. One trap: the node does args.setdefault("prompt", ...), so a "prompt" key inside params wins and your widget is quietly ignored.
  • params - the real API surface. {"image_size": "landscape_16_9", "num_images": 2} is the author's example.
  • custom_model - any endpoint id, used when model is custom. Empty custom raises.

Wire an image in and the schema decides how it's sent: a model declaring image_urls gets every frame of the batch, one declaring image_url gets the first (with a console note if you sent more), and a text-to-image model that declares neither gets a clear error instead of an argument it would reject. Both image and batch inputs work - a batch or a LIST is one call either way.

Outputs: images (the batch), urls (fal-hosted, newline-joined) and info (the rest of the result as JSON). Unlike the pack's OpenAI node there's no dollar figure here - check the fal dashboard for that.

Install

ComfyUI Manager → search comfyui-jz. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/j-zhang19/comfyui-jz

Restart. Nothing to download and nothing heavy to install: the pack's only declared dependencies are requests, pillow and numpy, all already in ComfyUI. There's no fal_client dependency - the queue client is this pack's own code, which is why it can't drift out of sync with a package bump.

For the key, put FAL_KEY=... in a .env at the pack root, or [FAL] api_key=... in config.ini (both gitignored, so a pull won't clobber them). Leave the api_key widget empty - anything typed there is saved inside the workflow JSON you'll eventually share. Resolution order is widget → env var → .env → config.ini.

One aside: an API node is a custom node that holds a credential and calls the network by design, and this ecosystem has already had one of those ship credential-stealing malware. This pack is small and depends on nothing unusual - but install it from the Manager listing, not a stranger's zip.

Where people get burned

  • Timeouts are cancellable, and the node cancels. fal supports it, so a job that outruns poll_timeout (max 7200) gets killed rather than left running and charging - but the job is dead once it trips.
  • The submit is never retried. Deliberate: these POSTs are billable, and a retry whose first attempt actually landed queues a second job.
  • Cost adds up quietly. fal is metered per call and an empty balance simply stops generating. A schnell draft is nothing; a nano-banana-pro pass at n images is a different conversation.
  • No model in the dropdown? Your 24h cache may predate it, or fal's catalogue page filter missed it. Set model: custom, paste the endpoint id in custom_model, and you skip the list entirely.
Categoryjz/api

Inputs (8)

NameTypeDefaultDescription
modelCOMBOfal-ai/flux/schnell5 options: fal-ai/flux/schnell, fal-ai/flux/dev, fal-ai/nano-banana-pro, fal-ai/nano-banana-pro/edit, custom
promptSTRINGa photo of a cute dog—
paramsSTRING{}model-specific arguments as json, e.g. {"image_size": "landscape_16_9", "num_images": 2}. checked against the model's schema before anything is billed; the console prints what it accepts
imageoptIMAGEreference image(s) for editing
custom_modeloptSTRINGany fal endpoint id, used when model is custom
api_keyoptSTRING—
poll_timeoutoptINT90030–7200—
poll_intervaloptINT31–30—

Outputs (3)

NameTypeDescription
imagesIMAGE—
urlsSTRING—
infoSTRING—