# FLUX.1 [dev] with Controlnets and Loras API

> FLUX.1 [dev] texte-vers-image avec prise en charge des LoRAs, ControlNets, IP-Adapters, EasyControl et du guidage par image de référence

Génère des images à partir d'un `prompt` avec plusieurs méthodes de conditionnement : `loras`, `control_loras`, `controlnets`, `controlnet_unions`, `ip_adapters` et `easycontrols`, ainsi que `fill_image` pour les zones masquées. Accepte aussi un `reference_image_url`, des prompts négatifs et un choix entre les ordonnanceurs euler et dpmpp_2m. Jusqu'à 10 images par appel, en png ou jpeg.

- Model id: `flux-general`
- Made by: Black Forest Labs
- Category: Text to Image
- Output: image
- Estimated price per run: $0.30 / image (cheapest run $0.30 (300 API credits))
- Run: `POST https://api.doitong.com/v1/run/flux-general`
- Quote: `POST https://api.doitong.com/v1/quote/flux-general`
- Docs page: https://doitong.com/fr/developers/models/flux-general

## Pricing

Price: **$0.30 / image**. Estimated from the typical cost of one run, per output (`num_images`). The quote is exactly what the run charges.

The full example input below costs $0.30 = 300 API credits (1 image × 300 API credits).

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/flux-general` 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 |  |  | Prompt qui guide la génération d'images. |
| `image_size` |  | object {width, height} \| enum (string) | no |  | `square_hd`, `square`, `portrait_4_3`, `portrait_16_9`, `landscape_4_3`, `landscape_16_9` | Dimensions de l’image générée. |
| `num_inference_steps` |  | integer | no | `28` | 1 – 50 | Nombre d’étapes d’inférence à exécuter. |
| `seed` |  | integer \| null | no |  |  | Seed pour des images reproductibles : un prompt et un seed identiques produisent une image identique lorsque la version du modèle est inchangée. |
| `loras` |  | array of object {path, scale} | no | `[]` |  | LoRAs dont l’effet combiné produit l’image générée, sans limite quant au nombre fourni. |
| `loras[].path` |  | string | yes |  |  | Emplacement des poids LoRA, indiqué sous forme d’URL ou de chemin. |
| `loras[].scale` |  | object \| number | no | `1` |  | Mise à l’échelle appliquée aux poids LoRA avant leur fusion avec le modèle de base. Fournissez un dictionnaire de la forme {"layer_name":layer_scale} pour définir l’échelle de chaque couche ; les couches non spécifiées utilisent 1.0. |
| `control_loras` |  | array of object {path, scale, control_image_url, preprocess} | no | `[]` |  | LoRAs d’image de contrôle fusionnées dans une configuration combinée pour générer l’image finale ; le nombre fourni n’est pas limité. |
| `control_loras[].path` |  | string | yes |  |  | Emplacement des poids LoRA, indiqué sous forme d’URL ou de chemin. |
| `control_loras[].scale` |  | object \| number | no | `1` |  | Mise à l’échelle appliquée aux poids LoRA avant leur fusion avec le modèle de base. Fournissez un dictionnaire de la forme {"layer_name":layer_scale} pour définir l’échelle de chaque couche ; les couches non spécifiées utilisent 1.0. |
| `control_loras[].control_image_url` |  | string (image URL) | yes |  |  | URL de l’image de contrôle. |
| `control_loras[].preprocess` |  | enum (string) | no | `None` | `canny`, `depth`, `None` | Méthode de prétraitement appliquée à l’image fournie. |
| `controlnets` |  | array of object {path, config_url, variant, control_image_url, mask_image_url, mask_threshold, conditioning_scale, start_percentage, end_percentage} | no | `[]` |  | Configuration ControlNet pour la génération d’images, actuellement limitée à un seul ControlNet. |
| `controlnets[].path` |  | string | yes |  |  | Emplacement des poids ControlNet, indiqué sous forme d’URL ou de chemin. |
| `controlnets[].config_url` |  | string \| null | no |  |  | URL facultative vers le fichier config.json de ControlNet. |
| `controlnets[].variant` |  | string \| null | no |  |  | Variante facultative à utiliser avec une clé de dépôt Hugging Face. |
| `controlnets[].control_image_url` |  | string (image URL) | yes |  |  | URL de l’image de contrôle. |
| `controlnets[].mask_image_url` |  | string (image URL) | no |  |  | URL du masque associé à l’image de contrôle. |
| `controlnets[].mask_threshold` |  | number | no | `0.5` | 0.01 – 0.99 | Valeur seuil du masque. |
| `controlnets[].conditioning_scale` |  | number | no | `1` | 0 – 2 | Mise à l’échelle appliquée aux poids ControlNet avant leur fusion avec le modèle de base. |
| `controlnets[].start_percentage` |  | number | no | `0` | 0 – 1 | Pourcentage du nombre total d’étapes temporelles auquel ControlNet commence à influencer la génération de l’image. |
| `controlnets[].end_percentage` |  | number | no | `1` | 0 – 1 | Pourcentage du nombre total d’étapes temporelles auquel ControlNet cesse d’influencer la génération de l’image. |
| `controlnet_unions` |  | array of object {path, config_url, variant, controls} | no | `[]` |  | Configuration ControlNet union pour la génération d’images, soumise à la restriction actuelle d’un seul ControlNet. |
| `controlnet_unions[].path` |  | string | yes |  |  | Emplacement des poids ControlNet, indiqué sous forme d’URL ou de chemin. |
| `controlnet_unions[].config_url` |  | string \| null | no |  |  | URL facultative vers le fichier config.json de ControlNet. |
| `controlnet_unions[].variant` |  | string \| null | no |  |  | Variante facultative à utiliser avec une clé de dépôt Hugging Face. |
| `controlnet_unions[].controls` |  | array of object {control_image_url, mask_image_url, control_mode, conditioning_scale, mask_threshold, start_percentage, end_percentage} | yes |  |  | Images de contrôle et modes associés fournis à ControlNet. |
| `controlnet_unions[].controls[].control_image_url` |  | string (image URL) | yes |  |  | URL de l’image de contrôle. |
| `controlnet_unions[].controls[].mask_image_url` |  | string (image URL) | no |  |  | URL du masque associé à l’image de contrôle. |
| `controlnet_unions[].controls[].control_mode` |  | enum (string) | yes |  | `canny`, `tile`, `depth`, `blur`, `pose`, `gray`, `low-quality` | Mode de contrôle utilisé par Flux Controlnet Union. Options : canny guide la génération avec des contours ; tile la guide avec des tuiles ; depth la guide avec une carte de profondeur en niveaux de gris ; blur floute l’image ; pose guide la génération avec la pose de l’image ; gray convertit l’image en niveaux de gris ; low-quality produit une version de faible qualité de l’image. |
| `controlnet_unions[].controls[].conditioning_scale` |  | number | no | `1` | 0 – 2 | Mise à l’échelle appliquée aux poids ControlNet avant leur fusion avec le modèle de base. |
| `controlnet_unions[].controls[].mask_threshold` |  | number | no | `0.5` | 0.01 – 0.99 | Valeur seuil du masque. |
| `controlnet_unions[].controls[].start_percentage` |  | number | no | `0` | 0 – 1 | Pourcentage du nombre total d’étapes temporelles auquel ControlNet commence à influencer la génération de l’image. |
| `controlnet_unions[].controls[].end_percentage` |  | number | no | `1` | 0 – 1 | Pourcentage du nombre total d’étapes temporelles auquel ControlNet cesse d’influencer la génération de l’image. |
| `ip_adapters` |  | array of object {path, subfolder, weight_name, image_encoder_path, image_encoder_subfolder, image_encoder_weight_name, image_url, mask_image_url, mask_threshold, scale} | no | `[]` |  | IP-Adapter appliqué pendant la génération de l’image. |
| `ip_adapters[].path` |  | string | yes |  |  | Emplacement de l’IP-Adapter sur Hugging Face. |
| `ip_adapters[].subfolder` |  | string \| null | no |  |  | Sous-dossier contenant les poids ip_adapter. |
| `ip_adapters[].weight_name` |  | string \| null | no |  |  | Nom de fichier Safetensors des poids de l’IP-Adapter. |
| `ip_adapters[].image_encoder_path` |  | string | yes |  |  | Emplacement de l’encodeur d’image de l’IP-Adapter, tel que 'openai/clip-vit-large-patch14'. |
| `ip_adapters[].image_encoder_subfolder` |  | string \| null | no |  |  | Sous-dossier contenant les poids de l’encodeur d’image. |
| `ip_adapters[].image_encoder_weight_name` |  | string \| null | no |  |  | Nom de l’encodeur d’image. |
| `ip_adapters[].image_url` |  | string (image URL) | yes |  |  | URL de l’image de conditionnement fournie à l’IP-Adapter. |
| `ip_adapters[].mask_image_url` |  | string (image URL) \| null | no |  |  | URL du masque associé à l’image de contrôle. |
| `ip_adapters[].mask_threshold` |  | number | no | `0.5` | 0.01 – 0.99 | Valeur seuil du masque. |
| `ip_adapters[].scale` |  | number | yes |  |  | Facteur d’échelle de l’IP-Adapter. |
| `easycontrols` |  | array of object {control_method_url, scale, image_url, image_control_type} | no | `[]` |  | Entrées EasyControl appliquées pendant la génération de l’image. |
| `easycontrols[].control_method_url` |  | string | yes |  |  | URL des poids safetensor de la méthode de contrôle ou identifiant pris en charge : `canny`, `depth`, `hedsketch`, `inpainting`, `pose`, `seg`, `subject`, `ghibli`. |
| `easycontrols[].scale` |  | number | no | `1` | 0 – 2 | Facteur d’échelle de la méthode de contrôle. |
| `easycontrols[].image_url` |  | string (image URL) | yes |  |  | URL de l’image fournissant une entrée de contrôle. |
| `easycontrols[].image_control_type` |  | enum (string) | yes |  | `subject`, `spatial` | Mode de contrôle de l’image ; accepte `spatial` ou `subject`. |
| `fill_image` |  | object {fill_image_url} \| null | no |  |  | Image d’entrée qui guide la génération et peut fournir du contenu pour les régions masquées. |
| `fill_image.fill_image_url` |  | string (image URL) \| array of image URL | no | `[]` |  | URL des images à remplir via le prompting redux. |
| `guidance_scale` |  | number | no | `3.5` | 0 – 20 | Force d'adhérence au prompt pour la sélection d'image, exprimée comme CFG (Classifier Free Guidance). |
| `real_cfg_scale` |  | number | no | `3.5` | 0 – 5 | Force d'adhérence au prompt pour la sélection d'image, exprimée comme CFG (Classifier Free Guidance). |
| `use_real_cfg` |  | boolean | no | `false` |  | Option CFG classique, automatiquement activée avec XLabs IP-Adapter v1. Le comportement du guidage correspond à celui de modèles tels que SD1.5 et SDXL. |
| `use_cfg_zero` |  | boolean | no | `false` |  | Active l’échantillonnage avec initialisation CFG-zero, décrit à l’adresse https://arxiv.org/abs/2503.18886. |
| `num_images` | `num_outputs` | integer | no | `1` | 1 – 10 | Définit le nombre d’images à générer ; ce choix est fixé à 1 lorsque la sortie est diffusée en continu. |
| `enable_safety_checker` |  | boolean | no | `true` |  | Vérification de sécurité qui renvoie des images noires à la place des images signalées comme non sûres. La valeur true active la vérification ; false la désactive uniquement pour les comptes autorisés, tandis que les requêtes sans autorisation sont vérifiées dans tous les cas. |
| `reference_image_url` |  | string (image URL) | no |  |  | URL de l’image utilisée pour le guidage Reference-Only. |
| `reference_strength` |  | number | no | `0.65` | -3 – 3 | Influence de l’image de référence pendant la génération reference_only ; sans image de référence fournie, ce paramètre d’intensité n’a aucun effet. |
| `reference_start` |  | number | no | `0` | 0 – 1 | Point de départ du guidage de référence, exprimé en pourcentage de toutes les étapes temporelles. |
| `reference_end` |  | number | no | `1` | 0 – 1 | Point de fin du guidage de référence, exprimé en pourcentage de toutes les étapes temporelles. |
| `base_shift` |  | number | no | `0.5` | 0.01 – 5 | Décalage de base appliqué aux étapes temporelles planifiées. |
| `max_shift` |  | number | no | `1.15` | 0.01 – 5 | Décalage maximal appliqué aux étapes temporelles planifiées. |
| `output_format` |  | enum (string) | no | `png` | `jpeg`, `png` | Format de fichier de l'image obtenue. |
| `use_beta_schedule` |  | boolean | no | `false` |  | Contrôle l’utilisation des sigmas bêta. |
| `sigma_schedule` |  | string \| null | no |  |  | Planification des sigmas utilisée pendant le débruitage. |
| `scheduler` |  | enum (string) | no | `euler` | `euler`, `dpmpp_2m` | Planificateur utilisé pendant le débruitage. |
| `negative_prompt` |  | string | no | `` |  | Prompt négatif traité par défaut avec NAG pour décourager les caractéristiques indésirables spécifiées dans les images générées. |
| `nag_scale` |  | number | no | `3` | ≤ 10, > 1 | Évitement du prompt négatif contrôlé par l’échelle NAG : l’augmenter rend l’image générée moins semblable à la description négative. |
| `nag_tau` |  | number | no | `2.5` | > 0 | Paramètre tau de NAG pour la normalisation de l’état caché ; il est recommandé de le laisser inchangé. L’augmenter affaiblit la normalisation et risque de provoquer des écarts inattendus par rapport à l’image originale. |
| `nag_alpha` |  | number | no | `0.25` | ≤ 1, > 0 | alpha de NAG définit dans quelle mesure le prompt positif réoriente le guidage normalisé combinant les prompts positif et négatif. Cette pondération finale donne davantage d’influence au prompt positif avec des valeurs faibles et réduit la réorientation avec des valeurs élevées. |
| `nag_end` |  | number | no | `0.25` | ≤ 1, > 0 | Seuil NAG exprimé comme une proportion des étapes de génération. Les processeurs d’attention originaux de FLUX prennent le relais après l’exécution de NAG pendant cette proportion initiale. |

File parameters (`reference_image_url`) 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"
}
```

