# GPT Image 2 — /images/generations

GPT Image 2 生图接口，异步任务：提交后立刻返回任务号（HTTP 202），再查询结果或等 Webhook 推送。文生图只需要 `prompt`；带上参考图就是图生图。支持 1K / 2K / 4K 三档、任意比例，按张计费，失败不收费。

**端点:** `POST https://nezhagate.com/v1/images/generations`

## 快速开始

三步跑通：提交任务 → 查询结果 → 拿到图片链接。把 YOUR_API_KEY 换成你的 Key，下面的命令可以直接运行。

**第 1 步 · 提交任务（立刻返回任务号，HTTP 202）**

```
curl https://nezhagate.com/v1/images/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-image-2", "prompt": "咖啡馆菜单海报，标题写“秋季限定”，列出三款饮品和价格，排版整洁", "size": "16:9", "resolution": "2K"}'
```

返回（HTTP 202）

```
{
  "id": "img_7f3c9a1e2b4d6f8a0c1e3b5d",
  "object": "image.generation.job",
  "status": "queued",
  "created": 1791281400,
  "model": "gpt-image-2"
}
```

**第 2 步 · 每 2–3 秒查询一次，直到 `status` 变成 `succeeded` 或 `failed`**

```
curl https://nezhagate.com/v1/images/jobs/img_7f3c9a1e2b4d6f8a0c1e3b5d \
  -H "Authorization: Bearer YOUR_API_KEY"
```

成功时的返回

```
{
  "id": "img_7f3c9a1e2b4d6f8a0c1e3b5d",
  "object": "image.generation.job",
  "status": "succeeded",
  "created": 1791281400,
  "model": "gpt-image-2",
  "data": [
    {"url": "https://img.nezhagate.com/i/2be8cd16d37f3a4b9c0e1f2a3b4c5d6e.png"}
  ],
  "usage": {"images": 1, "resolution": "2K", "model": "gpt-image-2"}
}
```

**第 3 步 · `data[0].url` 就是图片链接（PNG），保留 15 天；需要长期使用，请下载到你自己的存储。**

**完整示例（Python：提交 → 等待 → 保存到本地）**

```
import time
import requests

BASE = "https://nezhagate.com/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}

# 1. 提交任务
job = requests.post(f"{BASE}/images/generations", headers=HEADERS, json={
    "model": "gpt-image-2",
    "prompt": "咖啡馆菜单海报，标题写“秋季限定”，列出三款饮品和价格，排版整洁",
    "size": "16:9",
    "resolution": "2K",
}).json()
if "error" in job:
    raise SystemExit(job["error"]["message"])

# 2. 每 3 秒查询一次，直到结束
while job["status"] not in ("succeeded", "failed"):
    time.sleep(3)
    job = requests.get(f"{BASE}/images/jobs/{job['id']}", headers=HEADERS).json()

# 3. 下载图片
if job["status"] == "succeeded":
    url = job["data"][0]["url"]
    with open("gpt-image-2.png", "wb") as f:
        f.write(requests.get(url).content)
    print("saved", url)
else:
    print("failed:", job["error"]["code"], job["error"]["message"])
```

## 认证
```
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
```

## 请求参数

`POST /v1/images/generations` 的请求体（JSON）：

| 参数 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| model | string | 是 | 模型 id：`gpt-image-2`。 |
| prompt | string | 是 | 画面描述。图生图时写清楚要怎么改。 |
| size | string | 否 | 比例，例如 `16:9`（推荐），也可以写像素尺寸，例如 `1536x1024`。不传时出 1:1 方图。 |
| resolution | string | 否 | 档位：`1K`（默认）、`2K`、`4K`。 |
| quality | string | 否 | 画质档，只在 1K 生效：`low`、`medium`（默认）或 `high`；2K 和 4K 一律按 medium 出图，其他值也按 medium 处理。不影响价格，详见下面的「画质与原生分辨率」。 |
| image / images | string / array | 否 | 参考图，传了就是图生图：`image` 传一张，`images` 传多张（最多 8 张）。可以是公网图片链接、data: URI 或 base64。 |
| n | integer | 否 | 张数。建议不传：要多张图请同时提交多个任务。传了 `n` 时按 n 张预扣，按实际交付的张数结算。 |
| callback_url | string | 否 | 任务结束时把结果推送到这个地址，见下文的 Webhook。 |

其他 OpenAI 参数（如 `background`、`output_format`、`response_format`、`style`）不影响价格，也不保证生效；成片一律是 PNG，通过 `url` 返回。

