The official endpoint
BFL documents POST https://api.bfl.ai/v1/flux-3-image-klein with an x-key header and a JSON body. The prompt is required. For a simple text request, explicitly set aspect_ratio and resolution. For editing, include the reference in images. Keep the API key on your server rather than shipping it to the browser.
This guide combines the official endpoint specification with the queue and credit-accounting design in this project. Documentation was checked on October 19, 2026. The code is illustrative; this article does not report a live paid API run, measured latency, or tested output quality.
Choose request parameters deliberately
| Field | Example | Decision it controls |
|---|---|---|
prompt | A scene description or edit instruction | Required creative input |
aspect_ratio | 4:3 | The output's shape; choose it for the destination layout |
resolution | 1k | An equal-area size tier, not a promise that every edge is 1024 pixels |
images | An array containing a reference URL or base64 image | Optional reference input; the endpoint documents up to 10 |
seed | A recorded integer | Optional on this Klein endpoint; omitted means random |
output_format | png | File format; the documented default is jpeg |
The endpoint also supports exact width and height, which override both the ratio and resolution tier. Avoid sending those dimensions accidentally alongside settings that your UI presents as authoritative. For an edit, explicitly choosing a ratio also differs from preserving the reference's original shape.
Treat generation as an asynchronous task
The initial response contains an id and polling_url. Persist both before doing anything else. Query the returned polling URL, rather than constructing a different host yourself, and map upstream statuses to your own task states. Keep generation independent of the browser tab so a page refresh does not submit a second request.
Download the result promptly
BFL’s integration guide says delivery URLs expire after 10 minutes and are intended to be downloaded and served through your own infrastructure. Once a result is Ready, save the image into private object storage, store its object key in PostgreSQL, and issue short-lived access links to the image owner. Do not mark your own task complete until that storage step succeeds; otherwise a user can return to a completed task whose only image link has expired.
Resolution and published costs
The published Klein prices, checked on October 19, 2026, give the following simple image-budget calculation:
| Resolution tier | Published API price per image | Arithmetic estimate for 100 images |
|---|---|---|
| 768sq | $0.008 | $0.80 |
| 1K | $0.009 | $0.90 |
| 1.5K | $0.011 | $1.10 |
| 2K | $0.014 | $1.40 |
| 4K | $0.036 | $3.60 |
The last column is multiplication of the published rate, not an observed bill. It excludes storage, delivery, application hosting, and other service costs. Editing and text generation share the published rate. These are BFL API costs, not Flux3Klein.dev credit-pack prices. Verify current rates and billing terms before budgeting a live integration.
Retries and credit accounting
Reserve user credits in the same database transaction that creates the task. A repeat submission key should point to the same task. If submission times out after the request might have reached BFL, mark it for reconciliation instead of blindly submitting again. Settlement and refunds should be idempotent, with an audit trail of balance changes.
A small integration checklist
Validate prompts and images, enforce per-account limits, check ownership on every asset route, and limit downloads to trusted provider hosts. Handle moderation responses and confirmed errors explicitly. Record actual upstream cost separately from your product’s credits. Test real latency and failure behavior with your own account before promising service levels.
A minimal server-side request
The following example shows the submission part of a text-to-image request. Run it only on a server with BFL_API_KEY configured. Running it sends a real generation request; a complete integration also needs the persistence and polling steps described above.
const apiKey = process.env.BFL_API_KEY;
if (!apiKey) throw new Error("BFL_API_KEY is not configured");
const response = await fetch("https://api.bfl.ai/v1/flux-3-image-klein", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-key": apiKey,
},
body: JSON.stringify({
prompt: "A small ceramic teapot in soft morning window light",
aspect_ratio: "4:3",
resolution: "1k",
}),
signal: AbortSignal.timeout(30_000),
});
if (!response.ok) throw new Error(`BFL submission failed: ${response.status}`);
const task = await response.json();
if (typeof task.id !== "string" || typeof task.polling_url !== "string") {
throw new Error("Unexpected BFL submission response; reconcile before retrying");
}
// Persist task.id and task.polling_url before polling.
// A timeout after submission needs reconciliation before retrying.
Integration checks before launch
| Check | Expected behavior |
|---|---|
| Repeat submission key | The same task is returned and credits are reserved once. |
| Confirmed provider failure | The task fails and the original reservation is refunded once. |
| Ambiguous submission timeout | The task is held for reconciliation before another paid request. |
| Image access | Every download checks the requesting account's ownership. |
For the creative side of the workflow, see the prompt guide. Browse the model overview for the distinction between model capabilities and this workspace's current interface.
Sources & further reading
Klein API reference Integration and delivery URLs Current official Klein pricingOfficial documentation checked on . Features, prices, and terms may change.
Put your next idea to work.
Take a starting point into the image generator, then make it yours.
Start creating

