# POST /v1/images/*

OpenAI Images 兼容接口，支持 GPT Image 系列模型生成图片或基于参考图改图。使用方式和 OpenAI SDK 基本一致：把 `base_url` 指到 4AICode，把 `api_key` 换成你的 `sk-4ai-...` Token。

图片生成按次从钱包余额扣费。控制台的 [图片生成](/images) 页面适合手动使用；API 适合接入自己的应用、工作流和自动化脚本。

新项目推荐优先使用 GPT Image 2.5：`gpt-image-2.5-sunburst` 适合对生成质量和编辑精度要求高的场景；`gpt-image-2.5-flare` 是高质量日常生图的高速选择。已有集成仍可继续使用 `gpt-image-2`。

## 端点

```text
POST https://relay.4aicode.net/v1/images/generations
POST https://relay.4aicode.net/v1/images/edits
```

## 支持的模型

| 模型 | 用途 | 计费 |
|---|---|---|
| `gpt-image-2.5-sunburst` | GPT Image 2.5 能力最强，适合高质量生成和精细改图 | 按次从钱包扣费 |
| `gpt-image-2.5-flare` | GPT Image 2.5 高质量高速款，适合日常生图和追求更快响应的场景 | 按次从钱包扣费 |
| `gpt-image-2` | 通用文本生图、参考图改图 | 按次从钱包扣费 |

管理员为对应模型配置按次费率并启用、在上游模型集中选中该模型后可用。模型未启用时会返回 `503 model_unavailable`。

## 文本生图

### curl

```bash
curl https://relay.4aicode.net/v1/images/generations \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2.5-sunburst",
    "prompt": "A clean product shot of a black mechanical keyboard on a white desk",
    "size": "1024x1024",
    "quality": "medium",
    "response_format": "b64_json"
  }'
```

### Python

```python
import base64
from openai import OpenAI

client = OpenAI(
    base_url="https://relay.4aicode.net/v1",
    api_key="sk-4ai-xxxxxxxxxxxxxxxx",
)

resp = client.images.generate(
    model="gpt-image-2.5-sunburst",
    prompt="A clean product shot of a black mechanical keyboard on a white desk",
    size="1024x1024",
    quality="medium",
    response_format="b64_json",
)

image_base64 = resp.data[0].b64_json
with open("keyboard.png", "wb") as f:
    f.write(base64.b64decode(image_base64))
```

### TypeScript

```ts
import fs from "node:fs";
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://relay.4aicode.net/v1",
  apiKey: process.env.OPENAI_API_KEY,
});

const resp = await client.images.generate({
  model: "gpt-image-2.5-sunburst",
  prompt: "A clean product shot of a black mechanical keyboard on a white desk",
  size: "1024x1024",
  quality: "medium",
  response_format: "b64_json",
});

const image = resp.data[0]?.b64_json;
if (!image) throw new Error("image generation failed");
fs.writeFileSync("keyboard.png", Buffer.from(image, "base64"));
```

## 参考图改图

`/v1/images/edits` 支持两种输入方式：

- `multipart/form-data`：字段名用 `image` 或 `image[]` 上传文件，单文件最大 20MB。
- `application/json`：`images[].image_url` 传 base64 data URL 或可访问的图片 URL。

### multipart curl

```bash
curl https://relay.4aicode.net/v1/images/edits \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -F model="gpt-image-2.5-sunburst" \
  -F prompt="Keep the product, replace the background with a bright studio setup" \
  -F size="1024x1024" \
  -F quality="medium" \
  -F response_format="b64_json" \
  -F image="@./product.png"
```

多张参考图：

```bash
curl https://relay.4aicode.net/v1/images/edits \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -F model="gpt-image-2.5-sunburst" \
  -F prompt="Combine these references into one cohesive hero image" \
  -F image[]="@./subject.png" \
  -F image[]="@./style.png"
```

### JSON data URL

```bash
IMAGE_B64="$(base64 < product.png | tr -d '\n')"

curl https://relay.4aicode.net/v1/images/edits \
  -H "Authorization: Bearer sk-4ai-xxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"gpt-image-2.5-sunburst\",
    \"prompt\": \"Put this product in a premium ecommerce scene\",
    \"size\": \"1024x1024\",
    \"quality\": \"medium\",
    \"response_format\": \"b64_json\",
    \"images\": [
      { \"image_url\": \"data:image/png;base64,${IMAGE_B64}\" }
    ]
  }"
```

`file_id` 当前会返回明确错误。需要 mask 时用 `mask` 文件字段，或在 JSON 里传 `mask.image_url`。

## 参数

| 参数 | 适用端点 | 说明 |
|---|---|---|
| `model` | 全部 | 使用上表中已启用的模型 ID |
| `prompt` | 全部 | 生成或编辑指令，必填 |
| `size` | 全部 | `auto`、`1024x1024`、`1536x1024`、`1024x1536` |
| `quality` | 全部 | `auto`、`low`、`medium`、`high`；GPT Image 2.5 另支持 `xhigh`、`max` |
| `response_format` | 全部 | `b64_json` 或 `url`；`url` 返回 data URL |
| `output_format` | 全部 | `png`、`jpeg`、`webp` |
| `background` | 全部 | 透传给上游图片工具 |
| `output_compression` | 全部 | 输出压缩比例，适用于支持压缩的格式 |
| `stream` | 全部 | `true` 时返回 SSE |
| `partial_images` | 全部 | 流式模式下请求部分图片事件 |
| `image` / `image[]` | edits | multipart 参考图 |
| `images[].image_url` | edits | JSON 参考图 URL 或 data URL |
| `mask` / `mask.image_url` | edits | 可选蒙版 |
| `input_fidelity` | edits | 参考图保真度，透传给上游图片工具 |

## 响应

非流式返回 OpenAI Images 风格结构：

```json
{
  "created": 1770000000,
  "data": [
    {
      "b64_json": "iVBORw0KGgo...",
      "revised_prompt": "..."
    }
  ],
  "size": "1024x1024",
  "quality": "medium",
  "output_format": "png",
  "usage": {
    "images": 1
  }
}
```

`response_format=url` 时，`data[].url` 是 `data:image/png;base64,...`，图片内容直接在响应内返回。

## 流式响应

设置 `"stream": true` 后返回 SSE。

文本生图事件：

```text
event: image_generation.partial_image
data: {"type":"image_generation.partial_image","partial_image_index":0,"b64_json":"..."}

event: image_generation.completed
data: {"type":"image_generation.completed","b64_json":"...","usage":{"images":1}}
```

参考图改图事件前缀是 `image_edit`：

```text
event: image_edit.completed
data: {"type":"image_edit.completed","b64_json":"...","usage":{"images":1}}
```

## 计费与记录

每次成功生成按所选模型的当前单次价格扣费。用量页、钱包流水和后台 usage log 会记录模型、次数、费用、状态和 trace id。平台默认不保存你的 prompt 和图片正文。

## 常见错误

| HTTP | code | 处理方式 |
|---|---|---|
| 400 | `invalid_request_error` | 检查 `prompt`、`model`、图片字段和 multipart 格式 |
| 401 | `unauthorized` | 检查 `Authorization: Bearer sk-4ai-...` |
| 429 | `insufficient_quota` / `rate_limit` | 充值钱包或降低并发 |
| 503 | `model_unavailable` | 联系管理员启用所选图片模型的单次费率 |
| 502 | `upstream_error` | 稍后重试；持续失败时带 trace id 联系支持 |
