BFL API request pattern
Every BFL FLUX generation / edit / fill / expand endpoint follows the same async shape. This skill documents it, and points to the existing implementation in BaseFlux (nodes/base.py).
You should not write a new copy of this pattern. The base class already implements it. This skill exists to (a) explain the existing flow to humans and (b) handle the rare case where a new endpoint needs a one-off variant (e.g. multipart upload, streaming response).
The flow
- POST to
<BASE_URL>/<endpoint>with body JSON. Headers:x-key: <API_KEY>,Content-Type: application/json. - Response:
{ "id": "<task_id>" }(or an error JSON if BFL rejects). - Poll: GET
<BASE_URL>/get_result?id=<task_id>every 5 s, max 40 attempts (~200 s ceiling). Headers: samex-key. - Status enum (
nodes/status.py):"Pending"→ retry."Ready"→ response containsresult.sampleURL — download, convert to PIL, then tensor."Error"/"Content Moderated"/"Request Moderated"→ terminal failure; return blank 512×512 black image."Task not found"→ shouldn't happen mid-flow; treat as terminal.
- Image download & convert (
BaseFlux.process_result):- GET the
result.sampleURL (no auth needed; it's a signed S3-style URL). - Open with PIL.
- Re-encode in the requested
output_format(jpeg/png). - Convert to numpy float32 array
/ 255.0. - Wrap in torch tensor with leading batch dim:
torch.from_numpy(arr)[None,]. - Return as a 1-tuple matching
RETURN_TYPES = ("IMAGE",).
- GET the
Where this lives
| Step | Location |
|---|---|
| Build URL from base + path | nodes/config.py:44-65 (ConfigLoader.create_url) |
| POST + curl print | nodes/base.py:50-73 (BaseFlux.post_request) |
| Poll loop | nodes/base.py:75-133 (BaseFlux.get_result) |
| Image → tensor | nodes/base.py:19-38 (BaseFlux.process_result) |
| Graceful failure tensor | nodes/base.py:40-44 (BaseFlux.create_blank_image) |
| Dimension check | nodes/base.py:46-48 (BaseFlux.check_multiple_of_32) |
| Status enum | nodes/status.py |
Headers
headers = {"x-key": config_loader_instance.get_x_key()}
That's it. No Authorization: Bearer, no signed tokens. The x-key value is whatever's in config.ini X_KEY (or the override from FluxConfig_BFL).
curl-equivalent print
Every outbound POST prints a copy-pasteable curl command before sending. Pattern from nodes/base.py:60-62:
headers_str = " \\\n ".join(f"-H '{k}: {v}'" for k, v in prepared.headers.items())
print(f"[BFL] curl -X POST '{prepared.url}' \\\n {headers_str} \\\n -d '{body}'")
This is intentional. Users who hit BFL errors paste the curl into a terminal to confirm whether the issue is the request or the response handling.
Caveat: this prints the x-key header. That's a known trade-off — the user is the only one looking at their own console. Do not log this header value to a file or send it anywhere.
Regional endpoints (finetune only)
Default BASE_URL is https://api.bfl.ai/v1/ and does NOT serve finetune routes. Finetune endpoints live at:
https://api.us.bfl.ai/v1/<path>https://api.eu.bfl.ai/v1/<path>
ConfigLoader.create_url(path, region=...) (nodes/config.py:44-65) picks the right base. Region comes from FluxConfig_BFL's region field or from the per-call argument.
When you'd need to deviate from BaseFlux
You should reuse BaseFlux unless the endpoint:
- Uses multipart/form-data (not currently a thing in BFL).
- Streams the response (not currently a thing in BFL).
- Returns a non-image result that doesn't fit the
IMAGEtensor (seeFluxCreditsinnodes/api_node.py— utility node, doesn't inherit BaseFlux, callsrequests.getdirectly). - Polls at a different interval (BFL doesn't currently require this).
If you really do need a one-off, mirror the existing patterns:
- Print
[BFL] curl ...before any outbound request. - Print
[BFL] <status>lines. - On any exception or terminal status, return
self.create_blank_image()(ifBaseFluxsubclass) or an equivalent safe value.
What this skill does NOT do
- Does NOT write a new copy of
post_request/get_result. The base class is the single source of truth. - Does NOT change polling timing without explicit user ask.
- Does NOT log the
x-keyvalue to anywhere other than the user's console.
Source: gelasdev/ComfyUI-FLUX-BFL-API — distributed by TomeVault.