# FLUX.3 Klein Image Editing API

> FLUX.3 Klein-editor med op til 10 referencer og valgfri objektplacering via afgrænsningsbokse

Redigerer eller sammensætter billeder fra en prompt og 1 til 10 referencer i `image_urls`, som prompten kan henvise til efter rækkefølge, f.eks. det første billede. Op til 32 `bounding_boxes` kan fastholde, flytte, ændre størrelse på, fjerne eller tilføje objekter, der navngives med en etiket i prompten. Promptudvidelse er aktiveret som standard. Den returnerer 1 til 4 billeder i jpeg, png eller webp.

- Model id: `blackforestlabs/flux-3/klein/edit-image`
- Made by: Black Forest Labs
- Category: Image Editing
- Output: image
- Price per run: from $0.008 / run of output image (cheapest run $0.008 (8 API credits))
- Run: `POST https://api.doitong.com/v1/run/blackforestlabs/flux-3/klein/edit-image`
- Quote: `POST https://api.doitong.com/v1/quote/blackforestlabs/flux-3/klein/edit-image`
- Docs page: https://doitong.com/da/developers/models/blackforestlabs/flux-3/klein/edit-image

## Pricing

Price: **from $0.008 / run of output image** (the lowest tier; the quote prices your exact input). Price per run: the input files are measured before the run (length, resolution, frame rate). The quote measures the same files and is exactly what the run charges.

The full example input below costs $0.009 = 9 API credits (1 run × $0.009).

Prices are the upstream price in USD, paid from the API balance in API credits (1000 API credits = 1 USD). `POST https://api.doitong.com/v1/quote/blackforestlabs/flux-3/klein/edit-image` with the same JSON body returns the exact price for that input; the quote is exactly what a run charges. Invalid input is never charged and failed or canceled requests are refunded automatically.

## Input parameters

Send either the canonical name or the native field name (not both). Canonical names are the same across models.

| Parameter | Canonical name | Type | Required | Default | Allowed values / range | Description |
|---|---|---|---|---|---|---|
| `prompt` |  | string | yes |  |  | Skriv en komplet billedtekst, der beskriver det ønskede billede efter redigering, og identificer eventuelle referencer efter rækkefølge, f.eks. det første eller andet billede. |
| `enable_prompt_expansion` |  | boolean | no | `true` |  | Promptudvidelse til en detaljeret billedtekst før generering, aktiveret når værdien er true. Ved redigering forankres billedteksten i referencebillederne. |
| `seed` |  | integer \| null | no |  |  | Seed til reproducerbare billeder: En identisk prompt og seed producerer et identisk billede, når modelversionen er uændret. |
| `num_images` | `num_outputs` | integer | no | `1` | 1 – 4 | Antal billeder, der ønskes genereret. |
| `enable_safety_checker` |  | boolean | no | `true` |  | Aktivering af sikkerhedskontrol; true aktiverer kontrollen. |
| `output_format` |  | enum (string) | no | `png` | `jpeg`, `png`, `webp` | Filformat for det resulterende billede. |
| `image_urls` | `images` | array of image URL | yes |  | 1 – 10 items | Referencebilleder brugt til redigering eller komposition, begrænset til 10. |
| `image_size` |  | object {width, height} \| enum (string) \| null | no |  | `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9` | Outputdimensioner er som standard det første references dimensions, begrænset til 1 megapixel for flere referencer eller skaleret til højst 4 megapixel for en enkelt reference. Eksplicitte størrelser skal have hver side mellem 256 og 4096 pixels. |
| `bounding_boxes` |  | array of object {label, description, box, source_image_index, source_box, target_box} \| null | no |  | ≤ 32 items | Valgfrit objektlayout til at bevare, flytte, ændre størrelse på eller fjerne referenceobjekter eller placere nye objekter. Koordinater starter ved (0, 0) i hvert billedes øverste venstre hjørne; henvis til bokse med labels i prompten, f.eks. `<dragon>`. |
| `bounding_boxes[].label` |  | string \| null | no |  | ≤ 64 characters | Kort objektlabel til boksen, f.eks. `dragon`; standarden er `obj_<n>`. Inkluder `<dragon>` i prompten for at knytte dens ord til boksen; bokse, der ikke nævnes i prompten, føjes til scenen. |
| `bounding_boxes[].description` |  | string | yes |  | ≤ 500 characters | Objektet, der skal gengives i boksen, inklusive dets udseende. |
| `bounding_boxes[].box` |  | object {x_min, y_min, x_max, y_max} \| null | no |  |  | Outputplacering for objektet, der erstatter `source_box`/`target_box` og bruger samme placeringsadfærd som tekst-til-billede. |
| `bounding_boxes[].box.x_min` |  | number | yes |  | 0 – 1 | Venstre grænse udtrykt relativt til billedets bredde fra 0 til 1. |
| `bounding_boxes[].box.y_min` |  | number | yes |  | 0 – 1 | Øvre grænse udtrykt relativt til billedets højde fra 0 til 1. |
| `bounding_boxes[].box.x_max` |  | number | yes |  | 0 – 1 | Højre grænse udtrykt relativt til billedets bredde fra 0 til 1. |
| `bounding_boxes[].box.y_max` |  | number | yes |  | 0 – 1 | Nedre grænse udtrykt relativt til billedets højde fra 0 til 1. |
| `bounding_boxes[].source_image_index` |  | integer \| null | no |  | ≥ 0 | Valg af objektkilde: udelad for et nyt objekt, eller identificer en eksisterende reference via dens indeks i `image_urls`, talt fra 0. |
| `bounding_boxes[].source_box` |  | object {x_min, y_min, x_max, y_max} \| null | no |  |  | Objektets placering i referencebilledet; `source_image_index` skal også angives. |
| `bounding_boxes[].source_box.x_min` |  | number | yes |  | 0 – 1 | Venstre grænse udtrykt relativt til billedets bredde fra 0 til 1. |
| `bounding_boxes[].source_box.y_min` |  | number | yes |  | 0 – 1 | Øvre grænse udtrykt relativt til billedets højde fra 0 til 1. |
| `bounding_boxes[].source_box.x_max` |  | number | yes |  | 0 – 1 | Højre grænse udtrykt relativt til billedets bredde fra 0 til 1. |
| `bounding_boxes[].source_box.y_max` |  | number | yes |  | 0 – 1 | Nedre grænse udtrykt relativt til billedets højde fra 0 til 1. |
| `bounding_boxes[].target_box` |  | object {x_min, y_min, x_max, y_max} \| null | no |  |  | Outputplaceringsboks for objektet: Flytning eller ændring af størrelse kræver begge bokse, mens fjernelse af et refereret objekt kræver, at denne boks ikke angives. |
| `bounding_boxes[].target_box.x_min` |  | number | yes |  | 0 – 1 | Venstre grænse udtrykt relativt til billedets bredde fra 0 til 1. |
| `bounding_boxes[].target_box.y_min` |  | number | yes |  | 0 – 1 | Øvre grænse udtrykt relativt til billedets højde fra 0 til 1. |
| `bounding_boxes[].target_box.x_max` |  | number | yes |  | 0 – 1 | Højre grænse udtrykt relativt til billedets bredde fra 0 til 1. |
| `bounding_boxes[].target_box.y_max` |  | number | yes |  | 0 – 1 | Nedre grænse udtrykt relativt til billedets højde fra 0 til 1. |

