Skip to content

图片任务 API

异步图片生成与编辑接口:提交任务 → 轮询状态 → 下载成品。同一个入口 POST /api/v1/image-tasks 同时支持文生图图生图(编辑),并支持一次传多张参考图(多图编辑)

启用条件

绑定的 API Key 必须属于一个 OpenAI 平台分组,且该分组同时开启了「图片生成」和「图片任务 API」。

鉴权

http
Authorization: Bearer <你的 API Key>

POST /api/v1/image-tasks 还必须带幂等键:

http
Idempotency-Key: <每次请求唯一的字符串>

同一个幂等键 + 相同的请求体会返回已存在的任务(不重复生成/扣费)。response_format 在内部会被归一化,所以只改 response_format 仍命中同一任务;改其它字段会返回 409

提交任务

服务端会自动判断:请求里没有图 → 走文生图;带了 image(可选 mask)→ 走图生图编辑。 客户端只用这一个入口,无需声明意图。不支持 stream

文生图(不带输入图)

json
{
  "model": "gpt-image-2",
  "prompt": "赛博修真风格头像,霓虹,放松氛围",
  "size": "1024x1024",
  "n": 1,
  "response_format": "url"
}

图生图 / 多图编辑(带输入图)

三种格式任选其一,image 都可以是单张或多张:

① JSON + 图片 URL(服务端转发时自动下载):

json
{
  "model": "gpt-image-2",
  "prompt": "给主体加一圈霓虹光环",
  "image": "https://your-cdn/source.png",
  "size": "1024x1024"
}

② JSON + base64 / dataURL(本地图,无需公网 URL):

json
{
  "model": "gpt-image-2",
  "prompt": "去掉背景",
  "image": "data:image/png;base64,iVBORw0KGgo...",
  "mask": "data:image/png;base64,iVBORw0KGgo..."
}

③ 多张参考图:image字符串数组即可(URL / base64 混用都行):

json
{
  "model": "gpt-image-2",
  "prompt": "把这几张图融合成一张海报",
  "image": [
    "https://your-cdn/a.png",
    "data:image/png;base64,iVBORw0KGgo...",
    "https://your-cdn/c.jpg"
  ],
  "size": "1024x1536"
}

④ multipart 上传(与 OpenAI /v1/images/edits 的 form-data 一致):

http
POST /api/v1/image-tasks
Content-Type: multipart/form-data; boundary=...
Authorization: Bearer <你的 API Key>
Idempotency-Key: order-10001-image-1

表单字段:modelprompt、可选 size/n/quality、文件 [email protected]、可选 [email protected]多张参考图:重复 image[][email protected] 多个文件部分(也接受 image[0]=@...image[1]=@... 这种带下标的名字)。

三种格式落库时都会归一化成同一份 JSON,幂等哈希在归一化之后计算:同一批图片不论走 multipart 还是 base64,视为同一请求(URL 形式按 URL 文本独立哈希,不下载后再比)。

请求体字段

字段含义说明
model模型名gpt-image-2gpt-image-1
prompt提示词文生图必填;编辑时描述要做的改动
image输入图字符串或字符串数组;URL / base64 / dataURL 均可。多张=数组(多图编辑)
mask蒙版可选,作用于第一张 image;不能单独传 mask
size输出尺寸见下「尺寸与宽高比」。透传上游,按尺寸计费
n生成张数默认 1。n>1 需分组账号支持(高级能力)
quality质量透传上游(如 high/medium/low,依模型而定)
response_format返回形态url(返回本地文件链接)或 b64_json(内联 base64)

尺寸与宽高比

size宽x高 即可,支持任意宽高比(方/横/竖屏)。服务端按最长边归入计费档: ≤1024 = 1K,≤2048 = 2K,更大 = 4K(也接受直接写 1k/2k/4kauto)。常用值:

比例1K2K4K
1:1 方形1024x10242048x2048
16:9 横屏1792x10242048x11523840x2160
9:16 竖屏1024x17921152x20482160x3840
3:2 / 2:31536x1024 / 1024x1536
4:3 / 3:41024x768 / 768x1024

一次请求只能指定一个 size(OpenAI 协议如此)。需要多个规格 = 用不同 size 多发几次请求; 需要多张同尺寸结果 = 用 n

提交返回

json
{
  "object": "image_task",
  "task_id": "imgtask_4d89a5f68d2e44d4a1ab6b6e4a7b12e9",
  "status": "queued",
  "model": "gpt-image-2",
  "image_size": "1K",
  "image_count": 1,
  "billing": { "status": "not_billed", "customer_cost": 0.04 },
  "created_at": "2026-05-15T12:00:00Z"
}

