ai-api 图片转发网关 · 接口文档

对外一个极简接口做图片生成;内部转发到 highwayapi / otuapi,单入口 + 自动故障转移,出图落地成本站稳定 URL

概览

基址https://ai-api.dahe2016.com
数据格式请求/响应均为 application/json(图生图的参考图可传 URL 或 base64)
调用方只需关心提示词 prompt + 比例 ratio + 文生图/图生图 mode(+ 尺寸档 size / 张数 n
多渠道容错(对调用方透明)后端多渠道互为备份;某渠道故障时网关自动切换到可用渠道出图再返回,你完全无需感知、也无需做任何处理,照常拿 data[].url 即可。

鉴权

除只读/页面类端点外,写操作需在请求头带网关 key:

复制Authorization: Bearer <你的网关KEY>

key 错误或缺失 → 401。新增/吊销 key 由服务端 .env 管理(一行一个,行首加 # 即吊销)。

生成图片

POST/v1/images

请求字段

字段类型必填默认说明
promptstring必填文本提示词,中英文均可
modelstring可选gpt-image-2gpt-image-2(快,~20–90s)/ banana(Nano Banana 2,画质强但走异步任务、可能 2–4 分钟,客户端超时设 ≥300s)
ratiostring可选3:4比例,取值见下;auto=交给模型判断。banana 目前主用渠道仅 1:1 / 9:16 / 16:9 / auto,其余按 auto
modestring可选t2it2i=文生图 / i2i=图生图
imagestring | string[]i2i 必填参考图,单张或数组。三种都行:在线 URL / DataURLdata:image/png;base64,...)/ 裸 base64(无在线图、只有本地文件时直接传 base64 即可,网关会自动识别图片类型补成 DataURL)
sizestring可选1k尺寸档 1k/2k/4k2k/4k 仅 highwayapi 支持,otuapi 一律按 1k
ninteger可选1出图数 [1, 10]。网关对上游并发 n 次单图请求,绝不传 N

ratio 取值: auto1:13:44:32:33:29:1616:91:22:11:33:19:2121:9

示例 · 文生图(curl)

复制curl -X POST https://ai-api.dahe2016.com/v1/images \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"小红书封面 香港保险避坑 扁平插画 红黄撞色大标题","ratio":"3:4","n":2}'

示例 · 图生图(curl)

复制curl -X POST https://ai-api.dahe2016.com/v1/images \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode":"i2i","image":"https://example.com/ref.jpg","prompt":"改成夜景霓虹风格","ratio":"3:4"}'

没有在线 URL(只有本地图)时,把 image 换成图片的 base64 即可,例如 Python:image = base64.b64encode(open("a.png","rb").read()).decode() 再放进 body。

Python

复制import httpx
r = httpx.post(
  "https://ai-api.dahe2016.com/v1/images",
  headers={"Authorization": "Bearer "+KEY},
  json={"prompt":"...", "ratio":"3:4", "n":1},
  timeout=320)
for it in r.json()["data"]:
    print(it["url"])

JavaScript (fetch)

复制const r = await fetch("/v1/images", {
  method:"POST",
  headers:{ "Content-Type":"application/json",
            "Authorization":"Bearer "+KEY },
  body: JSON.stringify({prompt:"...", ratio:"3:4", n:1})
});
const d = await r.json();
console.log(d.data.map(x=>x.url));

响应

响应体永远是 JSON。HTTP 状态200=至少 1 张成功(可能部分失败,看 errors)|502=全部失败|400=参数错误|401=key 无效。

下面这个例子请求 2 张(n=2),成功 1 张、失败 1 张——同时展示 data[]errors[] 两种结构:

复制{
  "created": 1782286822,
  "ratio": "3:4", "mode": "t2i", "size": "1k",
  "requested": 2, "succeeded": 1, "failed": 1,
  "data": [
    {
      "url": "https://ai-api.dahe2016.com/img/5a8e1395abcd.png",
      "provider": "otuapi",
      "upstream_size": "auto",
      "width": 1086, "height": 1448,
      "bytes": 2000215, "elapsed_ms": 51000
    }
  ],
  "errors": [
    {
      "index": 1,
      "tried": [
        { "channel": "otuapi",     "error": "HTTP 403: insufficient_user_quota" },
        { "channel": "highwayapi", "error": "failed after 4 retries: HTTP 504" }
      ],
      "elapsed_ms": 62000
    }
  ]
}

顶层字段

字段类型说明
createdint生成时间戳(秒)
ratio / mode / sizestring本次实际使用的比例 / 模式 / 尺寸档(回显)
requestedint请求张数(= 入参 n
succeededint成功张数(= data 长度)
failedint失败张数(= errors 长度)
dataarray成功的图,每项见下;全失败时为 []
errorsarray失败的图,每项见下;全成功时为 []

data[] — 每张成功图

字段类型说明
urlstring本站稳定链接,永久有效,可直接 <img src> 引用(这是你要用的图片地址)
providerstring实际出图渠道:otuapihighwayapi(故障转移时可能是备用渠道,对你无影响)
upstream_sizestring上游实际 size 参数:otuapi 恒为 auto(比例靠提示词控);highwayapi 为精确像素如 1536x2048
width / heightint成品图真实像素
bytesint图片字节大小
elapsed_msint这张图耗时(毫秒)

errors[] — 每个失败项

字段类型说明
indexint这是第几张(从 0 起)
triedarray各渠道的尝试记录 [{channel, error}],主备都试过的报错都在里面,便于排查
elapsed_msint这张图耗时(毫秒)
怎么用:遍历 data[] 取每个 url 即可(succeeded 张)。要严谨就判一下 failed>0 时看 errors[].index 知道哪几张没出、为什么。

图片托管

GET/img/{filename} — 网关把上游图下载落地后,以本站稳定 URL 提供(免鉴权,可直接 <img> 引用)。

为什么要落地:上游链接是临时的(otuapi 图床 2h、highwayapi 腾讯云 COS 48h 签名链)。网关下载存到本站,返回的 url 不会过期。落地图超过 IMAGE_TTL_DAYS 天会被自动清理(默认 7 天)。

健康检查

GET/healthz

复制{ "ok":true, "primary":"highwayapi", "order":["highwayapi","otuapi"],
  "failover":true, "available":["highwayapi","otuapi"],
  "gateway_keys":1, "auth":"enabled", "otu_key":true, "hw_key":true }

请求统计

网关 key(标签)统计请求次数 + 出图成功/失败数 + 各渠道分担。统计随每次 /v1/images 累加,持久化、重启不丢。可视化见 /admin

GET/v1/stats — 读取统计(需 KEY

复制{
  "since": 1782200000,
  "total": { "requests": 128, "images_ok": 240, "images_failed": 3 },
  "by_key": {
    "default":  { "requests": 100, "images_ok": 190, "images_failed": 2, "last_ts": 1782284733 },
    "partner1": { "requests": 28,  "images_ok": 50,  "images_failed": 1, "last_ts": 1782280000 }
  },
  "by_channel": { "highwayapi": 230, "otuapi": 10 }
}

POST/v1/stats/reset — 清零(需 KEY,用于新计费周期)

key 标签从哪来:by_key 的标签 = .envAIAPI_KEY_标签=token 的标签部分。key 只在 .env 维护(一行一个、# 吊销),网页不配置 key。

比例 ↔ 后端 映射参考

调用方只传 ratio,网关按下表翻译。highwayapi 走精确 size,otuapi 走提示词描述。

ratiohighwayapi · 1k sizehighwayapi · 2khighwayapi · 4kotuapi
1:11024x10242048x2048统一 size:auto
+ 比例进提示词
(约 1k 原生分辨率,
如 3:4 出 1086×1448)
3:41536x20482160x3840
4:32048x15363840x2160
9:161152x20481152x20482160x3840
16:92048x11522048x11523840x2160
2:31024x1536
3:21536x1024
21:92048x880
9:21880x2048

注:highwayapi 某档无对应精确尺寸时回退到 1k 表;再没有则用 auto + 提示词兜底。1:2 / 2:1 / 1:3 / 3:1 也支持(1k)。

错误与坑

HTTP含义
200至少 1 张成功(也可能部分失败,看 errors[]
400参数错误(ratio/size 不支持、i2i 缺 image、n 超限等)
401网关 key 错误或缺失
502全部渠道都失败(errors[] 有每个渠道的报错)

在线试一试

注意:这里会真实调用后端出图,每次都会产生费用。key 仅保存在你本机浏览器(localStorage)。