## 价格

按张计费，价格只看档位，跟比例、文生图还是图生图无关。提交时按档位预扣，任务失败全额退回。1 积分 = $0.005。

| 档位 | 积分 / 张 | 美元 / 张 |
| --- | --- | --- |
| 1K | 1 | $0.005 |
| 2K | 5 | $0.025 |
| 4K | 8 | $0.04 |

## 比例、分辨率与输出尺寸

`size` 写比例，`resolution` 写档位。交付的图片严格按下表的尺寸：长边由档位决定，另一边按比例换算。表里没有的比例也可以用，规则相同。

| 比例 | 1K | 2K | 4K |
| --- | --- | --- | --- |
| 1:1 | 1024x1024 | 2048x2048 | 4096x4096 |
| 3:4 | 768x1024 | 1536x2048 | 3072x4096 |
| 2:3 | 683x1024 | 1365x2048 | 2731x4096 |
| 9:16 | 576x1024 | 1152x2048 | 2304x4096 |
| 4:3 | 1024x768 | 2048x1536 | 4096x3072 |
| 3:2 | 1024x683 | 2048x1365 | 4096x2731 |
| 16:9 | 1024x576 | 2048x1152 | 4096x2304 |

- 1K 档：模型按最接近的横版、竖版或方形构图出图，网关再居中裁切、缩放到上表的尺寸，所以比例离 3:2、2:3、1:1 越远，边缘裁掉得越多。网关会在提示词后补一句英文的比例说明，让主体尽量完整、居中；要保证边缘的内容，把它写在画面中部。

- 原生出图的档位（见下面的「画质与原生分辨率」）直接按你要的比例出图，边缘不会被裁掉。

- `size` 也可以写像素尺寸（如 `1536x1024`），按所写的尺寸交付（长边超过 4096 时等比缩小）。这时档位按 `resolution` 定；没写 `resolution` 时看长边：不超过 1536 为 1K，不超过 2048 为 2K，更大为 4K。`resolution` 只能把档位调高、不能调低，也不改变交付尺寸，所以别把小尺寸和高档位写在一起。

## 画质与原生分辨率

- 不传 `quality` 时按 OpenAI 的 **medium** 档出图。1K 可以选 `low`、`medium` 或 `high`，文生图和图生图都生效；**2K 和 4K 一律按 medium 出图**。`auto`、`xhigh`、`max` 等其他值都按 medium 处理，不会报错。价格只看分辨率档，和 `quality` 无关。

- `quality` 写成 `1K`、`2K` 或 `4K`、又没传 `resolution` 时，按分辨率档处理（出图尺寸和价格都按这一档）。

- **1K**：模型按自己的原生画幅出图（约 157 万像素，方图 1254×1254），网关再缩放到上面表里的尺寸。

- **2K 和 4K**：按你要的比例原生出图，单边最多 3840 像素、总像素约 830 万以内：2K 方图直接出 2048×2048，4K 的 16:9 出 3840×2160、方图出 2880×2880。表里的 4K 尺寸超出这个上限的部分由网关放大补齐（16:9 每边约 7%，越接近方形放大越多）；想拿到原生像素，`size` 直接写上限以内的像素尺寸，例如 `3840x2160`。

- 原生出图的档位只走原生线路：线路忙时任务排队等候，实在出不了图就失败并全额退款，不会拿 1K 图放大来交差。

- 1K 偶尔由备用线路完成，这时 `quality` 不一定生效。

## 图生图与参考图

- 传 `image`（一张）或 `images`（多张，最多 8 张，多出的不用）就是图生图，在提示词里写清楚要怎么改。也可以调用 `POST /v1/images/edits`，参数相同。

- 两个接口都只收 JSON 请求体，不支持 multipart 上传文件，所以 OpenAI SDK 的 `images.edit()` 不能直接用，请按下面的示例传链接或 base64。

- 每张参考图可以是公网图片链接（http / https）、data: URI 或纯 base64，单张不超过 16MB，JPEG、PNG、WebP 等常见格式都可以。

- 链接要能直接下载到图片本身，不能是网页、需要登录或有防盗链的地址。读不到的参考图会在提交时直接返回 400，写明是哪一张、什么原因，不建任务、不扣费。

- 输出比例由 `size` 决定，不跟随参考图；想保持原图比例，就把 `size` 设成和原图一样的比例。

- 参考图由我们代为托管，保留 7 天。

**两张参考图的图生图**

