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

FieldExampleDecision it controls
promptA scene description or edit instructionRequired creative input
aspect_ratio4:3The output's shape; choose it for the destination layout
resolution1kAn equal-area size tier, not a promise that every edge is 1024 pixels
imagesAn array containing a reference URL or base64 imageOptional reference input; the endpoint documents up to 10
seedA recorded integerOptional on this Klein endpoint; omitted means random
output_formatpngFile 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 tierPublished API price per imageArithmetic 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

CheckExpected behavior
Repeat submission keyThe same task is returned and credits are reserved once.
Confirmed provider failureThe task fails and the original reservation is refunded once.
Ambiguous submission timeoutThe task is held for reconciliation before another paid request.
Image accessEvery 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 pricing

Official 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
Back to the blog