Extensions/flux_3_api
ComfyUI Extension

flux_3_api

Flux 3 API

By DenRakEiw·Created about a month ago·Updated a day ago· 6
DenRakEiw/flux_3_api
Nodes3
On cloudLocal install
CategoryFlux3 API
Stars6
Updateda day ago
Readme

Flux 3 API — ComfyUI Nodes

ComfyUI nodes for the BFL Flux 3 video API, plus an LLM-powered prompt generator.

Nodes

  • Flux 3 Video (API) — generates video via POST https://api.bfl.ai/v1/flux-3-video (Docs, API reference).
  • Flux 3 Video Upscale (API) — super-resolution for short clips (≤20s, ≤50MB) via POST https://api.bfl.ai/v1/flux-tools/video-upscale-v1 (Docs, API reference). Precise mode preserves identity; creative mode enhances detail. Output capped at ~14.4 MP per frame; source audio preserved.
  • Flux 3 Openrouter Prompt — turns a vague idea into a structured FLUX 3 prompt using an OpenRouter LLM, guided by a prompting skill. Output feeds straight into the Video node's prompt input.

Setup

Add your keys to .env:

BFL_API_KEY=bfl_...
OPENROUTER_API_KEY=sk-or-...

Get an OpenRouter key at https://openrouter.ai/keys. Keys are looked up in this order: node api_key field → .env → environment variable.

Optional in .env:

BFL_BASE_URL=https://api.bfl.ai