```
curl https://nezhagate.com/v1/images/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-image-2", "prompt": "保留画面里的人物，把背景换成夜晚的海边，加上暖色的灯串", "images": ["https://example.com/people.jpg", "https://example.com/beach.jpg"], "size": "3:4", "resolution": "2K"}'
```

## 任务状态与返回字段

`GET /v1/images/jobs/{id}` 返回的状态如下，每个字段的说明见 [异步任务](https://nezhagate.com/docs/guide/async-jobs#fields)。建议每 2–3 秒查一次，或者用 Webhook。

| 状态 | 含义 |
| --- | --- |
| queued | 排队中。返回里带 `queue_position`（前面还有几个任务）和 `eta_seconds`（预计等待秒数）。 |
| processing | 生成中。 |
| succeeded | 已完成。结果在 `data[0].url`，计费明细在 `usage`。 |
| failed | 失败。原因在 `error`，预扣的积分已全额退回。 |

同一个账号最多 50 个任务同时生成，更多的任务按提交顺序排队；排队超过 15 分钟还没开始的任务会自动失败并全额退款。任务记录保留 3 天，图片链接保留 15 天。

## 出图时间

从提交到拿到结果：1K 通常 20–60 秒；2K 和 4K 是原生出图，通常 30–120 秒。图生图和多张参考图会更久，个别任务在自动换线重试时要几分钟。

近 7 天真实调用：中位 25 秒，90% 在 42 秒 内完成。

## 错误与退款

提交时出错会直接返回 HTTP 4xx / 5xx，不建任务、不扣费；提交成功后的失败写在查询结果里，预扣的积分全额退回。全部错误码见 [错误码](https://nezhagate.com/docs/guide/errors)。

### 提交时返回的错误

| HTTP | code | 原因 | 怎么办 |
| --- | --- | --- | --- |
| 400 | missing_prompt | `/v1/images/generations` 没有 `prompt`。 | 补上 `prompt`。 |
| 400 | invalid_request | 参考图读不到（链接打不开、不是图片、超过 16MB 等，`message` 写明是第几张、什么原因），`/v1/images/edits` 没带参考图，或请求体不是 JSON 对象、`n` 不是整数。 | 按 `message` 修改后重新提交。 |
| 400 | model_not_found | 型号写错、没有传 `model`，或这个型号不能用在这个接口上（例如拿对话模型调生图接口）。 | 以 `GET /v1/models` 或 [API 手册](https://nezhagate.com/docs/api) 里的模型 id 为准。 |
| 401 | invalid_api_key | Key 不存在、已删除或已停用，或者账号已停用。 | 到控制台「API Keys」页面检查这把 Key。 |
| 402 | insufficient_quota | 余额不够预扣这一单。网关先按这一单可能的最高费用预扣，同时发很多请求时也可能出现。 | 如果是并发突发，稍等几秒重试；否则充值。 |
| 429 | rate_limit_exceeded | 超过了这把 Key 设置的每分钟请求数（按最近 60 秒计）。不带 `Retry-After`。 | 等几秒再试，或在控制台调高这把 Key 的上限。 |
| 503 | model_maintenance | 型号维护中，暂停接单，期间不会改由其他模型作答。 | 维护结束后重试，进度见 [服务状态](https://nezhagate.com/status)。 |
| 503 | service_unavailable | 我们这边临时出错，例如保存参考素材失败；`/v1/responses` 暂时没有可用线路时也返回 503，并带 `Retry-After`。 | 稍后重试。 |

### 任务失败（`status` 为 `failed`）

| code | 什么时候出现 | 怎么办 |
| --- | --- | --- |
| moderation_blocked | 图片：模型方的安全审核拒绝了提示词或参考图（也可能是 `content_policy_violation`）。 | 改写提示词或更换参考图；原样重交通常还会被拒。 |
| upstream_error | 其他失败：所有线路都试过仍然失败、排队 15 分钟还没开始、上游拒绝但没有说明原因等，`message` 写明具体情况。 | 通常重新提交就能成功。 |

## 用 Webhook 代替轮询

提交时加上 `callback_url`，任务一结束（成功或失败），网关就把和查询接口完全一样的结果推送到这个地址，带签名，失败会自动重试。也可以在控制台「设置 → Webhook」里配一个账户级地址。 [Webhook 文档 →](https://nezhagate.com/docs/webhooks)

```
curl https://nezhagate.com/v1/images/generations \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-image-2", "prompt": "咖啡馆菜单海报，标题写“秋季限定”，列出三款饮品和价格，排版整洁", "size": "1:1", "callback_url": "https://your-domain.com/webhook"}'
```