File parameters (`images`) take a public `https://` URL, a `data:` URI up to 10 MB, or the `file_url` of an upload from `POST /files`.

## Example input

Required parameters only:

```json
{
  "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
  "images": [
    "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
  ]
}
```

A fuller example:

```json
{
  "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
  "image_urls": [
    "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
  ]
}
```

## Run it

Set `DOITONG_API_KEY` to a key from https://doitong.com/developers/dashboard#keys. `?wait=20` returns the finished request in the same call when it is ready within 20 seconds; otherwise poll `GET /requests/{id}` (it also accepts `?wait=`), or pass `webhook_url`.

### curl

```bash
# Run the model; wait up to 20 s for the finished result in the same call
curl -X POST "https://api.doitong.com/v1/run/blackforestlabs/flux-3/klein/edit-image?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
    "image_urls": [
      "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
    ]
  }'

# Still "queued" or "running"? Poll with the id from the response:
curl "https://api.doitong.com/v1/requests/REQUEST_ID?wait=20" \
  -H "Authorization: Bearer $DOITONG_API_KEY"
```

### JavaScript

```javascript
const API = "https://api.doitong.com/v1";
const headers = {
  "Authorization": "Bearer " + process.env.DOITONG_API_KEY,
  "Content-Type": "application/json",
};

// Run the model; wait up to 20 s for the finished result in the same call
let res = await fetch(API + "/run/blackforestlabs/flux-3/klein/edit-image?wait=20", {
  method: "POST",
  headers,
  body: JSON.stringify({
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
    "image_urls": [
      "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
    ]
  }),
});
let request = await res.json();
if (!res.ok) throw new Error(request.error.code + ": " + request.error.message);

// Not finished yet: long-poll until it is
while (request.status === "queued" || request.status === "running") {
  res = await fetch(API + "/requests/" + request.id + "?wait=20", { headers });
  request = await res.json();
}
if (request.status !== "succeeded") throw new Error(JSON.stringify(request.error));
console.log(request.outputs.map((o) => o.url), request.cost.credits + " API credits ($" + request.cost.usd + ")");
```

### Python

```python
import os
import requests

API = "https://api.doitong.com/v1"
headers = {"Authorization": "Bearer " + os.environ["DOITONG_API_KEY"]}

payload = {
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
    "image_urls": [
        "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg",
    ],
}

# Run the model; wait up to 20 s for the finished result in the same call
r = requests.post(API + "/run/blackforestlabs/flux-3/klein/edit-image", params={"wait": 20}, json=payload, headers=headers)
request = r.json()
if not r.ok:
    raise RuntimeError(request["error"]["code"] + ": " + request["error"]["message"])

# Not finished yet: long-poll until it is
while request["status"] in ("queued", "running"):
    request = requests.get(API + "/requests/" + request["id"], params={"wait": 20}, headers=headers).json()
if request["status"] != "succeeded":
    raise RuntimeError(request["error"])
print([o["url"] for o in request["outputs"]], request["cost"]["credits"], "API credits", "$" + request["cost"]["usd"])
```