轮询任务

http
GET /api/v1/image-tasks/{task_id}
Authorization: Bearer <你的 API Key>

成功后按你提交时的 response_format 返回。response_format: "url" 时:

json
{
  "status": "succeeded",
  "image_size": "1K",
  "image_count": 1,
  "billing": { "status": "settled", "customer_cost": 0.04 },
  "result": {
    "created": 1780000000,
    "data": [{ "url": "https://你的站点/api/v1/image-tasks/imgtask_4d.../files/0.png" }]
  }
}

省略或 b64_json 时,data 内联返回 { "b64_json": "iVBORw0KGgo..." }

下载图片文件

http
GET /api/v1/image-tasks/{task_id}/files/{idx}.{ext}
Authorization: Bearer <你的 API Key>
  • idx:data[] 里的序号,从 0 开始;ext:png/jpg/jpeg/webp/gif
  • 与轮询同样校验 API Key 归属;带 ETagCache-Control: private

保留期与过期

成品落本地磁盘,默认保留 3 天、总容量上限 1 GiB,先到者触发清理,最老任务被删、状态转 expired:

json
{ "status": "expired", "error": { "code": "expired", "message": "image files have been deleted by retention policy" } }

请在窗口内下载/转存。极少数情况下上游成功+已扣费但本地落盘失败,任务为 succeeded_storage_failed

Python 完整示例(多图编辑 + 指定尺寸 + 轮询下载)

下面这段已实测跑通:读本地多张图 → 多图编辑 → 轮询到成功 → 下载成品。

python
import base64, mimetypes, time, uuid, requests

BASE = "https://hub.nocannobb.com"
KEY  = "sk-你的Key"

s = requests.Session()
s.headers.update({
    "Authorization": f"Bearer {KEY}",
    # 若脚本被 Cloudflare 拦(返回 error 1010),带一个常规 User-Agent 即可
    "User-Agent": "Mozilla/5.0",
})

def data_url(path):
    mime = mimetypes.guess_type(path)[0] or "image/jpeg"
    with open(path, "rb") as f:
        return f"data:{mime};base64," + base64.b64encode(f.read()).decode()

payload = {
    "model": "gpt-image-2",
    # 多张参考图就传数组(URL 或 base64/dataURL 混用都行)
    "image": [data_url("a.jpg"), data_url("b.jpg"), data_url("c.jpg")],
    "prompt": "把这几款浴巾整齐挂在原木晾杆上,暖调婴儿房背景,柔和治愈。"
              "不要出现:水印、错误文字、混乱背景。",
    "size": "1024x1536",          # 任意 宽x高;竖屏/横屏/方形都行
    "n": 1,
    "response_format": "url",
}

# 提交(每次唯一 Idempotency-Key)
r = s.post(f"{BASE}/api/v1/image-tasks", json=payload,
           headers={"Idempotency-Key": str(uuid.uuid4())})
task_id = r.json()["task_id"]
print("task_id:", task_id)

# 轮询到终态
while True:
    time.sleep(4)
    t = s.get(f"{BASE}/api/v1/image-tasks/{task_id}").json()
    print("status:", t["status"])
    if t["status"] in ("succeeded", "failed", "expired", "succeeded_storage_failed"):
        break

# 下载成品
for i, d in enumerate(t.get("result", {}).get("data", [])):
    if d.get("url"):
        img = s.get(d["url"]).content
        open(f"out_{i}.png", "wb").write(img)
        print("saved out_%d.png" % i)

文生图(不带 image)把 image 字段去掉即可,其余相同。

避坑

  • 多张图就用 image 数组(或 multipart 重复 image[])——不是只能传一张。
  • 负面词不要用 --no:gpt-image 不认 Midjourney 语法,写成自然语言「不要出现 X」才有效。
  • 精确版式靠后期:gpt-image 擅长场景/风格/构图,但「把文字放到某个角」「预留 logo 区域」这类像素级排版不保证执行,建议出图后用设计工具叠加 logo/文字。
  • 不是同步直返:提交拿 task_id,要轮询到 succeeded 再取 result/下载,别期望提交就返回图。
  • size宽x高,任意比例都行;一次一个 size,多规格就多发请求。
  • mask 必须配 image 一起传,不能单独传。
  • 每次提交必须带唯一 Idempotency-Key;复用同键+同体会返回旧任务。