A fuller example:

```json
{
  "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
}
```

## 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/flux-general?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"
  }'

# 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/flux-general?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"
  }),
});
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",
}

# Run the model; wait up to 20 s for the finished result in the same call
r = requests.post(API + "/run/flux-general", 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": "flux-general",
      "input": {
        "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
      },
      "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": "flux-general",
  "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": 300,
    "usd": "0.30",
    "charged": 300,
    "refunded": 0
  },
  "input": {
    "prompt": "A red fox trots through fresh snow at sunrise, soft golden light, shallow depth of field"
  },
  "output": {
    "images": [
      {
        "url": "https://content.doitong.com/dev-api/2026/10/20/req_8k2m4q7x1z9c3v5b6n0p2r4t/0-output.jpeg",
        "width": 1024,
        "height": 768,
        "content_type": "image/jpeg"
      }
    ],
    "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, width, height, content_type} | Informations de fichier pour les images générées. |
| `timings` | object |  |
| `seed` | integer | Seed de génération d'images, y compris la valeur choisie aléatoirement si l'entrée n'en fournissait pas ; sinon, il reprend la valeur fournie. |
| `has_nsfw_concepts` | array of boolean | Indique si des concepts NSFW apparaissent dans les images générées. |
| `prompt` | string | Prompt utilisé pendant la génération d'images. |

## Related models

- [FLUX.1 \[dev\] with Controlnets and Loras · Differential Diffusion](https://doitong.com/developers/models/flux-general/differential-diffusion.md) (`flux-general/differential-diffusion`): $0.138 / image
- [FLUX.1 \[dev\] with Controlnets and Loras · Image to Image](https://doitong.com/developers/models/flux-general/image-to-image.md) (`flux-general/image-to-image`): $0.15 / image
- [FLUX.1 \[dev\] with Controlnets and Loras · Inpainting](https://doitong.com/developers/models/flux-general/inpainting.md) (`flux-general/inpainting`): $0.192 / image
- [FLUX.1 \[dev\] with Controlnets and Loras · Rf Inversion](https://doitong.com/developers/models/flux-general/rf-inversion.md) (`flux-general/rf-inversion`): $0.025 / image
- [FLUX.1 \[dev\]](https://doitong.com/developers/models/flux/dev.md) (`flux/dev`): $0.025 / megapixel
- [FLUX.1 \[schnell\]](https://doitong.com/developers/models/flux/schnell.md) (`flux/schnell`): $0.003 / megapixel
- [FLUX.2 \[dev\]](https://doitong.com/developers/models/flux-2.md) (`flux-2`): $0.012 / megapixel
- [FLUX.2 \[pro\]](https://doitong.com/developers/models/flux-2-pro.md) (`flux-2-pro`): $0.015 / megapixel of output image

## Links

- HTML page: https://doitong.com/developers/models/flux-general
- 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=flux-general
- Errors: https://doitong.com/developers/docs/errors
- Model details as JSON: https://api.doitong.com/v1/models/flux-general