### MCP

The MCP server at `https://api.doitong.com/v1/mcp` exposes the tools `search_models`, `get_model`, `quote`, `run`, `get_request`, `cancel_request`, `list_requests`, `create_upload` and `get_account`. A `run` call for this model:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "run",
    "arguments": {
      "model_id": "blackforestlabs/flux-3/klein/edit-image",
      "input": {
        "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
        "image_urls": [
          "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
        ]
      },
      "wait_seconds": 20
    }
  }
}
```

## Response

Every call returns a request object. `status` is one of `queued`, `running`, `succeeded`, `failed`, `canceled`. `outputs` lists the generated files with URLs on our storage (kept forever, or 7 days with `?storage=temporary`; `storage` says which); `output` is the model's own result object with the same URLs.

```json
{
  "id": "req_8k2m4q7x1z9c3v5b6n0p2r4t",
  "object": "request",
  "model": "blackforestlabs/flux-3/klein/edit-image",
  "status": "succeeded",
  "created_at": "2026-10-20T12:00:00Z",
  "started_at": "2026-10-20T12:00:02Z",
  "completed_at": "2026-10-20T12:00:09Z",
  "queue_position": null,
  "cost": {
    "credits": 9,
    "usd": "0.009",
    "charged": 9,
    "refunded": 0
  },
  "input": {
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field",
    "image_urls": [
      "https://content.doitong.com/images/showcase/v3/gen_fox_cartoon.jpg"
    ]
  },
  "output": {
    "images": [
      {
        "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
        "content_type": "image/jpeg",
        "file_name": "0-output.jpeg",
        "file_size": 1843200,
        "width": 1024,
        "height": 768
      }
    ],
    "timings": {},
    "seed": 42,
    "has_nsfw_concepts": [
      false
    ],
    "prompt": "string"
  },
  "outputs": [
    {
      "type": "image",
      "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
      "content_type": "image/jpeg",
      "file_size": 1843200,
      "width": 1024,
      "height": 768,
      "stored": true
    }
  ],
  "error": null,
  "metrics": {
    "inference_seconds": 6.8
  },
  "urls": {
    "self": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t",
    "cancel": "https://api.doitong.com/v1/requests/req_8k2m4q7x1z9c3v5b6n0p2r4t/cancel"
  }
}
```

### Output fields (`output`)

| Field | Type | Description |
|---|---|---|
| `images` | array of object {url, content_type, file_name, file_size, width, height} | Billeder produceret af modellen. |
| `timings` | object | Tidsoplysninger for genereringsprocessen. |
| `seed` | integer | Genereringsseed for det første billede. |
| `has_nsfw_concepts` | array of boolean | Angiver, om NSFW-koncepter forekommer i de genererede billeder. |
| `prompt` | string | Prompt brugt under billedgenerering. |

## Related models

- [FLUX.3 Klein](https://doitong.com/developers/models/blackforestlabs/flux-3/klein/text-to-image.md) (`blackforestlabs/flux-3/klein/text-to-image`): from $0.008 / run of output image
- [FLUX.1 Kontext \[pro\]](https://doitong.com/developers/models/flux-pro/kontext.md) (`flux-pro/kontext`): $0.04 / image
- [GPT Image 2.5 Edit](https://doitong.com/developers/models/openai/gpt-image-2.5/flare/edit.md) (`openai/gpt-image-2.5/flare/edit`): from $0.12 / image
- [Nano Banana 2 Edit](https://doitong.com/developers/models/nano-banana-2/edit.md) (`nano-banana-2/edit`): from $0.06 / image
- [Nano Banana Pro Edit](https://doitong.com/developers/models/nano-banana-pro/edit.md) (`nano-banana-pro/edit`): from $0.15 / image
- [Qwen Image 3 Edit](https://doitong.com/developers/models/alibaba/qwen-image-3/edit.md) (`alibaba/qwen-image-3/edit`): from $0.04 / image
- [Seedream 5.0 Pro Edit](https://doitong.com/developers/models/bytedance/seedream/v5/pro/edit.md) (`bytedance/seedream/v5/pro/edit`): from $0.0675 / run of output image
- [FLUX 2 Edit](https://doitong.com/developers/models/flux-2/edit.md) (`flux-2/edit`): $0.012 / megapixel

## Links

- HTML page: https://doitong.com/developers/models/blackforestlabs/flux-3/klein/edit-image
- All models and guides for AI agents: https://doitong.com/developers/llms.txt
- OpenAPI 3.1 with this model's typed request body: https://doitong.com/developers/openapi.json?model=blackforestlabs/flux-3/klein/edit-image
- Errors: https://doitong.com/developers/docs/errors
- Model details as JSON: https://api.doitong.com/v1/models/blackforestlabs/flux-3/klein/edit-image
