图片 API 对接文档从第一次调用,到稳定集成。
用一套 OpenAI 兼容接口完成文字生图、参考图编辑,以及异步任务交付。本文只描述 OraImg 当前对外开放能力。
开始接入
从一张图片开始,逐步接入同步生成与异步轮询。
使用 HTTP + JSON;文件上传编辑可使用 multipart/form-data。示例模型为 gpt-image-2,实际可用模型以 GET /v1/models 和控制台分组权限为准。
| 场景 | 接口 | 返回方式 |
|---|---|---|
| 文生图(同步) | POST /v1/images/generations | 同步 JSON |
| 文生图(异步) | POST /v1/images/generations/async | HTTP 202 + task_id |
| 图生图 / 编辑(同步) | POST /v1/images/edits | 同步 JSON |
| 图生图 / 编辑(异步) | POST /v1/images/edits/async | HTTP 202 + task_id |
| 查询异步任务 | GET /v1/images/tasks/{task_id} | 任务状态及结果 |
| 获取模型列表 | GET /v1/models | 当前可用模型 |
获取 Base URL 与 API Key
在 Sub2API 控制台创建并复制密钥。Base URL 与 Key 必须来自同一接入平台。
- 打开控制台:https://agent1.oraimg.com/
- 进入左侧 API Keys。
- 点击右上角 Create API Key 创建密钥;已有密钥则找到对应行。
- 在列表上方 API Endpoints 区域复制 Base URL。
- 点击目标 API Key 旁的复制图标,获取完整密钥。请确认所选分组与模型权限符合生图需求。
地址与鉴权
所有示例请替换为你自己的 Key。推荐主地址:
export BASE_URL="https://agent1.oraimg.com/v1"
export API_KEY="sk-xxxxxxxx"
# 备用(若主地址不可用):
# export BASE_URL="https://api.oraimg.com/v1"
# export BASE_URL="https://s2a.novaryns.com/v1"
BASE_URL 已含末尾 /v1。下面 curl 示例路径写 $BASE_URL/images/...,不要再拼一次 /v1。若 SDK 要求填写 base_url,保留 .../v1 即可。| 操作 | 是否需要 Key | 说明 |
|---|---|---|
| 生图、编辑、模型列表 | 是 | Authorization: Bearer $API_KEY |
| 查询异步任务 | 是 | 必须使用提交任务时的同一 API Key;换 Key 会 404 |
| 下载返回的图片 URL | 否 | 持有完整 URL 即可读取;链接请妥善保管 |
查询可用模型
接入前先用 Key 验证连通性,再选择生图模型。
curl "$BASE_URL/models" \
-H "Authorization: Bearer $API_KEY"
当前生图常用模型:
| 模型 ID | 说明 |
|---|---|
gpt-image-2 | 默认文生图 / 图生图 |
gpt-image-2.5-flare | 图片模型 |
gpt-image-2.5-sunburst | 图片模型 |
模型可用性以实际 /v1/models 返回及控制台分组权限为准。文字模型(如 gpt-6-astra 等)走 Chat Completions,不在本文展开。
文生图(同步)
根据文字描述生成图片。没有参考图时使用此接口。请求会同步等待直到出图或超时。
curl --max-time 300 "$BASE_URL/images/generations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "一只橘猫坐在窗边看雨,柔和自然光,水彩插画",
"n": 1,
"size": "1024x1024",
"response_format": "url"
}'
同步成功响应 · HTTP 200
{
"created": 1761610120,
"data": [
{
"url": "https://img.oraimg.com/…"
}
]
}
data 是数组,不要假设永远只有一张。也可设置 response_format: "b64_json" 获取 Base64。同步结果图通常托管在本站图片域名;请及时下载保存。
参数与尺寸
文生图与图生图共享大部分参数。
| 参数 | 类型 / 默认 | 说明 |
|---|---|---|
model | string · 建议必填 | 使用模型列表中的模型 ID,例如 gpt-image-2 |
prompt | string · 必填 | 非空文字描述;图生图请明确修改目标与需保留内容 |
n | integer · 1 | 生成张数;请传合法整数 |
size | string · 可选 | 1K / 2K / 4K,或显式宽高如 2048x2048、3840x2160;也可用 auto |
response_format | string · url | url 返回链接;b64_json 返回 Base64 |
quality | string · 可选 | 如 auto;具体档位由模型决定 |
尺寸写法
| 写法 | 目标像素 |
|---|---|
1K / 1024x1024 | 1024×1024 |
2K / 2048x2048 | 2048×2048 |
4K / 4096x4096 | 4096×4096 |
3840x2160 等显式 WxH | 按所写宽高 |
缺省 / auto / 非法 | 默认尺寸(约 1024×1024) |
"size":"2048x2048"。宽高之间用小写英文字母 x,不要写乘号 ×。同步、异步以及 edits 路径均适用上述尺寸字段。图生图 / 编辑
带参考图时应调用 edits 接口,不要向文生图接口附加图片字段。
curl --max-time 300 "$BASE_URL/images/edits" \
-H "Authorization: Bearer $API_KEY" \
-F "model=gpt-image-2" \
-F "prompt=保留人物,将背景替换为雪山" \
-F "image=@reference.png" \
-F "size=1024x1024"
JSON 方式也可提交可访问的图片 URL / Base64(字段兼容常见 OpenAI 写法)。成功响应结构与文生图相同。长任务请改用异步:
异步 edits 的受理与轮询规则与下方「异步任务」一致,请求体字段与同步 edits 相同。
异步任务
先提交任务拿到 task_id,再用同一 API Key 轮询结果。适合长任务和业务后端,可避免同步长连接超时。
- 鉴权
Authorization: Bearer $API_KEY- 请求体
- 与同步生图相同;不要开
stream
curl -i "$BASE_URL/images/generations/async" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "极简白色陶瓷花瓶产品摄影",
"n": 1,
"size": "2K"
}'
受理响应 · HTTP 202
{
"id": "imgtask_0123456789abcdef",
"task_id": "imgtask_0123456789abcdef",
"object": "image.generation.task",
"status": "processing",
"created_at": 1761610000,
"expires_at": 1761696400,
"poll_url": "/v1/images/tasks/imgtask_0123456789abcdef"
}
请持久化 task_id。202 只表示已受理,不等于出图成功。图生图异步路径为 POST /v1/images/edits/async。
查询与任务状态
- 鉴权
- 必须用提交任务时的同一 API Key
curl "$BASE_URL/images/tasks/$TASK_ID" \
-H "Authorization: Bearer $API_KEY"
进行中:
{
"id": "imgtask_0123456789abcdef",
"task_id": "imgtask_0123456789abcdef",
"object": "image.generation.task",
"status": "processing",
"created_at": 1761610000,
"expires_at": 1761696400
}
成功时 status 为 completed,图片在 result.data[].url(或顶层 image_url):
{
"task_id": "imgtask_0123456789abcdef",
"status": "completed",
"http_status": 200,
"image_url": "https://…",
"result": {
"created": 1761610120,
"data": [{ "url": "https://…" }]
},
"completed_at": 1761610120,
"expires_at": 1761696520
}
失败时 status 为 failed,读取 error.message。
| status | 含义 | 处理 |
|---|---|---|
processing | 排队或生成中 | 继续轮询 |
completed | 成功 | 保存 data[].url / image_url |
failed | 失败 | 记录 error,按业务决定是否重提 |
- 轮询间隔:优先遵循
Retry-After;默认每 3–5 秒一次 - 单任务最长约 30 分钟;结果约保留 24 小时
- 异步结果下载链接通常由对象存储签发,请在有效期内保存到自己的存储
- 换 Key 查询会 404;HTTP 200 只表示查询成功,必须再检查
status
计费说明
| 分组 | 用途 | 单价 |
|---|---|---|
| 分组 5 · Free | 免费池生图 | $0.005 / 张 |
| 分组 2 · Plus | Plus 池生图 | $0.01 / 张 |
按张计费,不按尺寸加价。账户充值按 1 USD = 1 CNY 入账显示。具体余额、分组与限速以控制台为准。
错误处理
同时记录 HTTP 状态、响应体中的 error,以及任务 ID(如有)。
{
"error": {
"message": "…",
"type": "invalid_request_error",
"code": "…"
}
}
| HTTP | 常见原因 | 处理建议 |
|---|---|---|
| 400 | 参数不合法 | 阅读 message,修改输入后重试 |
| 401 | Key 缺失或错误 | 核对 Authorization 与接入账号 |
| 404 | 模型 / 任务不存在,或换 Key 查任务 | 检查路径、模型列表与任务归属 Key |
| 429 | 限流 / 并发过高 | 降低并发并退避重试 |
| 502 / 503 / 504 | 网关或上游繁忙 / 超时 | 若已拿到 task_id,先查询;勿立即盲目重提 |
完整接入示例
Python · 异步文生图并轮询
import os, time
import requests
base = os.environ["BASE_URL"].rstrip("/")
headers = {"Authorization": "Bearer " + os.environ["API_KEY"]}
r = requests.post(
base + "/images/generations/async",
headers=headers,
json={
"model": "gpt-image-2",
"prompt": "极简白色陶瓷花瓶产品摄影",
"n": 1,
"size": "2K",
},
timeout=(10, 60),
)
r.raise_for_status()
if r.status_code != 202:
raise RuntimeError("Expected 202: " + r.text)
task_id = r.json()["task_id"]
print("task_id:", task_id)
deadline = time.monotonic() + 900
while time.monotonic() < deadline:
time.sleep(3)
q = requests.get(
base + f"/images/tasks/{task_id}",
headers=headers,
timeout=(10, 30),
)
if q.status_code in (429, 502, 503, 504):
time.sleep(5)
continue
q.raise_for_status()
task = q.json()
if task["status"] == "completed":
url = task.get("image_url") or task["result"]["data"][0]["url"]
img = requests.get(url, timeout=(10, 120))
img.raise_for_status()
open("result.png", "wb").write(img.content)
break
if task["status"] == "failed":
raise RuntimeError(task.get("error") or "failed")
else:
raise TimeoutError("本地等待结束;请继续用已保存的 task_id 查询")
cURL · 同步 4K
curl --max-time 300 "$BASE_URL/images/generations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "一只小狗在天上飞,电影感光影",
"n": 1,
"size": "4K"
}'
接入检查与常见问题
- 使用正确的
BASE_URL和 Key 拉取/v1/models。 - 以
n=1完成一次同步文生图,确认data[].url可下载。 - 再提交一次
/images/generations/async,保存task_id并轮询到completed。 - 验证
size为1K/2K/4K或显式宽高。 - 把最终图片保存到自己的存储,不长期依赖临时链接。
- 可在 在线测试页 快速验证。
收到 202,为什么还没有图片?
202 只表示任务已受理。等待 status=completed 后再读取 data / image_url。查询接口返回 HTTP 200 也可能仍是 processing。
同步超时后可以立即重新生成吗?
若已改用异步并拿到 task_id,先查询,不要立刻换参数重提。同步超时只说明客户端没拿到结果,上游可能仍在处理。
为什么换一个 Key 查不到任务?
任务与提交时的 API Key 绑定。必须使用同一 Key 查询,否则返回 404。
size 写 2K / 4K 可以吗?
可以。也支持 2048x2048、4096x4096、3840x2160 等显式宽高。
图片下载链接会过期吗?
会。异步结果链接通常有有效期(约 24 小时量级),请尽快转存。同步图也请自行保留副本。
网页报 CORS,但后端调用正常?
建议用自己的后端调用生图接口,不要把 Key 暴露到浏览器源码。测试可用本站测试页或服务端脚本。