FLUX.2 没有单独的编辑端点。编辑用的就是你做文生图时那个 POST,只是多加了几个 input_image 字段。这个设计决定了一件事:客户端该怎么搭,从第一行代码就定下来了。
下面每个端点、字段名和限额都来自 Black Forest Labs 官方文档。官方没写过的地方,本文直接说没有,不留空话。
FLUX.2 编辑端点的工作方式
三步任务流程
一次编辑是一个任务,不是一次就把图片装回来的响应。你把请求 POST 到 https://api.bfl.ai/v1/flux-2-pro-preview,这是官方编辑示例页用的那个端点;如果同一个提示词需要在多次运行里得到同样结果,就换成固定快照 flux-2-pro。返回里带着 id 和 polling_url,用同一个密钥请求头去 GET 这个轮询地址,等 status 变成 Ready,图片才会以 result.sample 的形式出现。
result.sample 指向的签名链接十分钟后失效,所以下载必须和轮询放在同一次运行里完成。
鉴权只有一个 x-key 请求头,不是 Bearer token。密钥怎么建,API 接入教程里写过。
一段可直接运行的多参考请求
关键字段名
prompt 是请求体里唯一的必填字段。input_image 装第一张参考图,input_image_2 装第二张,编号一直排到 input_image_8。FLUX.2 [pro] 的 API 参考文档正好列了这八个字段;[klein] 4B 的参考文档只到 input_image_4,并把这个模型描述为「like Pro but max 4 images」,也就是和 Pro 一样但最多四张。按四张参考图去组装请求体,两个档位都能通过校验。
width 和 height 是整数,官方给出的最小值是 64。seed、取值 0 到 5 的 safety_tolerance、可为 jpeg、png 或 webp 的 output_format、webhook_url 与 webhook_secret 都是可选项,user 用来传一个 1 到 256 字符的终端用户标识。
有一处空白值得提前安排:官方请求体里没有 negative_prompt 字段。凡是你不想要的东西,都只能写进对目标画面的正面描述里。
# 需要 curl 和 jq。BFL_API_KEY 从 dashboard.bfl.ai 获取。
API_BASE="https://api.bfl.ai/v1"
MODEL="flux-2-pro-preview"
response=$(curl -s -X POST "${API_BASE}/${MODEL}" \
-H "x-key: ${BFL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Keep the room from image 1, place the chair from image 2 on the rug from image 3, keep the chair proportions and the rug pattern, warm afternoon light.",
"input_image": "https://example.com/room.jpg",
"input_image_2": "https://example.com/chair.jpg",
"input_image_3": "https://example.com/rug.jpg",
"width": 1024,
"height": 1024,
"output_format": "png"
}')
polling_url=$(echo "${response}" | jq -r .polling_url)
while true; do
sleep 0.5
result=$(curl -s "${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
curl -sL -o edit.png "$(echo "${result}" | jq -r .result.sample)"
break
elif [ "${status}" = "Error" ] || [ "${status}" = "Failed" ]; then
echo "Generation failed: ${result}"
break
fi
done
在提示词里指代每张图
多参考图指南用一句话把规则说完了:把每张图承担的角色讲清楚,模型才知道该从哪儿取什么。它给出的推荐写法相当直白,比如「Change image 1 to match the style of image 2」。
也正因为如此,字段顺序本身就是提示词的一部分。一句「用第 5 张图里的木料」,只有在你确实把木料放在第五位的时候才成立。
指南还列了一串该避开的说法:Make it better、Improve the lighting、Make it more professional、Fix the image。这些句子的毛病是同一个——让模型去猜你想要的目标状态。

Create a house for the chickens from image 1 using materials from images 2, 3, 4, and 5. Use the wood from image 5 for the base, the materials from images 2 and 4 for the walls and floor, and the material from image 3 for a small pillow nest. Place the chickens from image 1 in their new home, sitting on the pillow nest. Next to them, include the eggs from image 6. Apply the style of image 1 to the entire new scene.
这段提示词来自官方编辑示例页。每张参考图都有一个编号、一种材质和一个去处,这就是生产环境里的编辑提示词该有的样子。
会轮询并保存结果的 Python 客户端
放进服务里时,提交和轮询应该待在同一个函数中,这样十分钟的窗口不会被错过。
import os
import time
import requests
API_BASE = "https://api.bfl.ai/v1"
MODEL = "flux-2-pro-preview"
HEADERS = {
"accept": "application/json",
"x-key": os.environ["BFL_API_KEY"],
"Content-Type": "application/json",
}
def edit(prompt: str, references: list[str], width: int = 1024, height: int = 1024) -> bytes:
payload = {"prompt": prompt, "width": width, "height": height}
# input_image, input_image_2, ... input_image_8
for index, url in enumerate(references[:8], start=1):
key = "input_image" if index == 1 else f"input_image_{index}"
payload[key] = url
response = requests.post(f"{API_BASE}/{MODEL}", headers=HEADERS, json=payload, timeout=30)
response.raise_for_status()
polling_url = response.json()["polling_url"]
for _ in range(120):
time.sleep(0.5)
result = requests.get(polling_url, headers=HEADERS, timeout=30).json()
status = result["status"]
if status == "Ready":
sample = requests.get(result["result"]["sample"], timeout=60)
return sample.content
if status in ("Error", "Failed"):
raise RuntimeError(result)
raise TimeoutError("no result after 120 polls")
with open("edit.png", "wb") as handle:
handle.write(
edit(
"Keep the room from image 1, place the chair from image 2 on the rug from image 3, warm afternoon light.",
[
"https://example.com/room.jpg",
"https://example.com/chair.jpg",
"https://example.com/rug.jpg",
],
)
)
两处细节决定了它的可靠程度。参考图列表在建字段之前就被切到八张,列表过长时是降级而不是校验失败;下载放在轮询循环内部,签名链接还在有效期内。
API 文档写明的限额
参考图数量不是一个固定数字。总览页给出的上限是:[klein] 四张,[max]、[pro] 和 [flex] 走 API 八张、在 playground 十张,[dev] 是建议最多六张。到了 [pro] 这一档,数量还会随输出尺寸变化,因为 9 MP 的预算是输入加输出一起算的:
| [pro] 的输出尺寸 | 9 MP 预算允许的参考图 |
|---|---|
| 1 MP | 最多 8 张 |
| 2 MP | 最多 7 张 |
| 3 MP | 最多 6 张 |
提示词增强也分档位。[pro] 和 [max] 默认会改写你的提示词,并提供了 disable_pup 来关掉;[klein] 完全不带提示词增强,所以总览页才反复提醒这一档要写得更细。编辑计费写在价格页上,FLUX.2 API 价格一文里整理过。
轮询状态在 Get Result 页面上有完整枚举:Task not found、Pending、Reasoning、Generating、Request Moderated、Content Moderated、Ready 和 Error。审核态不是你的请求体写错了,原样重发也过不去。
如果你操心的是提示词而不是管道,FLUX.2 提示词指南讲了结构和十六进制配色;当你开始拿别的模型来比同一次编辑,可以看与 Nano Banana Pro 的对比。
官方页面没有交代的部分
本文查阅的文档页里,没有成功率、没有中位延迟,也没有按国家或地区拆分的可用性说明。免费 API 额度同样不存在:playground 不需要注册也不需要绑卡,但它是演示,不是额度。
文件处理也是空白。API 参考把每个字段称为输入图的路径,官方示例传的是公网 URL,但文件体积上限、可接受的 MIME 类型和参考图的保存策略都没有公布。
稳妥的做法很无聊但有效:把模型 ID 写进配置,把密钥放进密钥管理服务,并在创建任务的那一次运行里把图片取回来。
常见问题
FLUX.2 有专门的图像编辑端点吗? 没有。编辑和生成共用 /v1/flux-2-pro-preview 或 /v1/flux-2-pro,只是在请求体里加了 input_image 系列字段。
一次请求能带几张参考图? [klein] 四张,[max]、[pro]、[flex] 走 API 八张、playground 十张,[dev] 六张。在 [pro] 上,9 MP 的输入加输出预算会随着输出变大而压低这个上限。
能传负向提示词吗? 官方请求体里没有 negative_prompt 字段。想排除什么,就改成对目标状态的正面描述。
一定要轮询吗? 是。提交的响应只返回 polling_url,只有状态变成 Ready 之后才有 result.sample。
结果链接有效期多久? 十分钟。下载要在同一次运行里完成。