# FLUX.3 Klein Image Editing API

> FLUX.3 Klein-Editor mit bis zu 10 Referenzen und optionaler Objektplatzierung per Begrenzungsrahmen

Bearbeitet oder erstellt Bilder aus einem Prompt und 1 bis 10 Referenzen in `image_urls`, auf die der Prompt anhand ihrer Reihenfolge verweisen kann, etwa auf das erste Bild. Bis zu 32 `bounding_boxes` können Objekte, die im Prompt über ein Label benannt werden, beibehalten, verschieben, skalieren, entfernen oder hinzufügen. Die Prompt-Erweiterung ist standardmäßig aktiviert. Zurückgegeben werden 1 bis 4 Bilder als jpeg, png oder 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/de/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 |  |  | Eine vollständige Bildunterschrift verfassen, die das gewünschte Bild nach der Bearbeitung beschreibt und Referenzen anhand ihrer Reihenfolge nennt, etwa als erstes oder zweites Bild. |
| `enable_prompt_expansion` |  | boolean | no | `true` |  | Erweiterung des Prompts zu einer detaillierten Bildunterschrift vor der Generierung, aktiviert bei true. Bei der Bearbeitung wird die Bildunterschrift auf die Referenzbilder gestützt. |
| `seed` |  | integer \| null | no |  |  | Seed für reproduzierbare Bilder: Ein identischer Prompt und Seed erzeugen bei unveränderter Modellversion ein identisches Bild. |
| `num_images` | `num_outputs` | integer | no | `1` | 1 – 4 | Für die Generierung angeforderte Bildanzahl. |
| `enable_safety_checker` |  | boolean | no | `true` |  | Aktivierung der Sicherheitsprüfung; true aktiviert die Prüfung. |
| `output_format` |  | enum (string) | no | `png` | `jpeg`, `png`, `webp` | Dateiformat des resultierenden Bilds. |
| `image_urls` | `images` | array of image URL | yes |  | 1 – 10 items | Für Bearbeitung oder Komposition verwendete Referenzbilder, maximal 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` | Die Ausgabeabmessungen entsprechen standardmäßig dem ersten Referenzbild, sind bei mehreren Referenzen auf 1 Megapixel begrenzt oder werden bei einer einzelnen Referenz auf höchstens 4 Megapixel skaliert. Explizite Größen müssen je Seite zwischen 256 und 4096 Pixel liegen. |
| `bounding_boxes` |  | array of object {label, description, box, source_image_index, source_box, target_box} \| null | no |  | ≤ 32 items | Optionales Objektlayout zum Beibehalten, Verschieben, Ändern der Größe oder Entfernen von Referenzobjekten sowie zum Platzieren neuer Objekte. Koordinaten beginnen in jeder Bildecke oben links bei (0, 0); Boxen werden mit Labels im Prompt referenziert, etwa `<dragon>`. |
| `bounding_boxes[].label` |  | string \| null | no |  | ≤ 64 characters | Kurzes Objektlabel für die Box, etwa `dragon`; der Standardwert ist `obj_<n>`. `<dragon>` im Prompt verknüpft dessen Wörter mit der Box; im Prompt nicht erwähnte Boxen werden der Szene hinzugefügt. |
| `bounding_boxes[].description` |  | string | yes |  | ≤ 500 characters | Innerhalb der Box zu renderndes Objekt einschließlich seines Erscheinungsbilds. |
| `bounding_boxes[].box` |  | object {x_min, y_min, x_max, y_max} \| null | no |  |  | Ausgabeposition des Objekts; ersetzt `source_box`/`target_box` und verwendet dasselbe Platzierungsverhalten wie Text-zu-Bild. |
| `bounding_boxes[].box.x_min` |  | number | yes |  | 0 – 1 | Linke Grenze relativ zur Bildbreite von 0 bis 1. |
| `bounding_boxes[].box.y_min` |  | number | yes |  | 0 – 1 | Obere Grenze relativ zur Bildhöhe von 0 bis 1. |
| `bounding_boxes[].box.x_max` |  | number | yes |  | 0 – 1 | Rechte Grenze relativ zur Bildbreite von 0 bis 1. |
| `bounding_boxes[].box.y_max` |  | number | yes |  | 0 – 1 | Untere Grenze relativ zur Bildhöhe von 0 bis 1. |
| `bounding_boxes[].source_image_index` |  | integer \| null | no |  | ≥ 0 | Auswahl der Objektquelle: für ein neues Objekt leer lassen oder eine vorhandene Referenz anhand ihres Index in `image_urls` angeben, beginnend bei 0. |
| `bounding_boxes[].source_box` |  | object {x_min, y_min, x_max, y_max} \| null | no |  |  | Position des Objekts im Referenzbild; `source_image_index` muss ebenfalls angegeben werden. |
| `bounding_boxes[].source_box.x_min` |  | number | yes |  | 0 – 1 | Linke Grenze relativ zur Bildbreite von 0 bis 1. |
| `bounding_boxes[].source_box.y_min` |  | number | yes |  | 0 – 1 | Obere Grenze relativ zur Bildhöhe von 0 bis 1. |
| `bounding_boxes[].source_box.x_max` |  | number | yes |  | 0 – 1 | Rechte Grenze relativ zur Bildbreite von 0 bis 1. |
| `bounding_boxes[].source_box.y_max` |  | number | yes |  | 0 – 1 | Untere Grenze relativ zur Bildhöhe von 0 bis 1. |
| `bounding_boxes[].target_box` |  | object {x_min, y_min, x_max, y_max} \| null | no |  |  | Ausgabebox des Objekts: Zum Verschieben oder Ändern der Größe sind beide Boxen erforderlich; zum Entfernen eines referenzierten Objekts muss diese Box nicht gesetzt werden. |
| `bounding_boxes[].target_box.x_min` |  | number | yes |  | 0 – 1 | Linke Grenze relativ zur Bildbreite von 0 bis 1. |
| `bounding_boxes[].target_box.y_min` |  | number | yes |  | 0 – 1 | Obere Grenze relativ zur Bildhöhe von 0 bis 1. |
| `bounding_boxes[].target_box.x_max` |  | number | yes |  | 0 – 1 | Rechte Grenze relativ zur Bildbreite von 0 bis 1. |
| `bounding_boxes[].target_box.y_max` |  | number | yes |  | 0 – 1 | Untere Grenze relativ zur Bildhöhe von 0 bis 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} | Vom Modell erzeugte Bilder. |
| `timings` | object | Zeitinformationen zum Generierungsprozess. |
| `seed` | integer | Generierungs-Seed für das erste Bild. |
| `has_nsfw_concepts` | array of boolean | Gibt an, ob NSFW-Konzepte in den generierten Bildern vorkommen. |
| `prompt` | string | Während der Bildgenerierung verwendeter Prompt. |

## 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
