Skip to main content
Edit images like magic. Describe what you want changed, and FLUX.2 makes it happen. Combine furniture from multiple photos into one room. Replace people with animals while keeping proportions perfect. Change backgrounds, swap textures, edit text—all while maintaining photorealism that matches professional photography. Reference multiple images simultaneously - up to 8 via API, up to 10 in the playground. Use [max] for highest precision editing, [pro] for production at scale, [flex] for fine-grained control, or [klein] for cost-efficient high-volume editing.
Try it live - Upload images and describe your edits in our playground. See the magic happen in seconds.

Examples

Single Reference

Foggy forest hillside
Sunny forest hillside with birds

Change the weather to a warm sunny day with clear blue sky and add a flock of birds flying over the treetops.

Multi Reference

API Integration

Create Request

import os
import requests

# Using image URLs directly (simplest)
# flux-2-pro-preview reflects our latest advances (use flux-2-pro for a pinned model)
response = requests.post(
    'https://api.bfl.ai/v1/flux-2-pro-preview',
    headers={
        'accept': 'application/json',
        'x-key': os.environ.get("BFL_API_KEY"),
        'Content-Type': 'application/json',
    },
    json={
        'prompt': '<What you want to edit on the image>',
        'input_image': 'https://example.com/your-image.jpg',
        # 'input_image_2': 'https://example.com/reference-2.jpg',  # Optional
    },
).json()

request_id = response["id"]
polling_url = response["polling_url"]
// Using image URLs (simplest method)
// flux-2-pro-preview reflects our latest advances (use flux-2-pro for a pinned model)
const response = await fetch("https://api.bfl.ai/v1/flux-2-pro-preview", {
  method: "POST",
  headers: {
    accept: "application/json",
    "x-key": process.env.BFL_API_KEY!,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    prompt: "<What you want to edit on the image>",
    input_image: "https://example.com/your-image.jpg",
    // input_image_2: "https://example.com/reference-2.jpg",  // Optional
  }),
});

const { id: requestId, polling_url: pollingUrl } = await response.json();
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

func main() {
	// Using image URLs (simplest method)
	// flux-2-pro-preview reflects our latest advances (use flux-2-pro for a pinned model)
	payload, _ := json.Marshal(map[string]string{
		"prompt":      "<What you want to edit on the image>",
		"input_image": "https://example.com/your-image.jpg",
		// "input_image_2": "https://example.com/reference-2.jpg",  // Optional
	})

	req, _ := http.NewRequest("POST", "https://api.bfl.ai/v1/flux-2-pro-preview", bytes.NewBuffer(payload))
	req.Header.Set("accept", "application/json")
	req.Header.Set("x-key", os.Getenv("BFL_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)

	requestId := result["id"].(string)
	pollingUrl := result["polling_url"].(string)
	fmt.Println(requestId, pollingUrl)
}
# Using image URLs (simplest method)
# flux-2-pro-preview reflects our latest advances (use flux-2-pro for a pinned model)
request=$(curl -X POST \
  'https://api.bfl.ai/v1/flux-2-pro-preview' \
  -H 'accept: application/json' \
  -H "x-key: ${BFL_API_KEY}" \
  -H 'Content-Type: application/json' \
  -d '{
    "prompt": "<What you want to edit on the image>",
    "input_image": "https://example.com/your-image.jpg",
    "input_image_2": "https://example.com/reference-2.jpg"
  }')
echo $request
request_id=$(echo $request | jq -r .id)
polling_url=$(echo $request | jq -r .polling_url)

Poll for Result

# This assumes that the `polling_url` variable is set.

import time
import os
import requests

while True:
    time.sleep(0.5)
    result = requests.get(
        polling_url,
        headers={
            'accept': 'application/json',
            'x-key': os.environ.get("BFL_API_KEY"),
        },
    ).json()

    if result['status'] == 'Ready':
        print(f"Image ready: {result['result']['sample']}")
        break
    elif result['status'] in ['Error', 'Failed']:
        print(f"Generation failed: {result}")
        break
// This assumes that the `pollingUrl` variable is set.

while (true) {
  await new Promise((resolve) => setTimeout(resolve, 500));

  const result = await fetch(pollingUrl, {
    headers: {
      accept: "application/json",
      "x-key": process.env.BFL_API_KEY!,
    },
  }).then((res) => res.json());

  if (result.status === "Ready") {
    console.log(`Image ready: ${result.result.sample}`);
    break;
  } else if (["Error", "Failed"].includes(result.status)) {
    console.log(`Generation failed: ${JSON.stringify(result)}`);
    break;
  }
}
// This assumes that the `pollingUrl` variable is set.

for {
	time.Sleep(500 * time.Millisecond)

	req, _ := http.NewRequest("GET", pollingUrl, nil)
	req.Header.Set("accept", "application/json")
	req.Header.Set("x-key", os.Getenv("BFL_API_KEY"))

	resp, _ := http.DefaultClient.Do(req)
	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)
	resp.Body.Close()

	status := result["status"].(string)
	fmt.Println("Status:", status)

	if status == "Ready" {
		sample := result["result"].(map[string]interface{})["sample"].(string)
		fmt.Println("Image ready:", sample)
		break
	} else if status == "Error" || status == "Failed" {
		fmt.Println("Generation failed:", result)
		break
	}
}
while true; do
  sleep 0.5
  result=$(curl -s -X 'GET' \
    "${polling_url}" \
    -H 'accept: application/json' \
    -H "x-key: ${BFL_API_KEY}")

  status=$(echo $result | jq -r .status)
  echo "Status: $status"

  if [ "$status" == "Ready" ]; then
    echo "Result: $(echo $result | jq -r .result.sample)"
    break
  elif [ "$status" == "Error" ] || [ "$status" == "Failed" ]; then
    echo "Generation failed: $result"
    break
  fi
done
Signed URLs are only valid for 10 minutes. Please retrieve your result within this timeframe.
For all available parameters and endpoint details, see the API Reference.