Try it live - Upload images and describe your edits in our playground. See the magic happen in seconds.
Examples
Single Reference


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.

