Flux 2 Dev Edit LoRA
Playground
Try it on WaveSpeedAI!FLUX.2 [dev] Edit with LoRA support enables precise image-to-image editing with natural-language instructions, hex color control, and personalized styles via custom LoRA adapters. Extends FLUX.2 [dev] Edit with up to 4 LoRAs for consistent, brand-specific results. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.
Features
FLUX.2 [dev] Edit LoRA is a lightweight, LoRA-aware editing model built on FLUX.2 [dev]. It’s designed to take an existing image and apply personalised, structure-preserving edits using natural language prompts plus up to 4 custom LoRA adapters—ideal when you want fast, consistent updates to assets you already have.
Ideal use cases
- Refreshing existing brand or product imagery with custom LoRAs
- Keeping characters consistent across many edited shots
- Rolling out seasonal or campaign variants from a stable asset library
- Post-processing generations from FLUX.2 [dev] Text-to-Image
- Teams that need low-cost, high-volume edits with style control
LoRA-guided editing on a compact engine
Starting from the same lean architecture as FLUX.2 [dev] Edit, Edit LoRA adds adapter hooks so your custom LoRAs can drive the look and feel of each edit. The base image anchors composition and identity, while LoRAs and prompts work together to adjust style, colours, and details—keeping edits fast and predictable even at scale.
Why teams pick this model
• Dev-class editing, upgraded with LoRAs
You keep the familiar behaviour of the original Edit model (local, prompt-based changes) and layer LoRAs on top for brand styles, art directions, or recurring characters—so everything stays on-model across campaigns.
• Multiple LoRAs in one pass
Attach up to four adapters at once, each with its own strength range (0–4). For example, combine a “character” LoRA, a “lighting/style” LoRA, and a “brand palette” LoRA while you update backgrounds, outfits, or props via text.
• Structure stays, style evolves
The model treats the input image as the anchor: faces, poses, and layout remain intact while textures, colours, and surface details are updated. That makes it ideal for catalogue refreshes and long-running series.
• Batch-friendly performance
Generate 1–4 edited variants per request using the same LoRA stack and prompt. This makes it easy to spin up A/B sets, platform variants, or bulk updates without manually tracking parameters per image.
• Open, integration-ready foundation
Built on the open FLUX.2 dev stack, so it plugs cleanly into your own LoRA training, storage, and deployment infrastructure, whether you manage LoRAs per client, per brand, or per project.
• Cost-efficient asset reuse
Because LoRAs are lightweight and edits are local, you can update large libraries of images at low cost—instead of regenerating everything from scratch or retraining a full model.
Pricing
Simple per-image billing:
- $0.03 per edited image
FLUX.2 [dev] family on WaveSpeedAI
- FLUX.2 [dev] Text-to-Image – base model without LoRA for the fastest, most lightweight generation.
- FLUX.2 [dev] Text-to-Image with LoRA – personalised generation with up to 4 LoRAs per prompt.
- FLUX.2 [dev] Edit – prompt-based editing of existing images using the plain dev backbone.
- FLUX.2 [dev] Edit with LoRA – this model, for LoRA-powered, structure-preserving edits on existing assets.
More LoRA-support image tools
- qwen-image/edit-plus-lora – combines Qwen’s strong semantic understanding with LoRA-based style control for precise, localised edits that keep the overall composition intact.
- FLUX Kontext LoRA – a FLUX.2 dev LoRA stack tuned for cleaner prompts, better context handling, and more coherent, production-friendly generations.
- SDXL-LoRA – a collection of SDXL LoRAs covering many styles and subjects, ideal for fast visual customisation without full-model fine-tuning.
LoRA resources
Authentication
For authentication details, please refer to the Authentication Guide.
API Endpoints
Submit Task & Query Result
set -euo pipefail
export WAVESPEED_API_KEY="your-api-key"
REQUEST_BODY=$(cat <<'JSON'
{
"prompt": "A cinematic ocean wave at sunrise, highly detailed",
"images": [
"https://interactive-examples.mdn.mozilla.net/media/cc0-images/painted-hand-298-332.jpg"
],
"seed": -1
}
JSON
)
# 1. Submit the prediction.
SUBMIT_RESPONSE=$(curl --silent --show-error --fail-with-body \
-X POST "https://api.wavespeed.ai/api/v3/wavespeed-ai/flux-2-dev/edit-lora" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}" \
-H "Content-Type: application/json" \
-d "${REQUEST_BODY}")
TASK=$(printf '%s' "${SUBMIT_RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
PREDICTION_ID=$(printf '%s' "${TASK}" | jq -r '.id // empty')
if [ -z "${PREDICTION_ID}" ]; then
printf 'Submission response did not contain a prediction id
' >&2
exit 1
fi
RESULT_URL=$(printf '%s' "${TASK}" | jq -r '.urls.get // empty')
if [ -z "${RESULT_URL}" ]; then RESULT_URL="https://api.wavespeed.ai/api/v3/predictions/${PREDICTION_ID}/result"; fi
# 2. Poll until the prediction finishes.
while true; do
RESPONSE=$(curl --silent --show-error --fail-with-body \
"${RESULT_URL}" \
-H "Authorization: Bearer ${WAVESPEED_API_KEY}")
RESULT=$(printf '%s' "${RESPONSE}" | jq 'if type == "object" and has("data") then .data else . end')
STATUS=$(printf '%s' "${RESULT}" | jq -r '.status // empty')
case "${STATUS}" in
completed) printf '%s\n' "${RESULT}" | jq '.outputs'; break ;;
failed|cancelled|timeout) printf '%s\n' "${RESULT}" | jq . >&2; exit 1 ;;
created|processing) sleep 2 ;;
*) printf 'Unexpected status: %s
' "${STATUS}" >&2; exit 1 ;;
esac
doneParameters
Task Submission Parameters
Request Parameters
| Parameter | Type | Required | Default | Range | Description |
|---|---|---|---|---|---|
| prompt | string | Yes | - | The prompt describing the desired edits to the image. | |
| images | array<string> | Yes | - | 1 ~ 3 items | List of URLs of input images for editing. The maximum number of images is 3. |
| loras | array<object> | No | 0 ~ 3 items | List of LoRAs to apply (max 3). | |
| seed | integer | No | -1 | - | The random seed to use for the generation. -1 means a random seed will be used. |
| enable_base64_output | boolean | No | false | - | If set to `true`, the prediction's `output` strings are returned as **naked base64** (no `data:<mime>;base64,` prefix). When `false` (default), outputs are returned as URLs pointing to our CDN. |
| enable_sync_mode | boolean | No | false | - | If set to `true`, the request attempts to wait for the generated result and return outputs in the same response. If the result is not ready within the sync wait window, the API can return a timeout body while the task continues processing. This option is only available via the API and is supported only by some models. |
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data.id | string | Unique identifier for the prediction, Task Id |
| data.model | string | Model ID used for the prediction |
| data.outputs | array | Output values, usually URL strings; some models return text strings or structured result objects (empty when status is not completed) |
| data.urls | object | Object containing related API endpoints |
| data.urls.get | string | URL to retrieve the prediction result |
| data.status | string | Status of the task: created, processing, completed, or failed |
| data.created_at | string | ISO timestamp of when the request was created (e.g., “2023-04-01T12:34:56.789Z”) |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |
Result Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | Yes | - | Task ID |
Result Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | integer | HTTP status code (e.g., 200 for success) |
| message | string | Status message (e.g., “success”) |
| data | object | The prediction data object containing all details |
| data.id | string | Unique identifier for the prediction |
| data.model | string | Model ID used for the prediction |
| data.outputs | array<string | object> | Array of generated outputs (empty when status is not completed). Items are usually URL strings, but may be text strings or structured result objects, depending on the model. |
| data.urls | object | Object containing related API endpoints |
| data.urls.get | string | URL to poll for the prediction result |
| data.status | string | Status: created, processing, completed, or failed |
| data.created_at | string | ISO timestamp of when the request was created |
| data.error | string | Error message (empty if no error occurred) |
| data.timings | object | Object containing timing details |
| data.timings.inference | integer | Inference time in milliseconds |