(Default is https://api.bfl.ai; only change it if BFL announces a different host.)


Flux 3 Video (API)

Outputs: video (mp4, with audio track) and metadata. Feed straight into Save Video.

Modes (mode)

One mode per request; the rest of the request stays the same.

| mode | requires | does | |---|---|---| | t2v | – | Text → Video | | i2v | images (1–10) | Image(s) → Video (keyframes) | | v2v | video | Continue a clip (start_video) | | draft_enhance | draft_cache | Final-render a previous draft run |

Parameters

| Field | Required | Values | |---|---|---| | mode | always | t2v i2v v2v draft_enhance | | prompt | t2v/i2v/v2v | free-form | | keyframes | i2v | 1 image (opening frame) · 2 images (start+end) · 3–10 images (evenly spread, needs duration) · or [seconds, image] pairs (storyboard). URL or base64. | | start_video | v2v | mp4 URL or base64 | | draft_cache | draft_enhance | base64 bundle or URL from the draft output of a previous run | | aspect_ratio | – | auto (default), 21:9, 2:1, 16:9, 4:3, 1:1, 3:4, 9:16 | | duration | – | whole seconds 5–20 or auto (default) | | resolution | – | hd (default) or fhd | | generate_audio | – | bool, default true | | safety_tolerance | – | 0 (strictest) to 4, default 2. Capped at 2 when conditioning media is present. | | draft | – | bool. true = fast hd preview; result includes a draft_cache. | | version | – | latest (default) |

draft_enhance accepts only mode, draft_cache and safety_tolerance — the bundle pins mode, prompt, seed and conditioning. All other inputs are ignored (with a console warning).

i2v keyframes (ComfyUI UX)

The node translates ComfyUI inputs into the documented keyframes schema:

| what's connected | keyframe_times | sent | |---|---|---| | 1 image | – | "<base64>" (opening frame) | | 2 images or images+end_image | – | ["<a>", "<b>"] (start+end) | | 3–10 images | – | ["<a>", ...] (evenly spread — duration must be set) | | n images | n seconds | [[t1, "<a>"], ...] (storyboard — values ascending) |

metadata output (debug)

The STRING output contains everything about the run — meant for a Show Any node for debugging. Untruncated:

=== FLUX 3 VIDEO ===
endpoint       : POST https://api.bfl.ai/v1/flux-3-video
task_id        : e696c5eb-e97a-484f-9976-d7a5722658b2
polling_url    : https://api.bfl.ai/v1/get_result?id=e696c5eb-…

--- REQUEST (sent to the API) ---
mode           : i2v
prompt         : a seed grows into a tree through the seasons
duration       : 10
resolution     : hd
generate_audio : True
keyframes      : [[0, <base64, 412 KB>], [10, <base64, 398 KB>]]

--- RESPONSE (from the API) ---
sample         : https://delivery.bfl.ai/results/…

Base64 images/videos/bundles are rendered as a size rather than a megabyte-long string.


Flux 3 Video Upscale (API)

Super-resolution for short clips via POST /v1/flux-tools/video-upscale-v1. Outputs: video (mp4, source audio preserved) and metadata. Feed straight into Save Video.

Limits

  • Source max 20 s and 50 MB. Longer sources are rejected before processing (not truncated, no charge).
  • Output max ~14.4 MP per frame (4K and beyond). Very large sources get upscaled by less than the requested upscale_factor.
  • The source audio track is preserved in the output.

Parameters

| Field | Required | Values | |---|---|---| | video | yes (or input_video_url) | ComfyUI VIDEO input (mp4) | | target_resolution | yes | 1080p · 2K · 4K (default 4K). Target on the short side; the node computes the upscale_factor from the source dimensions | | input_video_url | – | HTTP(S) URL to the source; takes priority over video, saves base64-encoding a large clip. The node only streams the moov atom to measure source dimensions — no full download | | creativity | – | precise (0) or creative (1, default) — see modes below | | prompt | – | Optional description steering the enhanced detail (mostly in creative mode) | | safety_tolerance | – | 0 (strictest) to 4, default 2. Moderates the prompt and delivered frames | | timeout_minutes | – | default 45, up to 240 | | api_key | – | empty = from .env |

target_resolution and factor computation

The node measures the source dimensions and computes upscale_factor:

factor = target_short / min(source_w, source_h)

| target_resolution | Short-side target | ~16:9 output | |---|---|---| | 1080p | 1080 px | 1920×1080 | | 2K | 1440 px | 2560×1440 | | 4K (default) | 2160 px | 3840×2160 |

  • Source ≥ target (factor < 1.5): the node errors — there's nothing to upscale. Pick a higher target_resolution or a smaller source.
  • Factor > 3.0 (e.g. a 360p source targeting 4K): the node clamps to 3.0× and warns that the target isn't fully reachable. Effective short side ~source_short × 3.
  • BFL additionally caps output at ~14.4 MP per frame — very large sources end up below the target even at 4K.

Modes (creativity)

| Mode | Value | Behaviour | |---|---|---| | precise | 0 | preserves the source exactly and sharpens it. For faces, products, brand assets, real people. | | creative | 1 (default) | restores/invents fine detail more aggressively. For generated footage, textures, crowds, scenery. Identity (faces/products) can drift. |

Pricing

Per megapixel-second of delivered output (megapixels per output frame × output duration in seconds). You're charged for delivered output only — rejected clips cost nothing.

| Mode | Price | |---|---| | precise (creativity: 0) | $0.075 / MP·s | | creative (creativity: 1) | $0.105 / MP·s |

Roughly per second of output: 1080p $0.15 (precise) / $0.21 (creative), 2K $0.26 / $0.37, 4K $0.59 / $0.83.

Tips

  • Start from the least compressed source material — compression artifacts limit recoverable detail.
  • creative for generated footage/landscapes/textures; precise when faces/products/brand assets must stay exact.
  • Run upscaling as your final step, after editing/trimming, so you only pay for footage you keep.
  • The signed delivery URL expires ~1 h after Ready — download the video in time.

Queue / Timeout

The BFL queue can run well past 15 minutes for videos. ComfyUI itself has no execution timeout — it waits indefinitely. Only timeout_minutes caps it (default 45, adjustable up to 240).

If the time runs out, only the node aborts; the job keeps running at BFL and still costs credits. The error message therefore includes the polling_url, so the result can be fetched afterwards.

While waiting, the console logs status every minute so a long run doesn't look hung. The poll interval grows with wait time (2 s up to max 10 s) — over 25 minutes that's 201 instead of 750 requests.

Network hiccups: polling survives them. requests does no retries by default, so a single dropped keep-alive connection (RemoteDisconnected) would have killed an already-paid job. Now: up to 5 automatic retries per request (with backoff), and beyond that up to 10 consecutive failures before giving up. Only GETs are retried — a repeated POST could submit the job twice and double-charge. The finished-asset download is also retried up to 4×, since the signed result URL expires.

Parallel runs

The node is async (async def generate). ComfyUI recognises coroutine FUNCTIONs, parks a waiting node as PENDING and runs other nodes meanwhile. Multiple Flux nodes in one graph therefore generate simultaneously, not one after another — the wait time is that of the slowest clip, not the sum of all.

For this to hold, nothing may block the event loop: polling uses await asyncio.sleep(), and all blocking parts (HTTP requests, base64 encoding of images/videos) run via asyncio.to_thread(). A single time.sleep() in the wrong place would re-serialise the whole graph.


Flux 3 Openrouter Prompt

Turns a plain-words idea into a complete, structured FLUX 3 prompt using an OpenRouter LLM. No variants, no metadata — just the prompt, ready to paste into the Video node.

| Input | What it does | |---|---| | idea | Describe your video in plain words. | | model | OpenRouter model slug. The dropdown is filled live from the OpenRouter API; refresh ComfyUI to pick up new models. | | skill | Prompting skill that steers the LLM (see below). | | images | Optional: reference image(s) for vision-capable models (GPT-4o, Claude Sonnet, Gemini, …). | | model_custom | Optional: any OpenRouter slug not in the dropdown. | | api_key | Optional override; empty = from .env (OPENROUTER_API_KEY). | | extra_instructions | Optional directives appended to the skill. | | temperature | LLM sampling temperature (0–2). | | max_tokens | Max output tokens. | | timeout_seconds | How long to wait for the LLM. |

Output: prompt (STRING) — feed it into the Flux 3 Video node's prompt input.

Skills

Skills are .md files in the skills/ folder. Two are pre-installed:

  • Flux3Director — full structured prompting skill for FLUX 3 video (all modes, multi-segment timing, camera vocabulary, tag system).
  • Flux3Director4Discord — the same skill compressed for the FLUX3 Discord bot's 2,000-character hard limit.

Add your own: drop any .md file into the skills/ folder and refresh ComfyUI — it shows up in the skill dropdown automatically. Set skill to none for freeform prompting without a skill.