API 文档
画境生成开放接口。用 API Key 可调用文生图、图生图与 MiniMax H3 视频生成,额度与网页端共用同一个账户。
文档核对日期:。响应示例中的金额、时间和任务编号仅示意,实际价格与限制以当前接口返回值为准。
价格、模型、参数
接模型先看这几张表:价格、扣费、模型、请求参数、1K/2K。单价打开本页后会按当前站点配置刷新。程序里请再调 GET /v1/pricing,不要把数字写死。
文档地址就是 /docs/。本站支持图像生成和 MiniMax H3 视频生成。图像模型参数与价格见模型表;视频按时长和分辨率计价,参数见视频接口。
价格
余额单位是「分」。1 元 = 100 分,所以 0.5 分 = 0.005 元,1 分 = 0.01 元。下面数字是当前站点价格。
| 类型 | 单价(分 / 张) | 折合人民币 | 对应接口 |
|---|---|---|---|
| 文生图 | 1 | 0.01 元 | POST /v1/images/generations |
| 图生图 | 2.5 | 0.025 元 | POST /v1/images/edits |
| 图片超分(画布超分) | 2K 1 · 4K 2 · 8K 4 分/张 | 按分辨率计费 | POST /v1/images/upscale |
| MiniMax H3 视频 | 按分辨率与时长计费 | POST /v1/videos/generations | |
| 查余额 / 模型 / 流水 / 健康检查 | 0 | 0 元 | 其余接口不扣费 |
图像扣费:按请求张数预扣并结算
同步图像请求按请求的 n 预扣;异步图像任务按站点配置的最多输出张数预扣。任务完成后按实际输出张数结算,多扣部分退回。上限为 3 张。
| 步骤 | 发生什么 | 举例(文生图,实际出 1 张) |
|---|---|---|
| 1. 预扣 | 同步按 单价 × n;异步按 单价 × max_output_images |
1 分 × 3 张 = 异步最多预扣 3 分 |
| 2. 出图 | 生成服务实际出了几张,就算几张 | 实际出了 1 张 |
| 3. 结算 | 多扣的立刻退回。响应里的 cost 是实花,balance 是结算后余额 |
退回 2 分,本次实花 1 分 |
| 失败 | 图像生成最终失败或运行中断时退还预扣;已提交的视频在重启后继续查询,最终失败才退款 | 实花 0 分 |
成功生成有多扣差额时,流水会出现预扣和退款两条;没有差额则无需退款记录。按流水净额核对花费。
MiniMax H3 视频按 分辨率单价 × 视频秒数 + 参考图单价 × 张数预扣;成功后按预扣额结算,失败全额退回。接口只返回本站费用与余额。
可用模型
请求里的 model 只接受下表 id。参数相同、价格相同,差别主要在出图像素。不填则用站点默认(当前 gpt-image-2.5)。GPT Image 2.5 当前默认使用 low 质量档。
| 请求里写 model | 界面显示名 | 出图大概多大 | 说明 |
|---|---|---|---|
gpt-image-2.5 |
GPT Image 2.5 | 2K,长边约 1920–2560,总像素约 370 万 | 站点模型标识。默认使用 low 质量档。 |
gpt-image-2.5-high |
GPT Image 2.5 high | 固定 1K | 该模型固定输出 1K,resolution 参数对它无效。需要 2K 时请选择 gpt-image-2.5。 |
nano-banana-2 |
Nano Banana 2 | 默认 2048 × 2048 PNG | 口语里的 Banana 2 / nano 2。 |
nano-banana-2-flash-lite |
Nano Banana 2 Flash Lite | 1K 原生档:方图 1024 × 1024,横图实测 1376 × 768 | 支持文生图、参考图编辑。分辨率固定归一为 1k,直接交付原图;不取压缩预览,不插值放大。 |
nano-banana-2.1 |
Nano Banana 2.1 | 2K 原生档:方图 2048 × 2048,横图实测 2752 × 1536 | 支持文生图、参考图编辑。分辨率固定归一为 2k,直接交付原图;沿用本站图片计费。 |
nano-banana-pro |
Nano Banana Pro | 默认 2048 × 2048 PNG | 口语里的 Banana Pro。旧值 nano-banana 会自动转到这里。 |
minimax-h3 | MiniMax H3 | 视频模型 | 使用 /v1/videos 接口;配置费率与参数见 GET /v1/videos/config |
不要传这些
| 有人会写成 | 结果 | 正确写法 |
|---|---|---|
nano |
报 unsupported_model |
nano-banana-2 或 nano-banana-pro |
gpt image / gpt-image-1.5 |
报错(id 必须完全一致) | gpt-image-2.5 |
sd2 / sd2.5 / Stable Diffusion |
本站没有这些模型 | 改用上表之一 |
| 视频、语音、对话 Agent | 不是图像模型 id | 视频使用专用的 /v1/videos 接口 |
图像模型共用的请求参数
| 参数 | 必填 | 取值 | 说明 |
|---|---|---|---|
prompt |
必填 | 文字;普通图像模型默认最长 12000 字符 | 主体、场景、光线、镜头写清楚。gpt-image-2.5-high 不设本站字符上限,但仍受 HTTP 请求体与生成服务限制。 |
model |
可选 | gpt-image-2.5 / gpt-image-2.5-high / nano-banana-2 / nano-banana-2-flash-lite / nano-banana-2.1 / nano-banana-pro |
不填用站点默认。填了不支持的值直接报错,不会悄悄换成别的模型。gpt-image-2.5-high 固定 1K。 |
ratio |
可选 | 1:1 16:9 9:16 4:3 3:4 |
留空由模型自己决定。这是倾向性引导,不是硬裁切,出图可能略有偏差。 |
resolution |
可选 | 1k / 2k,默认 2k |
见下一张表。传 4k 不会报错,按 2k 出原图;要更高分辨率请走 图片超分(2K/4K/8K),不要传 resolution=4k。gpt-image-2.5-high 例外:忽略此参数,固定出 1K。 |
| 参考图 | 仅图生图必填 | 文件、data URL 或 https 图片地址,最多 max_reference_images 张(以 GET /v1/pricing 的实时值为准) |
支持多张参考图,同步与异步图生图均可使用。超过上限返回 too_many_reference_images。 |
n | 可选 | 1~limits.max_output_images 的整数,默认 1 |
同步图像及聊天格式出图按此张数请求和预扣;异步图像当前不保存此值。 |
response_format | 可选 | url(默认)或 b64_json |
同步图像和聊天响应的 data[] 返回 URL 或 base64;异步任务查询仍返回图片链接。 |
resolution:1K 和 2K
| 传这个 | 拿到什么 | 格式 | 什么时候用 |
|---|---|---|---|
2k |
原图,约 2K–2.5K | 无损 PNG | 要成品就用这个,也是默认值 |
1k |
长边压到 1024 的预览 | 有损 webp,体积大约是原图的 1/40 | 列表缩略、快速看效果。价格和 2K 相同 |
4k |
已下线(普通出图接口) | — | 普通生成最高支持 2K。继续传会回落到 2k |
各比例大概尺寸(resolution=2k)
GPT Image 2.5(默认 low 档)实测。总像素大致固定,选宽幅不会让你多拿到画面,只是把同样多的像素铺成更宽的形状。Nano Banana 2 / Pro 默认是 2048 × 2048。
| ratio | 2K 原图 | 长边 | 1K 预览 |
|---|---|---|---|
1:1 | 1920 × 1920 | 1920 | 1024 × 1024 |
4:3 | 2176 × 1632 | 2176 | 1024 × 768 |
16:9 | 2560 × 1440 | 2560 | 1024 × 576 |
3:4 | 1632 × 2176 | 2176 | 768 × 1024 |
9:16 | 1440 × 2560 | 2560 | 576 × 1024 |
其它上限
| 限制 | 默认 | 说明 |
|---|---|---|
| 单次最多出图 | 3 | 异步图像预扣上限;同步按请求的 n 预扣 |
| 图生图参考图 | 按配置 | 最多 max_reference_images 张,以接口实时值为准 |
| 同时进行的生成任务 | 9999 | 单用户并发,默认 9999 |
| 异步任务排队上限 | 9999 | 排队 + 进行中合计,默认 9999 |
| 客户端超时 | 320 秒以上 | 同步接口通常 1–5 分钟。异步提交立刻返回,轮询 /v1/images/tasks/:id 即可 |
网页端和 API 共用同一套价格、模型和参数。登录工作台也能直接出图;要接自己的系统,往下看鉴权和接口说明。
概览
本站同时提供两套开放协议,共用同一把 API Key、同一份余额和同一套模型,按你手上客户端支持的协议选一套即可:
- OpenAI 兼容接口:全部在
/v1下,请求与响应均为 JSON(图生图额外支持 multipart 上传),风格接近 OpenAI Images API,并兼容 CPA、NewAPI、Sub2 常见的 Bearer /x-api-key鉴权、/v1/chat/completions图片调用和/api/v1路径别名。 - Gemini 原生接口:在
/v1beta/models/...下,按 Google 官方 GenerateContent / Predict 协议收发,鉴权用x-goog-api-key或?key=,图片以inlineData(base64) 返回。详见 Gemini 兼容接口。
中转兼容提示:OpenAI 类客户端 Base URL 可以填本站根地址、/v1 或 /api/v1,重复拼接成 /v1/v1/... 也会自动归一化。Gemini 类客户端 Base URL 填本站根地址即可(/v1beta/models/... 是 Gemini 协议,不是 OpenAI 路径别名)。OpenAI 路径拒绝未知图像模型;Gemini 模型名按兼容映射表处理,不能把映射后的站点模型当作所填模型的官方服务。
Base URL
https://your-domain.example/v1本页所有示例里的地址已经自动替换成你当前访问的域名,复制下来就能直接跑,不用再手动改。
接口一览
5 分钟上手
- 创建密钥。登录网页端,进入「API 密钥」标签页,填个备注后点「创建密钥」。密钥形如
mk-加 48 位十六进制字符,可在密钥列表随时查看或复制;旧密钥可先保存自己保留的原值。可以把密钥绑定到一个图像或视频模型,再把用途限制为文生图、图生图或视频生成。 - 确认有额度。调
GET /v1/balance看看余额;没有的话用兑换码或在网页端充值。 - 发第一个请求。下面这条命令会生成一张图并返回可直接下载的 URL。
curl -X POST https://your-domain.example/v1/images/generations \
-H "Authorization: Bearer mk-你的密钥" \
-H "Content-Type: application/json" \
-d '{
"prompt": "一只在草地上奔跑的柴犬,逆光,浅景深,35mm 胶片质感",
"ratio": "16:9",
"resolution": "2k"
}'返回:
{
"ok": true,
"images": ["https://.../a1b2c3.png"],
"resolution": "2k",
"model": "gpt-image-2.5",
"cost": 0.5,
"image_count": 1,
"balance": 999,
"session_id": "g_a8f3d2e16b9c0475"
}生成很慢,这是正常的。单次生成通常 1-5 分钟。同步接口会一直挂着直到出图,客户端超时请设到 320 秒以上。不想阻塞就用异步接口:提交立刻返回任务 id,再按 2-3 秒间隔轮询结果。
鉴权
每个请求都要带上 API Key。/v1(OpenAI 协议)支持下面两种写法,任选其一,效果完全相同:
Authorization: Bearer mk-xxxxxxxxxxxxxxxx
x-api-key: mk-xxxxxxxxxxxxxxxx/v1beta(Gemini 协议)额外支持官方 SDK 的两种写法;四种方式都指向同一把密钥、同一个账户,可以混用:
x-goog-api-key: mk-xxxxxxxxxxxxxxxx
?key=mk-xxxxxxxxxxxxxxxx密钥的性质
- 格式为
mk-+ 48 位十六进制字符,共 51 个字符。 - 密钥所有者可在登录后的「API 密钥」列表查看、复制自己的密钥,普通列表仅显示掩码。请妥善保管密钥。
- 一个账户可以创建多个密钥,便于按用途区分和单独吊销。旧密钥若暂不支持查看,可录入自己保存的原值;原值遗失时请撤销并重新创建。
- 删除(吊销)后立即失效,正在使用它的程序会开始收到
401 api_key_revoked。 - 密钥代表账户全部权限,可以花掉账户余额。不要写进前端代码、不要提交进 Git 仓库。
按模型分开的密钥
创建密钥时可以绑定一个模型,这把密钥之后就只能调那一个模型。可绑定图像模型或 minimax-h3 视频模型;绑定视频模型后仅能调用视频接口。
| 密钥类型 | 请求不带 model | 请求带别的 model |
|---|---|---|
| 不限模型(默认) | 用站点默认模型 | 照请求的模型执行 |
绑定 gpt-image-2.5 | 用 gpt-image-2.5 | 403 model_not_allowed |
绑定 gpt-image-2.5-high | 用 gpt-image-2.5-high(固定 1K) | 403 model_not_allowed |
绑定 nano-banana-2 | 用 nano-banana-2 | 403 model_not_allowed |
绑定 nano-banana-2-flash-lite | 用 nano-banana-2-flash-lite | 403 model_not_allowed |
绑定 nano-banana-2.1 | 用 nano-banana-2.1 | 403 model_not_allowed |
绑定 nano-banana-pro | 用 nano-banana-pro | 403 model_not_allowed |
绑定 minimax-h3 | 视频接口使用 minimax-h3 | 图像接口返回 403 model_not_allowed |
绑定关系在 GET /v1/me 的 key.model 里能查到;GET /v1/models 对绑定过的密钥只会列出它能用的那一个模型,照着这个列表选模型就不会踩到 model_not_allowed。绑定只能在创建时指定,事后改不了——需要换模型就再建一把。
老密钥(这个功能上线之前创建的)一律算「不限模型」,行为和以前完全一致,不用改代码。
按用途分开的密钥
创建密钥时还可以限定用途。它和「绑定模型」相互独立,可以自由组合,比如「不限模型 + 仅图生图」。用途只能调用对应形态的接口,调另一种会返回 403 scope_not_allowed,不扣费。
| 用途 | 文生图 | 图生图 | 视频生成 |
|---|---|---|---|
| 不限用途(默认,老 Key 等同) | 是 | 是 | 是 |
text 仅文生图 | 是 | 403 scope_not_allowed | 403 scope_not_allowed |
edit 仅图生图 | 403 scope_not_allowed | 是 | 403 scope_not_allowed |
video 仅视频生成 | 403 scope_not_allowed | 403 scope_not_allowed | 是 |
文生图、图生图接口及 /v1/chat/completions、Gemini /v1beta 按图像请求形态判定用途;视频仅通过 /v1/videos 接口提交。绑定 minimax-h3 时,用途须为「不限用途」或 video;创建后不可修改,需要换用途就再建一把。
API Key 仅可访问所属账户的公开 API,请按所需用途和模型范围创建密钥。
鉴权失败
HTTP/1.1 401 Unauthorized
{ "error": { "code": "invalid_api_key", "message": "无效的 API Key" } }密钥格式对但已被删除时返回的是 api_key_revoked,用来和「打错字 / 用了别站的密钥」区分开。两种都不要重试。
额度与计费
账户余额和所有价格对外统一以「分」为单位(响应里的 balanceUnit: "fen")。1 元 = 100 分。允许出现 0.5 这样的半分,费用以 0.5 分为最小精度。
扣费流程
图像请求按上方规则预扣并结算:同步请求按 n,异步任务按最多输出张数;视频任务按总费用预扣。完整对照表见开头的扣费表。
| 步骤 | 公式 | 举例(文生图 1 分/张,最多 3 张,实际出 1 张) |
|---|---|---|
| 预扣 | 同步图像:单价 × n;异步图像:单价 × max_output_images | 最多先扣 3 分 |
| 结算 | 单价 × 实际张数,多扣的退回 | 退 2 分,实花 1 分 |
响应里的 cost 是实际花费,balance 是结算后的余额。不要看预扣瞬间的余额。
生成最终失败会退还预扣;参数校验失败不扣费。图像任务运行中断后的未结算预扣会在重启时退还。视频已提交后暂时查不到结果或服务重启,不等于失败:系统会继续查询原任务、保留原预扣,最终成功结算或失败退款,避免重复提交和重复扣费。
若生成已完成但客户端断开,或 b64_json 图片字节读取失败,并不保证生成费用回退;请先检查生成记录和流水,再决定是否重新提交。
哪些接口花钱
| 接口 | 计费 |
|---|---|
POST /v1/images/generations | 按文生图单价 × 实际出图张数 |
POST /v1/images/edits | 按图生图单价 × 实际出图张数(通常比文生图贵) |
POST /v1/images/generations-async / edits-async | 与对应同步接口相同;提交时检查余额,任务开始执行时预扣 |
POST /v1/videos/generations | 视频费率 × 秒数 + 参考图费率 × 图片数 + 已开启的音频、视频或首尾帧参考加价;提交时预扣一次,最终失败全额退款 |
POST /v1/images/upscale,或 /v1/images/edits 的 upscale-2k/4k/8k 模型 | 单张图片按超分分辨率计费,成功后扣费 |
POST /v1/chat/completions、Gemini :generateContent / :streamGenerateContent / :predict | 按是否带参考图使用文生图或图生图单价 |
| 其余所有接口 | 免费,只受速率限制 |
实时单价通过 GET /v1/pricing 或 GET /v1/balance 获取,不要在代码里写死——管理员随时可以调价,站点搞活动时价格还会临时下调。
通用约定
请求
- 图生图、图片超分与视频生成支持 multipart 文件上传,其余请求体使用 JSON,并带
Content-Type: application/json。 - 普通 JSON 请求体上限 128 KiB;
/v1/images/edits、/v1/images/edits-async、/v1/chat/completions、/v1/videos/generations及/v1beta的 JSON 上限为 420 MiB,为 base64 编码留出空间。参考图解码后合计仍不得超过 300 MiB,单张不超过 20 MiB。/v1/images/upscale的 JSON 仍为 128 KiB,大图片请用 URL 或 multipart。 - 图生图及视频 multipart 请求体上限为 302 MiB(含表单开销),图片本体合计上限为 300 MiB;张数另外受模型与账户限制。
- 未知字段会被忽略,不会报错。
成功响应
本站查询类和同步出图通常带 ok: true,HTTP 状态码为 200。聊天、单模型元数据与 Gemini 响应使用各自兼容结构,不保证带 ok。异步提交返回 202,任务成败看 status;视频任务最终失败时即使 HTTP 200,ok 仍为 false。
错误响应
/v1 下的错误结构统一,error 恒为对象,永远有 code 和 message 两个字段:
{
"error": {
"code": "insufficient_credits",
"message": "余额不足:最多需要 3 分,当前 1 分",
"hint": "(可选)仅部分错误会带,给出可操作的修复建议"
},
"balance": 1
}部分生成执行失败与余额不足响应额外带 balance;鉴权、参数校验等提前返回的错误不保证有余额字段。
请按 code 判断错误类型,不要匹配 message。message 是给人看的中文提示,措辞会随版本变化;code 才是稳定契约。
以上是 /v1 的错误信封。/v1beta(Gemini 协议)遵循 Google 官方结构 { "error": { "code": 400, "message": "...", "status": "INVALID_ARGUMENT" } }:code 是 HTTP 数字、status 是枚举字符串,没有 type / param。详见 Gemini 兼容接口。
时间与金额字段
| 字段形态 | 含义 |
|---|---|
created_at / last_used_at 等 | Unix 毫秒时间戳(整数)。JavaScript 里 new Date(v) 直接可用。 |
兼容字段 created | Unix 秒时间戳。转 JavaScript Date 时乘以 1000;模型元数据中的 0 是兼容占位值。 |
cost / balance / delta | 以「分」为单位,可能带一位小数。 |
cost_units / delta_units | 每个单位表示 0.5 分;通常直接使用已换算的费用字段。 |
图片、参考图与视频 URL 的有效期
本站当前媒体保存期为 8 小时,按资源创建时间计算,不因查询或播放延长。图片、参考图与视频会在过期后自动清理;生成历史仍可用于核对任务与费用,但不能保证媒体文件继续可用。请及时下载转存。
返回的是站内读取或带签名的播放地址,例如 /img/... 与 /media/video/...。地址可能是相对路径,客户端须按本站 Base URL 解析;下载器应跟随重定向。不要修改签名,也不要把重定向后的短期 URL 当作永久地址。
速率限制
使用请求头传密钥时限流按 API Key 计算;无密钥请求头时按 IP 计算,因此 Gemini 仅用 ?key= 的请求共享该 IP 的限流额度。触发后返回 429:
{ "error": { "code": "rate_limited", "message": "API 调用过于频繁,请降低速率" } }| 范围 | 默认额度 | 环境变量 |
|---|---|---|
全部 /v1 与 /v1beta 接口 | 9999 次 / 分钟 | RL_API |
POST /v1/redeem(叠加) | 30 次 / 10 分钟 | RL_REDEEM |
响应头使用 draft-7 的 RateLimit 和 RateLimit-Policy,触发限流时可结合 Retry-After 做退避。这些额度由部署方通过环境变量配置。
被限流挡掉的请求也会记进调用历史,所以到底是哪个时段、哪把密钥撞上了限流,翻 GET /v1/usage 就能看出来,不用自己在客户端埋点。
并发上限
限流之外还有同时进行的生成任务上限,这是另一套机制:
- 单用户默认 9999 路并发生成。实时值见
GET /v1/pricing的limits.max_concurrent_per_user;视频配置也会返回此值。 - 全站默认 9999 路并发生成。同步接口只有撞上这个天花板才返回
503 busy;异步会留在队列里等空位。 - 异步排队 + 进行中默认最多 9999 个,见
limits.max_open_async_tasks。只有碰到这个数字才会429 too_many_tasks。
图像批量任务和视频任务走异步接口轮询。网页端每次提交一个视频任务,需要多个视频时可继续新建任务;API 可并发提交。超过并发上限的任务自动排队。
文生图
根据文字提示词生成图片。同步接口,等到出图才返回,通常耗时 1-5 分钟。
请求参数(JSON)
| 参数 | 类型 | 说明 |
|---|---|---|
prompt 必填 |
string | 图片描述。普通图像模型默认最多 12000 字符,超过返回 prompt_too_long;gpt-image-2.5-high 无本站字符上限,但仍受请求体与生成服务限制。 |
ratio 可选 |
string | 画面比例,可传 1:1、16:9、9:16、4:3、3:4 或任意合法的 宽:高。响应中的 requested_ratio / normalized_ratio 分别表示请求值和归一化值,实际输出比例以生成文件为准。 |
size / output_size / dimensions 可选 |
string | 兼容 CPA、NewAPI、Sub2 常见字段,例如 1008x1344。接受 64–16384 的宽高且总像素不超过 64MP;请求尺寸不保证与输出尺寸完全相同。响应中的 requested_size / normalized_size 分别表示请求值和归一化值,实际尺寸以生成文件为准。 |
resolution 可选 |
string |
输出分辨率,默认 2k,非法值静默回落到 2k。
4k 已下线:继续传 4k 会按 2k 处理。需要更高分辨率时,请使用图片超分接口。模型原生档位: nano-banana-2-flash-lite 固定使用 1k 原图,nano-banana-2.1 固定使用 2k 原图。传入另一档或省略参数时自动归一;响应及任务记录的 resolution 返回实际使用的档位。这两个模型均交付原文件,不生成压缩预览或放大版本。1K/2K 是原生档位名称,具体长宽随比例变化。
|
model 可选 |
string | 生图模型,可选 gpt-image-2.5、gpt-image-2.5-high、nano-banana-2、nano-banana-2-flash-lite、nano-banana-2.1 或 nano-banana-pro。旧值 gpt-image / gpt-image-2.0 / image2.0 会自动兼容到 gpt-image-2.5;旧值 nano-banana 会当作 nano-banana-pro。留空使用站点默认模型;填了不支持的值会直接报错而不是回落,避免你以为用上了实际没用上。密钥绑定了模型时留空即用绑定的那个,填别的会返回 403 model_not_allowed。注意 gpt-image-2.5-high 固定输出 1K,resolution 参数对它无效。nano-banana-2-flash-lite 固定归一为 1K 原图,nano-banana-2.1 固定归一为 2K 原图;具体像素随画幅变化。 |
n 可选 | integer | 默认 1,取值为 1~limits.max_output_images;非法值返回 400 invalid_n。同步按此值请求和预扣,实际输出张数及费用以 image_count / cost 为准;站点可能对特定网关密钥强制单张。 |
response_format 可选 | string | url(默认)让 data[] 返回 url;b64_json 返回不含 data URL 前缀的 base64。其它值返回 400 invalid_response_format。 |
关于比例和自定义尺寸:比例和尺寸参数用于描述期望画幅,不保证精确裁切或逐像素匹配。响应中的 requested_* 和 normalized_* 字段分别说明请求值与归一化值,请以实际生成文件为准。
各比例的实际出图尺寸
下面是实测数据(resolution=2k)。注意总像素是固定的,约 370 万——实际尺寸会随画面比例变化,请以生成文件为准。
| ratio | 原图尺寸 | 长边 | 总像素 | 1k 档对应尺寸 |
|---|---|---|---|---|
1:1 | 1920 × 1920 | 1920 | 369 万 | 1024 × 1024 |
4:3 | 2176 × 1632 | 2176 | 355 万 | 1024 × 768 |
16:9 | 2560 × 1440 | 2560 | 369 万 | 1024 × 576 |
3:4 / 9:16 | 对应横版的转置 | 1632 / 1440 | 同上 | 768 × 1024 / 576 × 1024 |
上面是 GPT Image 2.5 的 low 档实测。Nano Banana 2 / Pro 默认输出 2048 × 2048 PNG,实际尺寸以文件为准。需要 4K / 8K 时,请使用图片超分接口。换算成印刷尺寸,按 300 DPI 计算长边约 16~21 厘米,做屏幕内容、社媒图和网页配图绰绰有余;要出大幅面海报则需要自行做超分。
响应字段
| 字段 | 类型 | 说明 |
|---|---|---|
created | integer | OpenAI 兼容的 Unix 秒时间戳 |
data | object[] | response_format=url 时为 [{"url":"https://本站/img/..."}];b64_json 时为 [{"b64_json":"..."}]。同步文生图和图生图都返回。 |
requested_size / normalized_size | string | 有尺寸请求时返回请求意图与兼容归一化尺寸;归一化值不是实际媒体尺寸保证。 |
requested_ratio / normalized_ratio | string | 有比例请求时返回请求比例与兼容归一化画幅。 |
ok | boolean | 恒为 true |
images | string[] | 图片直链数组,顺序即生成顺序。至少一张,否则本次会按失败处理并退款。 |
resolution | string | 实际使用的分辨率 |
model | string | 实际使用的模型 id |
cost | number | 本次实际扣费(分),已按出图张数结算完毕 |
image_count | number | 出图张数,等于 images.length |
balance | number | 结算后的账户余额(分) |
session_id | string | 本次请求的排查编号,联系支持时可提供 |
示例
curl -X POST https://your-domain.example/v1/images/generations \
-H "Authorization: Bearer mk-你的密钥" \
-H "Content-Type: application/json" \
--max-time 330 \
-d '{
"prompt": "极简主义产品摄影:一只哑光黑陶瓷咖啡杯放在浅灰水泥台面上,柔和顶光,阴影干净,高级商业质感",
"ratio": "1:1",
"resolution": "2k",
"model": "gpt-image-2.5"
}'可能的错误
| 状态码 | code | 含义与处理 |
|---|---|---|
| 400 | missing_prompt | prompt 为空或只有空白字符 |
| 400 | prompt_too_long | 普通模型 prompt 超过默认 12000 字符上限,不扣费;high 图像模型无本站字符上限 |
| 400 | unsupported_model | model 不在支持列表里,先查 /v1/models |
| 400 | prompt_rejected | 提示词未通过内容审核,不扣费。响应带 hint 说明如何修改 |
| 401 | invalid_api_key | 密钥不存在 |
| 401 | api_key_revoked | 密钥已被删除,重新创建一把 |
| 402 | insufficient_credits | 余额不足以覆盖预扣金额,先充值 |
| 403 | model_not_allowed | 这把密钥绑定的是别的模型,不扣费。响应带 hint 指出该换哪把密钥 |
| 403 | scope_not_allowed | 这把密钥限定了用途(文生图 / 图生图 / 视频),调了不匹配的接口,不扣费。响应带 hint |
| 429 | rate_limited | 超出速率限制,退避后重试 |
| 429 | too_many_requests | 你的并发生成数已达上限,等前面的任务完成 |
| 503 | no_channel | 服务暂时繁忙,已全额退款,稍后重试 |
| 503 | busy | 全站并发已满,已全额退款,稍后重试 |
| 500 | generation_failed | 生成服务失败或超时,已全额退款 |
内容审核
提交前会进行内容审核,未通过时不产生生成费用。限制的内容包括:涉及未成年人的性化内容、真实人物的裸露内容、露骨色情、武器爆炸物制作方法、毒品制作方法,以及站点管理员自定义的禁用词。
{
"error": {
"code": "prompt_rejected",
"message": "提示词未通过内容审核(露骨色情内容)",
"hint": "提示词可能触发了内容审核。建议去掉真人姓名、品牌标识、暴力或成人相关描述后重试。"
},
"balance": 1000
}本地检查放行不代表一定能出图,生成服务还有自己的审核。服务拒绝时同样返回 prompt_rejected,同样不扣费。
图生图
带参考图生成新图片。同步接口,耗时与文生图相当。支持 multipart 文件上传和 JSON 两种传图方式。
方式一:multipart/form-data(推荐)
直接上传本地文件,不用做 base64 编码,请求体也小得多。
| 字段 | 类型 | 说明 |
|---|---|---|
image 必填 | file | 参考图文件。字段名也可以用 images 或 image[],效果相同。 |
prompt 必填 | string | 希望如何改动或参考这张图 |
ratio / size / resolution / model / n / response_format 可选 | string / integer | 与文生图相同,JSON 与 multipart 均可传 |
curl -X POST https://your-domain.example/v1/images/edits \
-H "Authorization: Bearer mk-你的密钥" \
--max-time 330 \
-F "image=@./reference.png" \
-F "prompt=保持人物姿势不变,把背景换成黄昏海滩,增加暖色边缘光" \
-F "resolution=2k"方式二:JSON
适合图片来自远程 URL 或已经是 base64 的场景。以下字段任选一个:
| 字段 | 类型 | 说明 |
|---|---|---|
image | string | data URL,形如 data:image/png;base64,iVBORw0... |
image_url | string | 公网可访问的图片 URL,服务端会代为下载 |
images | string[] | 多张 data URL(受参考图数量上限约束) |
image_urls | string[] | 多张图片 URL(同上) |
filename / filenames 可选 | string / string[] | 指定上传文件名,不填会自动生成 |
mime 可选 | string | 指定 MIME 类型,一般不需要,服务端会从图片内容嗅探 |
curl -X POST https://your-domain.example/v1/images/edits \
-H "Authorization: Bearer mk-你的密钥" \
-H "Content-Type: application/json" \
--max-time 330 \
-d '{
"image_url": "https://example.com/reference.jpg",
"prompt": "转换成水彩插画风格,保留构图",
"ratio": "4:3"
}'参考图上限以 max_reference_images 的实时值为准。参考图片按传入顺序参与生成。超过上限返回 too_many_reference_images。
图片要求
- 支持 PNG、JPEG、WebP、GIF、BMP。服务端按文件头嗅探真实类型,改扩展名骗不过去。
- 单张不超过 20 MiB;JSON 整个请求体不超过 420 MiB;multipart 请求体不超过 302 MiB;参考图解码后合计不超过 300 MiB。编码体积、图片字节与张数上限分别校验。
- 用
image_url时目标必须是公网地址。指向127.0.0.1、内网段、云元数据地址(169.254.169.254)等一律被拒绝,这是防 SSRF 的硬性限制,DNS 解析后的真实 IP 也会检查。
响应字段
比文生图多四个字段,其余相同:
| 字段 | 类型 | 说明 |
|---|---|---|
mode | string | 恒为 "image_to_image" |
reference_count | number | 本次实际使用的参考图数量 |
finalText | string | 模型返回的文字说明,可能为空字符串 |
{
"ok": true,
"mode": "image_to_image",
"images": ["https://.../edited.png"],
"finalText": "已将背景替换为黄昏海滩。",
"resolution": "2k",
"model": "gpt-image-2.5",
"reference_count": 2,
"cost": 1.5,
"image_count": 1,
"balance": 996.5,
"session_id": "g_b7c1e9f43a6d0528"
}额外的错误
除文生图那张表里的全部错误外,还可能出现:
| 状态码 | code | 含义 |
|---|---|---|
| 400 | missing_image | 没有提供任何参考图 |
| 400 | too_many_reference_images | 参考图数量超过 max_reference_images |
| 400 | invalid_image | 不是可识别的图片格式、下载失败,或 URL 指向内网地址 |
| 400 | LIMIT_FILE_SIZE | multipart 单张参考图超过 20 MiB |
| 413 | payload_too_large | JSON 请求体超过对应路由的解析上限 |
| 413 | reference_images_too_large | 参考图片合计超过 300 MiB,或请求体超过该接口的参考图传输上限 |
异步出图
提交后立刻返回任务 id,不等出图。文生图使用 POST /v1/images/generations-async,图生图使用 POST /v1/images/edits-async,支持对应同步接口的提示词、模型、比例、分辨率及参考图输入。
当前异步限制:n 与 response_format 会通过参数校验,但不会保存到图像任务;任务按站点的 max_output_images 上限请求和预扣,不保证恰好输出 n 张。GET /v1/images/tasks/:id 返回 images 链接,不提供 b64_json。需要按 n 控制或直接拿 base64 时,请用同步接口。
没有 webhook。提交后请轮询 GET /v1/images/tasks/:id,建议间隔 2-3 秒,直到 status 变成 succeeded 或 failed。图生图对应 POST /v1/images/edits-async,multipart / JSON 字段与同步图生图相同。
curl -X POST https://your-domain.example/v1/images/generations-async \
-H "Authorization: Bearer mk-你的密钥" \
-H "Content-Type: application/json" \
-d '{"prompt": "一只在草地上奔跑的柴犬", "resolution": "2k"}'HTTP 202:
{
"ok": true,
"id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"status": "queued",
"kind": "text",
"model": "gpt-image-2.5",
"ratio": "",
"resolution": "2k",
"created_at": 1730000000000,
"started_at": null,
"finished_at": null
}| 字段 | 说明 |
|---|---|
id | 任务 id,后续查询用它 |
status | queued 排队 / running 出图中 / succeeded 成功 / failed 失败 |
kind | text 文生图,edit 图生图 |
提交时只做参数校验、内容审核和余额软检查,不预扣。真正占并发槽和预扣发生在任务开始跑的时候,规则与同步接口相同。失败全额退款。
每个账号同时处于 queued + running 的任务默认最多 9999 个。并发生成默认 9999 路;服务繁忙时,任务保持排队,请继续查询原任务状态。
| 状态码 | code | 含义 |
|---|---|---|
| 400 | missing_prompt 等 | 与同步接口相同的参数/审核错误,不会创建任务 |
| 402 | insufficient_credits | 提交时余额已不够覆盖预扣 |
| 429 | too_many_tasks | 该账号未完成的异步任务已达上限 |
查询异步任务
用提交时拿到的 id 查询状态。只能查自己账号的图像任务,别人的 id 或视频任务返回 404 not_found。当前密钥用途须匹配任务形态,绑定模型须匹配任务模型,否则返回 403 scope_not_allowed 或 model_not_allowed。查询本身不扣费。
curl https://your-domain.example/v1/images/tasks/task_xxxxxxxxxxxxxxxxxxxxxxxx \
-H "Authorization: Bearer mk-你的密钥"成功时除任务字段外,还带与同步接口同形的 images(站内 /img/...)、cost、balance、session_id:
{
"ok": true,
"id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"status": "succeeded",
"kind": "text",
"model": "gpt-image-2.5",
"ratio": "",
"resolution": "2k",
"created_at": 1730000000000,
"started_at": 1730000000500,
"finished_at": 1730000120000,
"images": ["/img/xxxxxxxx"],
"cost": 1,
"image_count": 1,
"balance": 997,
"session_id": "g_a1b2c3d4e5f60718"
}失败时 HTTP 仍是 200,看 status: "failed" 和 error:
{
"ok": true,
"id": "task_xxxxxxxxxxxxxxxxxxxxxxxx",
"status": "failed",
"kind": "text",
"error": {
"code": "no_channel",
"message": "服务暂时繁忙,已退还余额"
}
}进程重启后:进行中的图像任务变为 status=failed、error.code=interrupted;排队中的文生图继续执行;排队图生图因内存参考图丢失变为 status=failed、error.code=task_expired,需要重新提交。视频按独立的任务恢复规则处理。
MiniMax H3 视频生成
异步创建 MiniMax H3 视频任务,返回 202 和任务编号。网页端和 API 共用任务队列、账户余额与并发限制。
API Key 已支持全部视频参考模式:此接口接受图片、视频、音频和首尾帧。文字或仅图片参考沿用原生成流程;启用视频、音频或首尾帧参考时使用扩展参考流程。网页会话接口继续保留,不需要将登录 Cookie 交给 API 客户端。
字段:model 可省略(默认 minimax-h3);prompt 必填;duration_seconds 为 5–15 秒整数;resolution 为 768p 或 1080p(默认 768p);aspect_ratio 为 16:9 或 9:16(默认 16:9)。最多 9 张 PNG、JPG、WebP 或 GIF 参考图,单张不超过 20 MiB、合计不超过 300 MiB。
JSON:参考图编号、URL 或 data URL
仅图片参考推荐先使用下方直传接口,再传 reference_image_ids;原有 URL、data URL 和 multipart 文件方式继续支持。默认保留参考图片的画幅;图片任一边超过5760像素时会等比例缩小至该范围。需要补齐第一张图的画幅时,传入 reference_padding: true,并选择 padding_mode:blur(默认模糊背景)、color(纯色,padding_color 采用 #RRGGBB,默认白色)、transparent(透明 PNG)。透明区仍占据画幅,可能被生成服务转换为白色或黑色背景,成品不保证透明。
单张图片按首帧提交,多张图片按多图参考数组提交,最多 9 张。首帧模式和多图参考模式的构图约束不同,参考图的内容应在提示词里明确说明。
视频基础费用为 max(所选分辨率秒价 × 时长, pricing.minimum_fen),再加参考图和已启用参考选项的费用,最终按 0.5 分精度结算。当前基础起步价为 6 分,实时值以 GET /v1/videos/config 为准。已提交任务按提交时价格锁定,不补扣。
同一任务最多自动尝试三次,也可能提前结束。最终失败时退还预扣费用;查询原任务不会创建新任务。
curl -X POST https://your-domain.example/v1/videos/generations \
-H "Authorization: Bearer mk-视频密钥" \
-H "Content-Type: application/json" \
-d '{"model":"minimax-h3","prompt":"黄昏海边,一辆复古摩托车驶过,电影镜头","duration_seconds":8,"resolution":"768p","aspect_ratio":"16:9","reference_images":["https://example.com/reference.jpg"]}'multipart/form-data:上传参考图文件
curl -X POST https://your-domain.example/v1/videos/generations \
-H "Authorization: Bearer mk-视频密钥" \
-F 'prompt=黄昏海边,电影镜头' -F 'duration_seconds=8' \
-F 'resolution=768p' -F 'aspect_ratio=16:9' -F 'reference_images=@reference.jpg'提交响应中的 cost / reserved_cost 单位为本站分。成功任务的 cost 是最终本站费用;失败任务的 cost 为 0,reserved_cost 已退回。结果中的 video_url 是本站播放地址。
{"ok":true,"id":"task_xxx","status":"queued","model":"minimax-h3","prompt":"黄昏海边","duration_seconds":8,"resolution":"768p","aspect_ratio":"16:9","reference_count":1,"cost":8,"reserved_cost":8,"progress":0,"stage":"queued","progress_message":"等待生成","created_at":1760000000000}费率、补边与并发配置
GET /v1/videos/config 返回当前视频费率、参数与并发上限;GET /v1/pricing 的 video_h3 也包含该配置。本站计价公式是「分辨率每秒单价 × 秒数 + 参考图单价 × 图片数」。pricing.reference_enabled 表示是否开启参考图加价;关闭时 reference_fen 为 0,参考图不额外收费。每秒和每张单价支持自定义小数,任务总费用四舍五入到 0.5 分,以响应中的 cost 为准。分辨率费率为 0 时暂停该分辨率的任务提交。
curl https://your-domain.example/v1/videos/config -H "Authorization: Bearer mk-视频密钥"配置额外包含 duration_min_seconds(5)、duration_max_seconds(15)、duration_step_seconds(1)、max_reference_images(9),以及 reference_padding.default(false)、reference_padding.modes 和各分辨率画幅的 targets。这些目标尺寸用于首张图补边,最终视频尺寸仍以实际成片为准。
配置返回 features 和 api_capabilities。reference_images、reference_videos、reference_audios、first_frame、last_frame、generate_audio、reference_padding 表示后台当前开放的功能;为 false 时不要上传对应素材或开启该选项,否则返回 HTTP400、video_feature_disabled,不扣生成费。首尾帧模式仍必须有首帧。asset_upload 表示有参考素材类型开放。reference_limits 是 API 与网页共用的限制。pricing.reference_options.*.enabled 仅表示对应加价是否开启,不表示该参考功能是否可用;关闭加价时该项费用为零。
参考图与补边参数
| 字段 | 类型 / 默认 | 说明 |
|---|---|---|
reference_image_ids | array / [] | 直传确认后返回的图片编号,按数组顺序使用,仅限当前账号未过期的图片;适用于仅图片参考。与其他图片输入合计最多9张。扩展参考使用原有 asset_ids。 |
reference_images / images | array / [] | JSON 数组元素可为 URL、data URL,或 {"url":"..."} / {"image_url":"..."} / {"data_url":"..."};对象可带 filename、mime。所有图片输入合计最多 9 张。无参考图时为文生视频。 |
reference_images | file(multipart) | 重复同名字段上传多个文件;不是 image[]。最多 9 张,单张 20 MiB,合计 300 MiB。 |
reference_videos | array / file | JSON 数组可用 HTTPS URL、base64 data URL 或带 url / data_url 的对象;multipart 可重复上传同名文件。最多3个,每个64 MiB。兼容别名 video_references。 |
reference_audios | array / file | 输入形式同视频,最多3个,每个20 MiB;每段2–15秒、所有音频总时长最多15秒。必须搭配至少一张图片或一个视频。兼容别名 audio_references。 |
first_frame / last_frame | URL / object / file | 各最多一张 PNG、JPEG 或 WebP 图片,每张20 MiB。首帧必需,尾帧可选。扩展参考模式的普通参考图片也使用这三种格式。兼容 first_frame_image / last_frame_image,或 JSON keyframes: {"first":"...","last":"..."};同一帧不能通过多个别名重复提供。 |
input_mode | references / frames | 默认按素材推断。首尾帧模式与普通图片、视频、音频参考互斥。 |
enable_video_reference / enable_audio_reference | boolean | 缺省时根据输入素材自动开启。显式开关必须与素材一致。JSON 使用布尔值;multipart 使用 true 或 false。 |
generate_audio | boolean / false | 扩展参考模式的成品声音选项,与音频参考开关独立。仅文字或图片时请省略或设为 false,保留原生成流程;此模式不能指定生成声音。画布补边参数也只适用于原图片流程。 |
asset_ids | array | 使用下方上传接口返回的素材编号,按数组顺序选择;仅限同一账户未过期的素材。可以与文件或 URL 输入组合,所有形式一起计入数量和大小上限。 |
expected_cost | number(分) | 可选。提交前核对当前价格;与服务器计算费用不符时返回 409 video_price_changed,不创建任务、不扣费。 |
reference_padding | boolean / false | 只补齐第一张参考图;multipart 接受字符串 true/false 或 1/0。关闭时保留画幅,超过5760像素的图片仍会等比例缩小。 |
padding_mode | string / blur | 开启补边时为 blur、color 或 transparent。 |
padding_color | string / #ffffff | 仅纯色补边时使用,必须为六位十六进制颜色 #RRGGBB。 |
开启纯色补边的 JSON 附加参数:{"reference_padding":true,"padding_mode":"color","padding_color":"#ffffff"}。预处理不额外调用生成模型;实际任务仍按视频费率收费。
视频参数错误
图片最多9张、视频最多3个、音频最多3个;参考素材合计最多12个、解码后合计300 MiB。同一数组或同名文件的顺序就是编号顺序。扩展参考模式组合输入时,先 asset_ids、再 JSON 素材、最后 multipart 文件;仅图片混合输入保留原有文件在前的顺序。视频和音频分别编号,首尾帧单独标识。首尾帧参考加价按模式每任务一次,不按帧数重复收费。视频与音频同时启用时,两项加价各收一次;具体金额以 pricing.reference_options 为准。
图片 + 视频 + 音频
curl -X POST https://your-domain.example/v1/videos/generations \
-H "Authorization: Bearer mk-你的密钥" -H "Content-Type: application/json" \
-d '{"model":"minimax-h3","prompt":"图1保持人物外观,视频1参考动作,音频1参考节奏","duration_seconds":8,"resolution":"768p","aspect_ratio":"16:9","reference_images":["https://example.com/person.png"],"reference_videos":["https://example.com/motion.mp4"],"reference_audios":["https://example.com/rhythm.mp3"],"generate_audio":true}'首尾帧
curl -X POST https://your-domain.example/v1/videos/generations \
-H "Authorization: Bearer mk-你的密钥" \
-F 'prompt=从首帧的站立动作平滑转到尾帧的回头动作' -F 'duration_seconds=5' \
-F 'resolution=768p' -F 'aspect_ratio=9:16' -F 'input_mode=frames' \
-F 'first_frame=@start.png' -F 'last_frame=@end.png' -F 'generate_audio=false'参数错误返回 HTTP 400:missing_prompt、invalid_duration、invalid_resolution、invalid_aspect_ratio、invalid_image、invalid_video_references、too_many_reference_assets 或原有补边参数错误。体积超限为413;服务暂时不可用时为 503 video_capacity_unavailable;未定价为 503 video_pricing_unavailable;站内余额不足为402,任务数量超限为429。参数校验失败不会提交生成。
视频参考图直传(API Key,仅图片参考)
请求 JSON {"filename":"reference.png","mime":"image/png","bytes":12345} 获取 HTTP201 上传授权。支持 PNG、JPEG、WebP、GIF,单张最多20MiB。配置中 api_capabilities.direct_reference_upload 表示此功能当前可用。此步骤及确认步骤只保存素材,不启动生成、不扣视频生成费。
响应形如 {"id":"vr_xxx","upload":{"url":"https://上传地址/","method":"POST","fields":{"key":"指定对象名","token":"短期上传授权"},"expires_at":1793000000000},"expires_at":1793020000000,"max_bytes":20971520}。把返回的全部 fields 和文件字段 file 组成 FormData,POST 到 upload.url,无需再携带本站 API Key。授权仅允许上传该对象和声明的文件大小,5分钟内有效,覆盖已有对象会被拒绝。
上传成功后,以同一视频 API Key 调用 POST /v1/videos/reference-uploads/{id}/complete,请求体为 {}。服务器核对存储中的实际格式、尺寸和大小,成功 HTTP200 返回 {"image":{"id":"vr_xxx","filename":"reference.png","mime":"image/png","bytes":12345,"width":1024,"height":1024,"url":"https://本站/reference-images/public/vr_xxx","created_at":1793000000000,"expires_at":1793028800000}}。重复确认返回同一图片,不重复创建。
将确认返回的编号按顺序放入 reference_image_ids 创建视频。素材从获取上传授权时起最多保留8小时,确认、访问或重复使用都不会延长时间;过期后重新上传。编号仅限所属用户使用。仅图片混合输入的顺序为:multipart 文件、asset_ids、JSON图片、reference_image_ids;建议统一使用一种形式以便确定编号。
// Node.js 22;fileBytes 为本地文件内容,apiKey 为视频用途密钥。
const base = 'https://your-domain.example';
const headers = {Authorization: 'Bearer ' + apiKey, 'Content-Type': 'application/json'};
async function post(path, body) {
const r = await fetch(base + path, {method:'POST', headers, body:JSON.stringify(body)});
const data = await r.json();
if (!r.ok) throw new Error(JSON.stringify(data.error));
return data;
}
const ticket = await post('/v1/videos/reference-uploads', {
filename:'reference.png', mime:'image/png', bytes:fileBytes.length
});
const form = new FormData();
for (const [key,value] of Object.entries(ticket.upload.fields)) form.set(key,value);
form.set('file',new Blob([fileBytes],{type:'image/png'}),'reference.png');
const uploaded = await fetch(ticket.upload.url,{method:'POST',body:form});
if (!uploaded.ok) throw new Error('Upload failed: '+uploaded.status);
const {image} = await post('/v1/videos/reference-uploads/'+ticket.id+'/complete',{});
const task = await post('/v1/videos/generations', {
prompt:'图1保持人物外观,镜头缓缓推进', duration_seconds:5,
resolution:'768p', aspect_ratio:'9:16', reference_image_ids:[image.id]
});编号无效、非本人、过期或文件格式不符返回400;功能关闭返回 video_feature_disabled;直传服务暂不可用返回503。原有 /v1/videos/reference-assets 与生成接口的文件、URL输入保持兼容。网页对应接口为 /api/video/reference-uploads 和 /api/video/reference-uploads/{id}/complete,需要登录及同源请求。
视频参考素材上传(API Key)
使用 multipart 字段 role 和 file。role 支持 images、videos、audios、first_frame、last_frame。仅上传和保存素材,不启动生成,也不扣视频生成费用;此接口与生成接口使用相同的 API Key 用途和模型权限检查。
curl -X POST https://your-domain.example/v1/videos/reference-assets \
-H "Authorization: Bearer mk-你的密钥" -F 'role=videos' -F 'file=@motion.mp4'{"asset":{"id":"ga_素材编号","role":"videos","name":"motion.mp4","mime":"video/mp4","bytes":12345,"width":720,"height":1280,"duration":5,"expires_at":1792000000000}}HTTP201 返回素材编号及已识别的大小、时长、尺寸和过期时间。把编号放进 POST /v1/videos/generations 的 asset_ids 数组即可。上传失败返回400,单文件超限返回413,存储暂不可用返回503。素材过期后需要重新上传。
网页视频参考(登录接口)
上传一份参考素材,返回当前用户的素材编号。此处与下一节是网页内部接口,不是 /v1 开放 API。
鉴权:必须先登录本站,并从本站同源页面发起请求,浏览器携带当前登录 Cookie。API Key、Authorization: Bearer mk-...、x-api-key 均不能替代网页会话。不要把登录 Cookie 放进公开代码或交给第三方。
请求为 multipart/form-data,每次一个文件。浏览器使用 FormData 时不要手工设置 Content-Type,由浏览器生成 multipart boundary。
| 字段 | 类型 | 说明 |
|---|---|---|
role 必填 | string | images、videos、audios、first_frame 或 last_frame。 |
file 必填 | file | 图片和音频单文件最多20MiB,视频单文件最多64MiB。素材类型由文件内容判断。 |
上传成功为 HTTP 201:{"asset":{"id":"ga_xxx","role":"audios","name":"reference.mp3","mime":"audio/mpeg","bytes":12345,"width":0,"height":0,"duration":5,"expires_at":1790000000000}}。duration 单位为秒,expires_at 为毫秒时间戳;返回素材编号,不返回素材源地址。素材只允许其所属用户使用。
参考素材限制
| 类型 | 数量 / 大小 | 格式与时长 |
|---|---|---|
图片 images | 最多9张,单张20MiB | PNG、JPEG、WebP;此会话接口不支持GIF。 |
视频 videos | 最多3个,单个64MiB | MP4、MOV、M4V、WebM;当前没有单独限制参考视频时长。 |
音频 audios | 最多3个,单个20MiB | MP3、WAV、M4A、AAC、FLAC、OGG;每个2–15秒,全部音频合计不超过15秒,必须搭配图片或视频。 |
| 首帧 / 尾帧 | 各最多1张,单张20MiB | PNG、JPEG、WebP;首帧必选、尾帧可选,不与普通图片、视频、音频参考混用。 |
普通参考模式的图片、视频和音频合计最多12个,素材总大小最多300MiB。例如6张图片、3个视频和3个音频可以提交;9张图片、3个视频和3个音频不能提交。素材按创建时间保留8小时,过期后需重新上传。
使用已上传的素材编号创建参考视频任务。HTTP 202 返回站内任务编号,任务、余额、历史记录与原视频流程共用。
请求使用 multipart/form-data 文本字段,不直接附带文件。仅图片参考继续使用原网页 POST /api/video/generate;此新增接口要求启用音频参考、视频参考或首尾帧模式中的至少一项。
| 字段 | 类型 / 默认 | 说明 |
|---|---|---|
prompt 必填 | string | 完整创作描述。 |
duration_seconds 必填 | integer | 成品时长为5–15秒整数,不是参考素材时长。 |
resolution | string / 768p | 768p 或 1080p。 |
aspect_ratio | string / 9:16 | 9:16 或 16:9;与开放 API 的默认比例不同,建议显式传入。 |
asset_ids 必填 | JSON数组字符串 | 例如 ["ga_image","ga_audio"]。编号必须属于当前用户、尚未过期且不重复;图片编号顺序按数组中的图片顺序确定。 |
input_mode | string / references | references 为普通参考;frames 为首尾帧,只允许首帧和可选尾帧素材。 |
enable_video_reference | boolean / false | 开启时必须提供视频素材;有视频素材时也必须开启。首尾帧模式必须关闭。 |
enable_audio_reference | boolean / false | 开启时必须提供音频素材;有音频素材时也必须开启。首尾帧模式必须关闭。 |
generate_audio | boolean / false | 是否生成声音,不等于音频参考开关。网页默认勾选生成声音,请按需要显式传入。 |
expected_cost | number / 可选 | 用户已确认的预计费用,单位为本站分。与提交时实时费用不一致会返回409,不创建任务或预扣余额。 |
multipart 开关使用字符串 true / false 或 1 / 0。首尾帧模式不传普通参考素材,两种参考开关为false;只上传首帧也可生成。此接口固定使用视频模型,无需另外传 model。
同源网页 JavaScript 示例:图片与音频参考
在已登录的本站页面中调用以下函数,参数为文件选择器得到的两个 File 对象。不要将此示例作为 API Key 客户端调用方式。
async function submitAudioReferenceVideo(imageFile, audioFile) {
async function upload(file, role) {
const body = new FormData();
body.append("role", role);
body.append("file", file);
const response = await fetch("/api/video/reference-assets", {
method: "POST", credentials: "same-origin", body
});
const data = await response.json();
if (!response.ok) throw new Error(data.error || "素材上传失败");
return data.asset.id;
}
const imageId = await upload(imageFile, "images");
const audioId = await upload(audioFile, "audios");
const body = new FormData();
body.append("prompt", "参考图中的人物随参考音频节奏运动");
body.append("duration_seconds", "5");
body.append("resolution", "768p");
body.append("aspect_ratio", "16:9");
body.append("input_mode", "references");
body.append("asset_ids", JSON.stringify([imageId, audioId]));
body.append("enable_audio_reference", "true");
body.append("enable_video_reference", "false");
body.append("generate_audio", "true");
const response = await fetch("/api/video/reference-generate", {
method: "POST", credentials: "same-origin", body
});
const data = await response.json();
if (!response.ok) throw new Error(data.error || "视频任务提交失败");
return data; // 后续查询 /api/video/tasks/ + data.task_id
}计费、查询与错误
同源登录请求 GET /api/video/config 可获取最新费率。总费用为 max(分辨率每秒单价 × 成品秒数, pricing.minimum_fen) + 图片加价 × 普通参考图片数 + 已开启参考选项的加价之和,四舍五入到0.5分。pricing.reference_options.audio、video、frames 各有 enabled 和 fee_fen,金额单位为分/次;每个任务每种选项收一次,不按视频或音频文件数量收取,音频与视频同时开启时相加。基础起步价和参考加价由后台独立配置,实时值以配置接口为准。
提交时保存费用快照并预扣,成功结算,最终失败全额退款。参数或价格校验失败不创建任务、不扣费;素材上传本身不收生成费。查询 GET /api/video/tasks 或 GET /api/video/tasks/:id 获取状态,成功的 video_url 是本站播放地址。任务恢复只查询原结果,不重复生成;请求断线后先查任务列表,不要自动再次提交。
新参考任务还返回 input_mode、enable_video_reference、enable_audio_reference、generate_audio 和 reference_summary。普通任务字段、费用和状态规则见视频任务说明。/v1/videos/tasks 可读取同一账户的网页视频任务,公开 API 也已支持提交这些参考模式。
未登录为401;非同源写入请求会被拒绝;无效素材、类型、数量、模式或时长为400;素材体积超限为413;余额不足为402;任务或请求限流为429;确认费用已变化为409。网页错误中的 error 为字符串,与 /v1 的对象错误格式不同。
查询视频任务
任务返回 attempt_count(已尝试次数)和 max_attempts=3(最多尝试次数)。服务可能自动重试或提前结束,期间保持同一任务编号,费用只预留一次。最终失败全额退款。排队和状态查询不增加尝试次数;审核拒绝或参数错误时,请修改输入后再提交。请求超时或结果尚未确认时,请继续查询原任务。
列出当前账户最近任务,并返回生成中、排队数量和余额。
curl https://your-domain.example/v1/videos/tasks -H "Authorization: Bearer mk-视频密钥"轮询单个任务:GET /v1/videos/tasks/:id。状态为 queued、running、succeeded 或 failed。成功响应包含 video_url、generation_id、费用与余额;失败响应含 error 并自动全额退款。服务重启后排队任务继续执行;已提交且有持久任务标识的视频会继续查询原结果,恢复查询期间保留原预扣,最终失败才退款。
列表响应形如 {"ok":true,"tasks":[...],"concurrency":{"queued":0,"running":0,"limit":9999,"max_open_tasks":9999},"balance":100};最多返回账户最近 100 个视频任务,不是当前密钥专属列表。单任务查询本身不扣费,可每 2–3 秒轮询,进度百分比不是完成时间保证。
| 任务字段 | 说明 |
|---|---|
id / task_id | 同一个站内任务编号;后续只查询它,客户端断线后不要自动重复提交。 |
ok / status | 查询已存在任务通常为 HTTP 200;最终失败时 ok=false、status=failed,不同于图像任务失败时仍返回 ok=true。 |
progress / stage / progress_message / logs | 进度 0~100、公开阶段与状态提示;日志含 message、stage、percent 和毫秒 created_at。 |
cost / reserved_cost | 排队和运行时为预扣额;成功时 cost 是结算费用,失败时为 0。reserved_cost 保留最初预扣额,不表示失败后仍扣着该金额。 |
reference_count / reference_padding / padding_mode / padding_color | 提交时的参考图数量与补边设置。 |
created_at / started_at / finished_at | Unix 毫秒;未开始、未完成分别为 null。 |
generation_id / video_url / balance | 只在成功结果中提供;视频地址遵循 8 小时媒体保存期,下载请跟随重定向。 |
{"ok":false,"id":"task_xxx","task_id":"task_xxx","kind":"video","status":"failed","model":"minimax-h3","cost":0,"reserved_cost":8,"error":{"code":"generation_failed","message":"视频生成失败,已退还额度"}}视频任务会出现在工作台左侧任务列表中,完成后可在「生成历史」播放、下载并查看费用。API Key 选择 minimax-h3 或不限模型,用途设为「仅视频生成」或「不限用途」。
图片超分
把一张已有图片交给图片超分服务放大到指定分辨率,不改构图、不重新生成,等价于网页端「无限画布」里对图片点「超分」。
一次只处理 1 张图,按分辨率单价 × 1 张计费(当前 2K 1 分 / 4K 2 分 / 8K 4 分,以 GET /v1/pricing 的 canvas_upscale 为准)。
| 字段 | 类型 | 说明 |
|---|---|---|
image 必填 | string | 图片来源:https 直链、data:image/...;base64,...,或本站 /img/<id> / /reference-images/... 地址 |
image_url / images 可选 | string | 与 image 等价;一次仍只能传 1 张,多传报 too_many_images |
resolution 可选 | string | 2k · 4k(默认) · 8k,其它值按 4k 处理 |
也支持 OpenAI 风格 multipart:image=<file> + resolution。
需要兼容只转发标准图生图接口的网关,可用 POST /v1/images/edits 并指定 model=upscale-2k、upscale-4k 或 upscale-8k,同样只处理一张图,不需要提示词。密钥用途须为 edit 或不限用途,不能绑定视频模型。这些是超分别名,不是普通生图模型,不出现在 /v1/models 列表中。
curl -X POST "{BASE}/v1/images/upscale" \
-H "Authorization: Bearer mk-xxx" \
-H "Content-Type: application/json" \
-d '{"image":"https://example.com/in.png","resolution":"4k"}'{
"ok": true,
"mode": "canvas_upscale",
"resolution": "4k",
"images": ["https://.../img/xxxxxxxx"],
"cost": 2,
"image_count": 1,
"balance": 998
}额外返回 created(Unix 秒)、data:[{"url":"..."}] 与 model: "upscale-4k" 等兼容字段。超分接口不使用 response_format 切换为 base64。
返回的 images 是本站 /img/<id> 地址,受 8 小时媒体保存期约束,请及时下载。失败不收取超分费用。
聊天格式出图
给使用聊天格式调用图片模型的网关提供兼容入口,只生成图片,不提供普通文字聊天、工具调用或视频生成。
messages[].content 可为字符串或 parts 数组;各消息中的文本会合并为提示词。传 {"type":"image_url","image_url":{"url":"https://..."}} 或 data URL 时按图生图处理,否则按文生图处理;密钥用途、模型绑定、参考图张数及费用遵循相应图像接口。
model、n、size、ratio、resolution、response_format 沿用同步图像参数。stream 应省略或为 false,开启时返回 400 unsupported_stream。该接口没有生成前的流式进度。
curl -X POST https://your-domain.example/v1/chat/completions \
-H "Authorization: Bearer mk-你的密钥" \
-H "Content-Type: application/json" \
--max-time 330 \
-d '{"model":"nano-banana-2","messages":[{"role":"user","content":[{"type":"text","text":"保持构图,将背景变为黄昏海滩"},{"type":"image_url","image_url":{"url":"https://example.com/reference.jpg"}}]}],"n":1,"response_format":"url","stream":false}'{
"id": "chatcmpl_xxx",
"object": "chat.completion",
"created": 1760000000,
"model": "nano-banana-2",
"choices": [{"index":0,"message":{"role":"assistant","content":""},"finish_reason":"stop"}],
"data": [{"url":"https://your-domain.example/img/xxx"}],
"usage": {"prompt_tokens":0,"completion_tokens":1,"total_tokens":1}
}choices[0].message.content 是图片 Markdown;data[] 提供 URL 或 base64。usage 是兼容占位统计,不是实际 token 账单;此响应没有本站 cost / balance,费用请查调用历史、生成记录或余额。
Gemini 兼容接口
面向支持 Gemini 请求格式的 SDK 与客户端。把 Base URL 指向本站根地址、填上本站 API Key,使用下面列出的 GenerateContent / Predict 兼容入口出图。这是本站的协议适配层,不是 Google 官方模型服务,也不保证实现 Gemini 或 Vertex AI 的全部功能。
与 OpenAI 接口的关系:两种协议是同一套后端的两张皮——同一把 Key、同一份余额、同一套模型与计费。用哪套只取决于客户端支持哪套,随时可以混着用。
端点一览
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /v1beta/models/{model}:generateContent | 文生图 / 图生图,同步返回 |
| POST | /v1beta/models/{model}:streamGenerateContent?alt=sse | 同上,按 SSE 分片返回 |
| POST | /v1beta/models/{model}:predict | Imagen 风格,结果在 predictions[] |
| POST | /v1beta/models/{model}:countTokens | 本地估算 token 数,不扣费 |
| GET | /v1beta/models | 可用模型列表 |
| GET | /v1beta/models/{model} | 单个模型信息 |
鉴权
支持 x-goog-api-key、?key=、Bearer 和 x-api-key,均指向同一把 mk- 密钥;优先使用请求头,避免 URL 中暴露密钥。
x-goog-api-key: mk-xxxxxxxxxxxxxxxx
?key=mk-xxxxxxxxxxxxxxxx
Authorization: Bearer mk-xxxxxxxxxxxxxxxx缺少或无效的密钥返回 401 UNAUTHENTICATED。
模型名映射
URL 里的 {model} 既可以直接写本站模型 id,也可以写 Gemini / Imagen 的官方模型名,服务端会自动映射:
| 客户端传的模型名 | 实际使用 |
|---|---|
gpt-image-2.5 / gpt-image-2.5-high / nano-banana-2 / nano-banana-2-flash-lite / nano-banana-2.1 / nano-banana-pro | 对应本站模型,原样使用 |
gemini-2.5-flash-image、gemini-3-pro-image-preview、imagen-4.0-generate-001 等 | nano-banana-pro |
名字里含 nano-banana-2 | nano-banana-2 |
名字里含 gpt-image 或 dall-e | gpt-image-2.5(未命中直接站点模型时的兼容映射) |
| 其它无法识别的名字 | 回落到 nano-banana-pro(不报 404,方便客户端换预览版模型名) |
与 OpenAI 侧一致:如果这把密钥绑定了某个模型,映射后与绑定不一致会返回 403 PERMISSION_DENIED;如果密钥限定了用途而本次请求形态不匹配,同样返回 403 PERMISSION_DENIED。
请求体
标准 Gemini contents[].parts[]:文本部分即提示词;inlineData(base64)或 fileData.fileUri(公网 https 链接)会作为参考图走图生图。也支持 Imagen 的 instances[].prompt。
| 参数 | 位置 | 取值 |
|---|---|---|
| 画面比例 | generationConfig.imageConfig.aspectRatio;也读 generationConfig.aspectRatio 和 Imagen 的 parameters.aspectRatio | 1:1、16:9、9:16、4:3、3:4 等 |
| 分辨率 | generationConfig.imageConfig.imageSize;也读 generationConfig.imageSize 和 Imagen 的 parameters.sampleImageSize | 1K:有损 webp 预览,约几十 KB;2K:无损 PNG 原图,默认,base64 可达数 MB。4K 及以上回落到 2K |
| 出图张数 | generationConfig.candidateCount(:predict 读 parameters.sampleCount) | 1 ~ max_output_images |
分辨率别漏传。不传 imageSize 时按 2K 原图出(与 OpenAI 侧默认一致),返回的 inlineData 是数 MB 的 PNG;只要缩略图请显式传 "imageSize": "1K",体积小很多、返回也更快。
{
"contents": [
{ "role": "user", "parts": [ { "text": "一只在草地上奔跑的柴犬,逆光,浅景深" } ] }
],
"generationConfig": {
"candidateCount": 1,
"imageConfig": { "aspectRatio": "16:9", "imageSize": "2K" }
}
}:generateContent 示例
curl -X POST "https://your-domain.example/v1beta/models/gemini-2.5-flash-image:generateContent" \
-H "x-goog-api-key: mk-你的密钥" \
-H "Content-Type: application/json" \
--max-time 600 \
-d '{"contents":[{"parts":[{"text":"一只在草地上奔跑的柴犬,逆光,浅景深"}]}],"generationConfig":{"candidateCount":1,"imageConfig":{"aspectRatio":"16:9","imageSize":"2K"}}}'响应是标准 Gemini 结构,图片以 base64 内联在 inlineData 里,一张图一个 candidate:
{
"candidates": [
{
"content": { "role": "model", "parts": [ { "inlineData": { "mimeType": "image/png", "data": "iVBORw0KGgo..." } } ] },
"finishReason": "STOP",
"index": 0,
"safetyRatings": []
}
],
"modelVersion": "nano-banana-pro",
"responseId": "resp_xxxxxxxx",
"usageMetadata": { "promptTokenCount": 0, "candidatesTokenCount": 1, "totalTokenCount": 1 }
}把 inlineData.data 做 base64 解码即得到图片字节;mimeType 给出真实类型,但不能仅凭 PNG/WebP 判定分辨率,实际尺寸以文件为准。本站不返回 fileData.fileUri,图片一律内联 base64。gpt-image-2.5-high 仍固定输出 1K,忽略分辨率设置。
:streamGenerateContent 与 :predict
流式:Gemini SDK 默认请求 :streamGenerateContent?alt=sse。服务端在生成完成后按 SSE 下发 data: {...} 分片,每张图一个 chunk,最后一个 chunk 带 "finishReason": "STOP"。不带 alt=sse 时返回 JSON 数组(与官方行为一致)。
curl -N -X POST "https://your-domain.example/v1beta/models/gemini-2.5-flash-image:streamGenerateContent?alt=sse" \
-H "x-goog-api-key: mk-你的密钥" \
-H "Content-Type: application/json" \
--max-time 600 \
-d '{"contents":[{"parts":[{"text":"赛博朋克城市夜景,写实"}]}]}'Imagen 风格::predict 用 instances[].prompt 入参,结果在 predictions[].bytesBase64Encoded:
{
"predictions": [
{ "bytesBase64Encoded": "iVBORw0KGgo...", "mimeType": "image/png" }
]
}错误信封与常见错误
/v1beta 的鉴权、生成及参数错误使用下面的 Gemini 结构,与 /v1 不同。共享 API 限流器可能返回 {"error":{"code":"rate_limited","message":"..."}},客户端应先检查 HTTP 429,再按可用字段处理:
{
"error": {
"code": 400,
"message": "contents 中必须包含提示词(text part 或 instances[].prompt)",
"status": "INVALID_ARGUMENT"
}
}| HTTP | status | 典型场景 |
|---|---|---|
| 400 | INVALID_ARGUMENT | 没有提示词、提示词未通过审核、参考图无法识别、请求体过大 |
| 401 | UNAUTHENTICATED | 缺少或无效的 API Key |
| 402 | FAILED_PRECONDITION | 余额不足,无法预扣 |
| 403 | PERMISSION_DENIED | 密钥绑定了别的模型,或密钥用途与本次请求不匹配 |
| 404 | NOT_FOUND | 路径或动作不存在 |
| 429 | RESOURCE_EXHAUSTED | 超出速率限制或并发上限 |
| 500 | INTERNAL | 生成失败或服务端错误(预扣已全额退回) |
| 503 | UNAVAILABLE | 服务暂时繁忙(预扣已全额退回) |
超时提示:同步出图通常 1-5 分钟,请把客户端(以及 generateContent 的 HTTP 超时)设到 320 秒以上。一次请求多张图用 candidateCount;批量出图仍建议走 OpenAI 异步接口,Gemini 协议没有异步版本。
早先 /v1beta 曾整体作为 OpenAI 协议的路径别名(等价于 /v1)。现在 /v1beta/models/* 已是 Gemini 原生入口;其它 /v1beta/* 路径(如 /v1beta/images/generations)仍按旧规则归一化到 /v1,只把 Base URL 设成 /v1beta 的老配置不受影响。
查询余额
查询当前余额和实时价格。生成前先调这个可以避免因余额不足白等一次请求。
curl https://your-domain.example/v1/balance \
-H "Authorization: Bearer mk-你的密钥"{
"ok": true,
"credits": 998.5,
"pricing": {
"text": { "halfFen": 1, "fen": 0.5, "yuan": 0.005 },
"edit": { "halfFen": 3, "fen": 1.5, "yuan": 0.015 },
"upscale4k": null,
"maxOutputImages": 3,
"balanceUnit": "fen",
"promo": false
}
}| 字段 | 说明 |
|---|---|
credits | 当前余额(分) |
pricing.text | 文生图单价。fen 是对外单位,yuan 是元,halfFen 以 0.5 分为单位 |
pricing.edit | 图生图单价,结构同上 |
pricing.upscale4k | 已下线,恒为 null(旧版 2K→4K 修复的加价字段,保留兼容)。要放大请用图片超分 |
pricing.maxOutputImages | 单次最多出图张数,也是预扣的倍数 |
pricing.promo | 站点是否处于活动期。为 true 时价格和各项上限可能临时放宽 |
账户信息
查询密钥所属账户的基本信息。可用来验证密钥是否有效、属于哪个账户。
curl https://your-domain.example/v1/me \
-H "Authorization: Bearer mk-你的密钥"{
"ok": true,
"username": "alice@example.com",
"email": "alice@example.com",
"credits": 998.5,
"credit_unit": "fen",
"created_at": 1754870400000,
"key": { "label": "生产环境-banana", "model": "nano-banana-2", "scope": null, "scope_label": "不限用途" }
}email 在纯用户名注册的账户上为 null。key 描述当前密钥:model 为 null 表示不限模型;scope 为 null 表示不限用途,也可能是 text、edit 或 video,scope_label 为用途显示名称。
使用兑换码
用兑换码给当前账户充值。兑换码由管理员发放,一码只能用一次。
请求参数(JSON)
| 参数 | 类型 | 说明 |
|---|---|---|
code 必填 | string | 兑换码。大小写不敏感,首尾空格会自动去掉。 |
curl -X POST https://your-domain.example/v1/redeem \
-H "Authorization: Bearer mk-你的密钥" \
-H "Content-Type: application/json" \
-d '{"code": "FL53HIJDSTQF"}'{ "ok": true, "added": 100, "balance": 1098.5 }| 状态码 | code | 含义 |
|---|---|---|
| 400 | missing_code | code 为空 |
| 400 | invalid_code | 兑换码不存在 |
| 400 | code_already_used | 该兑换码已被使用过 |
| 429 | rate_limited | 兑换过于频繁(防爆破,默认 10 分钟 30 次) |
并发提交同一个兑换码只会有一次成功入账,其余返回 code_already_used,不会重复加钱。
模型列表
列出这把密钥能用的模型和默认模型。不限用途密钥会同时看到图像模型与 MiniMax H3;video 用途密钥只列视频模型。
{
"ok": true,
"models": [
{ "id": "gpt-image-2.5", "label": "GPT Image 2.5" },
{ "id": "gpt-image-2.5-high", "label": "GPT Image 2.5 high" },
{ "id": "nano-banana-2", "label": "Nano Banana 2" },
{ "id": "nano-banana-2-flash-lite", "label": "Nano Banana 2 Flash Lite", "type": "image", "resolutions": ["1k"], "native_resolution": "1k" },
{ "id": "nano-banana-2.1", "label": "Nano Banana 2.1", "type": "image", "resolutions": ["2k"], "native_resolution": "2k" },
{ "id": "nano-banana-pro", "label": "Nano Banana Pro", "type": "image" },
{ "id": "minimax-h3", "label": "MiniMax H3", "type": "video" }
],
"default_model": "gpt-image-2.5",
"key_model": null
}生成接口的 model 参数只接受这里列出的 id。label 是给界面显示用的名字。
同一响应还包含 OpenAI 兼容的 object:"list" 和 data[],每项有 id、object:"model"、created:0、owned_by:"huajing"。不限模型的 text/edit 用途密钥仅列图像模型。
key_model 是当前密钥绑定的模型,不限模型时为 null。绑定过的密钥这里只会返回那一个模型,default_model 也跟着变成它:
{
"ok": true,
"models": [ { "id": "nano-banana-2", "label": "Nano Banana 2" } ],
"default_model": "nano-banana-2",
"key_model": "nano-banana-2"
}单个模型
GET /v1/models/:id 返回兼容模型元数据,不带 ok。仍检查当前密钥的模型绑定和用途;非法模型或不匹配绑定返回 400/403。
curl https://your-domain.example/v1/models/nano-banana-2 \
-H "Authorization: Bearer mk-你的密钥"
{"id":"nano-banana-2","object":"model","created":0,"owned_by":"huajing"}价格与限制
一次性拿到所有价格和参数上限。写客户端时建议启动时调一次并缓存几分钟,而不是把这些值硬编码。
{
"ok": true,
"pricing": {
"text": { "halfFen": 1, "fen": 0.5, "yuan": 0.005 },
"edit": { "halfFen": 3, "fen": 1.5, "yuan": 0.015 },
"upscale4k": null,
"maxOutputImages": 3,
"balanceUnit": "fen",
"promo": false
},
"canvas_upscale": { "2k": 1, "4k": 2, "8k": 4 },
"video_h3": {
"model": "minimax-h3",
"durations": [5,6,7,8,9,10,11,12,13,14,15],
"resolutions": ["768p", "1080p"],
"aspect_ratios": ["16:9", "9:16"],
"pricing": { "rate_fen_per_second": { "768p": 0, "1080p": 0 }, "minimum_fen": 6, "reference_enabled": false, "reference_fen": 0 },
"concurrency_limit": 9999,
"max_open_tasks": 9999
},
"limits": {
"max_output_images": 3,
"max_reference_images": 30,
"max_concurrent_per_user": 9999,
"max_open_async_tasks": 9999,
"resolutions": ["1k", "2k"],
"ratios": ["1:1", "16:9", "9:16", "4:3", "3:4"],
"custom_ratio": true,
"custom_size": true,
"size_fields": ["size", "output_size", "dimensions"],
"upscale4k": false,
"deliveries": []
}
}| 字段 | 说明 |
|---|---|
limits.max_output_images | 出图上限及同步 n 的合法上限;同步按 n 预扣,异步图像按此上限预扣 |
limits.max_reference_images | 图生图单次参考图上限,以账户实时配置为准 |
limits.max_concurrent_per_user | 你能同时跑几个生成任务,默认 9999 |
limits.max_open_async_tasks | 异步接口同时处于排队+进行中的任务上限,默认 9999 |
limits.resolutions | resolution 参数的合法取值 |
limits.ratios | 常用比例,另外允许留空;custom_ratio=true 时也可传其它合法的宽:高 |
limits.custom_ratio / custom_size / size_fields | 是否接受自定义比例/尺寸及尺寸字段别名;不保证输出恰好等于请求尺寸 |
policy / sale | 当前生成策略及活动信息。sale.mode 为 discount(旧优惠价)或 free_quota(免费额度)。免费额度是每场活动全站共用的公共池,quotaScope="global";图片按成功张数、视频按成功条数,与秒数无关。imageQuota、videoQuota 的 limit、used、reserved、globalRemaining 均为公共池数据。perUserEnabled 表示是否另外限制个人分配;各池的 userLimit、userUsed、userReserved、userRemaining 为当前用户本场数据,未开启个人上限时 userLimit 和 userRemaining 为null。remaining 是公共池与个人限制共同约束后的可用数量。个人额度不预先占满公共库存,也不保证在公共池耗尽后仍可免费使用。所有 API Key 与网页共用。仅 running、eligible 和对应参与开关为真时免费;余额须严格大于 minBalanceFen。提交先预占,最终失败归还,重试不重复占用。额度不足时返回HTTP403、sale_quota_exhausted及“免费额度耗尽”,不自动结束活动或转收费,由管理员增加总量或结束活动恢复常规计费。明确指定的批量张数不足时整次拒绝,自动出图最多交付可用免费张数。freeBlocked=true 表示账号被禁止参与免费活动,仍可按常规价格付费使用。未参与、活动结束或未达余额门槛时也按原有规则计费。视频免费涵盖基础费及参考加价,独立图片超分不包含在内。 |
limits.image_to_image / min_text_balance_fen | 图生图是否开放及文生图最低余额门槛;门槛不是每次额外收取的费用 |
canvas_upscale | 图片超分各分辨率单价(分/张):2k / 4k / 8k,对应 POST /v1/images/upscale |
video_h3 | MiniMax H3 参数、本站费率、参考图费与并发上限 |
video_h3.sale | 当前账户活动状态,同上;GET /v1/videos/config 直接返回 sale。活动和功能开关由后台配置。确认费用传 expected_cost 时,免费视频填0;最后一条免费额度被其他任务占用时返回403、sale_quota_exhausted,不会转为付费提交。价格发生变化仍返回409;请重新查询配置并取得用户确认。 |
健康检查
服务存活探针。注意路径不在 /v1 下,也不需要密钥,适合给负载均衡或监控用。
{ "ok": true, "uptime": 86400.5, "inflight": 2 }| 字段 | 说明 |
|---|---|
uptime | 进程已运行秒数 |
inflight | 当前全站正在进行的生成任务数。接近全站上限(默认 9999)时新请求会收到 503 busy |
生成记录
按时间倒序返回本账户的历史生成记录,包含失败的任务。
查询参数
| 参数 | 说明 |
|---|---|
limit 可选 | 返回条数,默认 30,最大 100。非法或超范围的值会回落到默认/上限,不报错。 |
curl "https://your-domain.example/v1/generations?limit=5" \
-H "Authorization: Bearer mk-你的密钥"{
"ok": true,
"generations": [
{
"id": 42,
"prompt": "一只在草地上奔跑的柴犬",
"ratio": "16:9",
"resolution": "2k",
"model": "gpt-image-2.5",
"cost": 1,
"cost_units": 2,
"status": "success",
"duration_ms": 42318,
"duration_sec": 42.3,
"created_at": 1754870400000,
"images": ["https://.../a1b2c3.png"]
},
{
"id": 43,
"prompt": "海边日落时的帆船",
"ratio": "16:9",
"resolution": "768p",
"model": "minimax-h3",
"cost": 15,
"cost_units": 30,
"status": "success",
"duration_ms": 128000,
"duration_sec": 128.0,
"created_at": 1754870500000,
"images": [],
"video_url": "https://your-domain.example/media/video/43/SIGNATURE",
"videos": ["https://your-domain.example/media/video/43/SIGNATURE"],
"video_duration_seconds": 10
}
],
"speed": {
"count": 40,
"avg_duration_ms": 38200,
"avg_duration_sec": 38.2,
"by_resolution": {
"1k": { "label": "1K", "count": 5, "avg_duration_ms": 12100, "avg_duration_sec": 12.1 },
"2k": { "label": "2K", "count": 30, "avg_duration_ms": 28400, "avg_duration_sec": 28.4 },
"hd4k": { "label": "4K", "count": 5, "avg_duration_ms": 61000, "avg_duration_sec": 61.0 }
}
}
}status 为 "success" 或 "failed"。失败记录的 cost 恒为 0(已退款),images 为空数组。model 是这次实际使用的模型,这个字段上线之前的老记录为 null。duration_sec 是任务耗时(秒,一位小数)。视频记录使用 video_url 和 videos 返回站内播放地址,并通过 video_duration_seconds 标出片长;每条记录中的 cost 是本站实际消耗。speed 是本账户成功出图的平均时速:avg_duration_sec 为全部平均,by_resolution 按 1k / 2k / hd4k(4K)分类。
历史里的图片和视频地址都是站内播放/读取地址。请按接口返回的地址读取媒体文件;视频费用和状态可直接在同一条记录里核对。
调用历史
返回本站识别到的 /v1 与 /v1beta 密钥逐次调用记录,成功和失败都记。默认只看当前密钥;纯粹无法识别密钥的请求不能归属到账号。
查询参数
| 参数 | 说明 |
|---|---|
limit 可选 | 返回条数,默认 50,最大 200 |
scope 可选 | 默认 key,只返回当前密钥的记录;传 account 返回本账户所有密钥的记录 |
curl "https://your-domain.example/v1/usage?limit=20" \
-H "Authorization: Bearer mk-你的密钥"{
"ok": true,
"scope": "key",
"summary": {
"days": 7,
"total": 128,
"succeeded": 124,
"failed": 4,
"images": 131,
"cost": 141.5,
"cost_units": 283,
"avg_duration_ms": 38120,
"avg_duration_sec": 38.1,
"by_resolution": {
"1k": { "label": "1K", "count": 8, "avg_duration_ms": 12100, "avg_duration_sec": 12.1 },
"2k": { "label": "2K", "count": 110, "avg_duration_ms": 28400, "avg_duration_sec": 28.4 },
"hd4k": { "label": "4K", "count": 10, "avg_duration_ms": 61000, "avg_duration_sec": 61.0 }
}
},
"calls": [
{
"id": 9012,
"api_key_id": 7,
"api_key": "mk-a1b2c3d********",
"key_label": "生产环境-banana",
"method": "POST",
"path": "/v1/images/generations",
"model": "nano-banana-2",
"status": 200,
"ok": true,
"error_code": null,
"cost": 1,
"cost_units": 2,
"image_count": 1,
"duration_ms": 42318,
"duration_sec": 42.3,
"created_at": 1754870400000
},
{
"method": "POST",
"path": "/v1/images/generations",
"model": "gpt-image-2.5",
"status": 403,
"ok": false,
"error_code": "model_not_allowed",
"cost": 0,
"image_count": 0,
"reference_count": 0,
"duration_ms": 3,
"duration_sec": 0,
"created_at": 1754870300000
}
]
}| 字段 | 说明 |
|---|---|
summary | 近 7 天的汇总:调用次数、成功/失败数、出图张数、总花费(分)。平均时速见 avg_duration_sec(全部)和 by_resolution(1K / 2K / 4K) |
ok | 该次 HTTP 调用是否 2xx,等价于 status >= 200 && status < 300。异步提交的 202 只代表已接收,不代表生成最终成功,最终结果另查任务。 |
error_code | 失败时的 error.code,成功为 null |
reference_count | 本次调用服务端实际收到的参考图张数(图生图 / 超分 / chat / Gemini 带图请求会有具体数字)。null 表示该接口不带参考图。用来核对「少了图二」是客户端没把图传上来,还是系统丢图 |
model | 本次用的模型;被 model_not_allowed 拒掉时记的是它想调用的那个,方便定位是哪段代码传错了。不涉及模型的接口为 null |
cost | 该 HTTP 调用的记账金额(分)。视频提交先记录预扣,最终结算或退款后会更新;异步图像提交时尚未预扣,不可将调用历史当作完整生成账单,请结合生成记录和流水。 |
duration_sec | 服务端处理耗时(秒,一位小数),含等待生成完成的时间。兼容字段 duration_ms 是同一数值的毫秒 |
by_resolution | 成功出图按分辨率分类的平均时速。键为 1k / 2k / hd4k,值为 avg_duration_sec 和 count |
被限流挡掉的 429 也会记进来,所以速率调优可以直接看这里。记录保留 30 天,更早的会被自动清理——需要长期留存请自行定期拉走。
用已删除的密钥发请求同样会记在它名下(401 api_key_revoked),方便定位「哪台机器上还有个旧脚本在跑」。完全不认识的密钥无从归属,不会记录。
额度流水
按时间倒序返回额度变动明细,包括注册赠送、充值、兑换、扣费和退款。
查询参数
| 参数 | 说明 |
|---|---|
limit 可选 | 返回条数,默认 50,最大 200 |
{
"ok": true,
"ledger": [
{ "delta": -1.5, "delta_units": -3, "reason": "文生图 预扣最多 3 张", "balance_after": 998.5, "created_at": 1754870400000 },
{ "delta": 1, "delta_units": 2, "reason": "按实际输出张数退回差额", "balance_after": 999.5, "created_at": 1754870460000 },
{ "delta": 100, "delta_units": 200,"reason": "兑换码充值 FL53HIJDSTQF", "balance_after": 1099.5, "created_at": 1754870500000 }
]
}delta 为正表示入账,为负表示扣费;balance_after 是该笔变动之后的余额。图像生成存在多扣差额时会有预扣和退款两条,没有差额则不需要退款记录;视频成功按预扣额结算,失败返还预扣。按流水净额核对费用。
无限画布
登录网页端后,工作台顶部的「无限画布」标签页。这是一块没有边界的平面,用来把多轮尝试铺开摆在一起看,而不是像生成历史那样挤成一列。画布本身是网页端功能,但画布上的图片超分已开放接口(见 图片超分);画布上出图和在「开始生成」页出图走的是同一套计费,单价一样。
基本操作
| 操作 | 怎么做 |
|---|---|
| 平移 | 在空白处按住拖动 |
| 缩放 | 滚轮或触控板双指,以光标为锚点;也可以点工具栏的 − / +。范围 10%~400% |
| 看全部 | 点「回到中心」,会自动缩放到刚好装下画布上所有图并居中 |
| 全屏 | 点「全屏」铺满整个窗口,Esc 退出 |
| 移动 / 缩放单张图 | 拖图片本体移动;选中后拖右下角的小方块等比缩放。松手才写库,拖动过程不会一直发请求 |
| 删除 | 悬停图片点「删除」,或选中后按 Delete / Backspace |
就地生成
在画布任意空白处双击,原地弹出输入框,填提示词、选模型比例和分辨率,出的图就落在你双击的位置。生成过程中该位置显示进度占位,不阻塞你继续在别处双击排下一张——多个任务可以同时跑(默认并发 9999,见 /v1/pricing 的 limits.max_concurrent_per_user)。一次出多张时会沿横向依次排开,不会叠在一起。
Ctrl(Mac 上 Cmd)加 Enter 可以直接提交,Esc 关掉输入框。
基于已有图片再生成
悬停任意图片,右上角出现「再生成」,点开的输入框会带上这张图作为底图,模型和比例默认沿用原图。这走的是图生图那条路,等价于把原图当参考图重新出一张,但不需要你先下载再上传——服务端本地就存着这张图的字节,直接拿来用。
由此产生的新图会带一个「改自上一张」的角标,点角标会把视野移到它的来源图并高亮。多轮迭代因此会在画布上自然形成一条看得见的链路,这也是画布相对生成历史的主要价值:你能看出第 7 张是从第 3 张分叉出来的。
导入历史图片
点工具栏「导入历史图片」,弹窗里以缩略图列出你最近的生成记录,勾选想要的,或者用「全选」一次带走。已经在画布上的会置灰并标注「已在画布」,不会重复导入。确认后按网格铺在当前视口左上角附近。
图片会过期,记得下载
画布上的图和生成历史引用的是同一批文件,同样受保存期约束(当前 8 小时,到期失效并自动清理)。到期后画布上对应的卡片会变成「图片已过期」的占位,这是不可恢复的。所以画布适合承载当次创作过程,不要当成长期作品库。
悬停图片点「下载」即可存到本地,这是唯一能长期保住图的办法。
另外每个账号的画布最多放 500 张图,超出会提示先删一些。
错误码总表
按 error.code 处理,不要匹配 message。
| 状态码 | code | 含义 | 建议处理 |
|---|---|---|---|
| 400 | missing_prompt | 缺少提示词 | 修正请求 |
| 400 | prompt_too_long | 提示词超过当前字符上限;high 图像模型无本站字符上限 | 缩短后重试 |
| 400 | invalid_n | 出图张数不是合法整数或超过配置上限 | 查询 limits.max_output_images |
| 400 | invalid_response_format | 同步图像返回格式非法 | 使用 url 或 b64_json |
| 400 | invalid_size / invalid_ratio | 尺寸或比例格式、范围不合法 | 按图像参数约束修正请求 |
| 400 | unsupported_stream | 聊天格式出图开启了流式 | 省略 stream 或设为 false |
| 400 | invalid_duration / invalid_resolution / invalid_aspect_ratio | 视频时长、分辨率或比例不合法 | 查询 /v1/videos/config |
| 400 | invalid_reference_padding / invalid_padding_mode / invalid_padding_color | 视频首张图补边参数不合法 | 修正开关、模式或颜色 |
| 400 | missing_code | 缺少兑换码 | 修正请求 |
| 400 | missing_image | 图生图未提供参考图 | 修正请求 |
| 400 | unsupported_model | 模型不在支持列表 | 查 /v1/models |
| 400 | prompt_rejected | 提示词未通过审核 | 不要重试,改提示词 |
| 400 | invalid_image | 图片无法识别、下载失败或指向内网 | 换一张图或换公网 URL |
| 400 | too_many_reference_images | 参考图超量 | 减少张数 |
| 400 | too_many_images | 图片超分一次传了多张图 | 只传 1 张 |
| 400 | invalid_code | 兑换码不存在 | 核对兑换码 |
| 400 | code_already_used | 兑换码已使用 | 换一个码 |
| 400 | invalid_json | 请求体不是合法 JSON | 检查序列化 |
| 400 | LIMIT_FILE_SIZE | multipart 单张图片超过 20 MiB | 压缩后重传 |
| 401 | invalid_api_key | 密钥不存在 | 不要重试,检查密钥 |
| 401 | api_key_revoked | 密钥已被删除 | 不要重试,重新创建一把 |
| 402 | insufficient_credits | 余额不足 | 不要重试,先充值 |
| 402 | minimum_balance_required | 常规模式下文生图发起前余额低于门槛(limits.min_text_balance_fen) | 不要重试,先充值 |
| 403 | model_not_allowed | 密钥绑定了别的模型 | 不要重试,换对应模型的密钥 |
| 403 | scope_not_allowed | 密钥用途不匹配(文生图 / 图生图 / 视频生成) | 不要重试,换用途匹配的密钥 |
| 413 | payload_too_large | 请求体超限 | 改用 multipart 上传 |
| 413 | reference_images_too_large | 参考图片合计超过 300 MiB 或请求体超过接口的参考图传输上限 | 压缩或减少参考图 |
| 429 | rate_limited | 超出速率限制 | 指数退避后重试 |
| 429 | too_many_requests | 你的并发生成数已满 | 等待在跑的任务完成,或改用异步接口排队 |
| 429 | too_many_tasks | 未完成的异步任务已达上限 | 等已提交的任务结束再提交 |
| 404 | not_found | 异步任务不存在或不属于当前账号 | 核对任务 id 和密钥 |
| 500 | generation_failed | 生成失败,已退款 | 可重试 |
| 500 | no_output | 本次未产出图片,已退款 | 可重试 |
| 500 | generation_stall | 生成服务长时间无进度,已自动重试或退款 | 可重试 |
| 500 | generation_timeout | 生成超时,已退款 | 可重试 |
| 500 | node_transport_failed | 服务通信失败,已自动重试或退款 | 可重试 |
| 500 | internal_error | 服务端内部错误 | 可重试,持续出现请联系管理员 |
| 503 | no_channel | 服务暂时繁忙,已退款 | 稍后重试 |
| 503 | busy | 全站并发已满,已退款 | 稍后重试 |
| 503 | upscale_failed | 图片超分失败(服务暂时不可用等) | 稍后重试 |
| 503 | video_pricing_unavailable | 视频所选分辨率费率未启用 | 换已启用分辨率或联系管理员 |
| 500 | cache_miss | 图片已生成,但无法读取字节返回 base64 | 先查询生成记录和流水,再决定是否重提 |
| 任务失败字段 | video_reference_processing_failed | 开启补边后,首张参考图处理失败 | 检查图片尺寸和格式;最终失败返还预扣 |
重试建议
- 可以重试:
generation_failed、no_channel、busy、internal_error、rate_limited、too_many_requests。建议指数退避,首次等 5 秒起步。 - 不要重试:所有 400 类错误、
invalid_api_key、api_key_revoked、model_not_allowed、insufficient_credits。重试只会白白消耗速率配额。
完整示例
依赖 requests(pip install requests)。包含超时设置、错误分类和自动重试。
import time
import requests
BASE = "https://your-domain.example"
API_KEY = "mk-你的密钥"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# 生成最长 5 分钟,超时必须给够,否则会掐断服务端还在正常处理的请求
TIMEOUT = (10, 330) # (连接超时, 读取超时)
RETRYABLE = {"generation_failed", "no_channel", "busy", "internal_error", "rate_limited"}
class ApiError(Exception):
def __init__(self, code, message):
super().__init__(f"[{code}] {message}")
self.code = code
def generate(prompt, ratio="", resolution="2k", model=None, max_retries=3):
payload = {"prompt": prompt, "ratio": ratio, "resolution": resolution}
if model:
payload["model"] = model
for attempt in range(max_retries):
response = requests.post(
f"{BASE}/v1/images/generations",
headers={**HEADERS, "Content-Type": "application/json"},
json=payload,
timeout=TIMEOUT,
)
data = response.json()
if response.ok:
return data
error = data.get("error", {})
code = error.get("code", "unknown")
if code not in RETRYABLE or attempt == max_retries - 1:
raise ApiError(code, error.get("message", "未知错误"))
time.sleep(5 * (2 ** attempt)) # 5s, 10s, 20s
def edit(image_path, prompt, **kwargs):
with open(image_path, "rb") as handle:
response = requests.post(
f"{BASE}/v1/images/edits",
headers=HEADERS,
files={"image": handle},
data={"prompt": prompt, **kwargs},
timeout=TIMEOUT,
)
data = response.json()
if not response.ok:
error = data.get("error", {})
raise ApiError(error.get("code", "unknown"), error.get("message", ""))
return data
if __name__ == "__main__":
balance = requests.get(f"{BASE}/v1/balance", headers=HEADERS, timeout=30).json()
print(f"当前余额 {balance['credits']} 分,文生图单价 {balance['pricing']['text']['fen']} 分")
result = generate("雪后的京都清水寺清晨,薄雾,暖色灯笼", ratio="16:9")
print(f"花费 {result['cost']} 分,余额 {result['balance']} 分")
for index, url in enumerate(result["images"]):
image = requests.get(url, timeout=60)
with open(f"output_{index}.png", "wb") as handle:
handle.write(image.content)
print(f"已保存 output_{index}.png")Node.js 18+ 自带 fetch,无需额外依赖。注意必须显式放宽超时,否则默认设置会提前中断。
const fs = require("node:fs");
const BASE = "https://your-domain.example";
const API_KEY = "mk-你的密钥";
const RETRYABLE = new Set(["generation_failed", "no_channel", "busy", "internal_error", "rate_limited"]);
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
async function call(path, options = {}) {
// 生成最长 5 分钟,给到 330 秒留出余量
const response = await fetch(BASE + path, {
...options,
headers: { Authorization: `Bearer ${API_KEY}`, ...options.headers },
signal: AbortSignal.timeout(330000),
});
const data = await response.json();
if (!response.ok) {
const error = new Error(data.error?.message || "请求失败");
error.code = data.error?.code || "unknown";
throw error;
}
return data;
}
async function generate(prompt, options = {}, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
return await call("/v1/images/generations", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt, ...options }),
});
} catch (error) {
if (!RETRYABLE.has(error.code) || attempt === maxRetries - 1) throw error;
await sleep(5000 * 2 ** attempt);
}
}
}
async function edit(imagePath, prompt, options = {}) {
const form = new FormData();
form.append("image", new Blob([fs.readFileSync(imagePath)]), imagePath.split(/[\\/]/).pop());
form.append("prompt", prompt);
for (const [key, value] of Object.entries(options)) form.append(key, value);
return call("/v1/images/edits", { method: "POST", body: form });
}
(async () => {
const { credits, pricing } = await call("/v1/balance");
console.log(`当前余额 ${credits} 分,文生图单价 ${pricing.text.fen} 分`);
const result = await generate("赛博朋克风格的东京街头,雨夜,霓虹倒影", { ratio: "16:9", resolution: "2k" });
console.log(`花费 ${result.cost} 分,余额 ${result.balance} 分`);
for (const [index, url] of result.images.entries()) {
const image = await fetch(url);
fs.writeFileSync(`output_${index}.png`, Buffer.from(await image.arrayBuffer()));
console.log(`已保存 output_${index}.png`);
}
})().catch(error => {
console.error(`失败 [${error.code}]: ${error.message}`);
process.exit(1);
});需要 curl 和 jq。演示生成后直接下载所有图片。
#!/usr/bin/env bash
set -euo pipefail
BASE="https://your-domain.example"
API_KEY="mk-你的密钥"
# 先看余额
curl -sS "$BASE/v1/balance" -H "Authorization: Bearer $API_KEY" | jq
# 生成图片。--max-time 必须大于服务端 5 分钟的生成上限
response=$(curl -sS -X POST "$BASE/v1/images/generations" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
--max-time 330 \
-d '{"prompt": "北欧极简客厅,自然光,原木家具", "ratio": "4:3"}')
if [ "$(echo "$response" | jq -r '.ok // false')" != "true" ]; then
echo "失败: $(echo "$response" | jq -r '.error.code'): $(echo "$response" | jq -r '.error.message')" >&2
exit 1
fi
echo "花费 $(echo "$response" | jq -r '.cost') 分,余额 $(echo "$response" | jq -r '.balance') 分"
# 下载全部结果
echo "$response" | jq -r '.images[]' | while IFS= read -r url; do
filename="output_$(date +%s)_$RANDOM.png"
curl -sS -o "$filename" "$url"
echo "已保存 $filename"
done常见问题
价格、1K/2K、模型参数在哪看?
就在本页最上面的表格。图像价格与参数,以及视频费率和费用估算,可从 GET /v1/pricing 或 GET /v1/videos/config 获取。
有没有 SD2、SD2.5,或者视频?
图像模型包括 gpt-image-2.5、gpt-image-2.5-high、nano-banana-2、nano-banana-2-flash-lite、nano-banana-2.1 和 nano-banana-pro;视频模型是 minimax-h3,通过 /v1/videos 异步生成。旧值 gpt-image 会自动兼容到 gpt-image-2.5。
各模型的参数一样吗?价格一样吗?
生图参数一样:prompt / model / ratio / resolution,图生图再加参考图。计费只有文生图、图生图两档,不按模型加价。gpt-image-2.5-high 固定输出 1K;nano-banana-2-flash-lite 固定使用 1K 原图;nano-banana-2.1 固定使用 2K 原图。其余图片模型沿用各自的分辨率选项。
想要 4K / 8K 怎么办?
普通出图接口最高就是 2K 原图(传 resolution=4k 会回落到 2k)。要放大到 4K / 8K 请用 POST /v1/images/upscale:它把一张已有图片按原比例超分到指定分辨率、不改构图,按分辨率计费(2k / 4k / 8k,实时价格见 GET /v1/pricing 的 canvas_upscale)。
请求一直卡着不返回,是挂了吗?
大概率没挂。生成是同步的,正常就要 1-5 分钟。请确认客户端读取超时设到了 320 秒以上。如果你在 nginx 之类的反向代理后面,代理的 proxy_read_timeout 也要一起调大,否则会被代理提前掐断。生成长时间无进度时,服务会尝试自动恢复。请查询原任务状态,避免重复提交。
能异步提交、轮询取结果吗?
可以。调 POST /v1/images/generations-async(文生图)或 POST /v1/images/edits-async(图生图),拿到 id 后按 2-3 秒间隔轮询 GET /v1/images/tasks/:id,直到 status 为 succeeded 或 failed。没有 webhook。同步接口仍然可用,超时请继续设到 320 秒以上。
用 OpenAI / NewAPI 的聊天接口怎么调?
现在支持图片模型的 POST /v1/chat/completions 兼容入口。把文字消息合并成提示词即可文生图;消息里的 image_url、image 部分会进入图生图。接口返回标准 choices,同时附带图片 data 数组。需要更完整的图片参数时,也可以直接调用 /v1/images/generations 或 /v1/images/edits。
用 Gemini SDK、Cherry Studio 的 Gemini 渠道怎么接?
Base URL 填本站地址(例如 https://your-domain.example),API Key 填你在这里创建的 mk- 密钥,模型名写 gemini-2.5-flash-image 之类的官方名即可,也可以直接写本站模型 id。协议走 /v1beta/models/...,完整说明见 Gemini 兼容接口。注意 /v1beta 现在是 Gemini 原生协议,不要再给 OpenAI 类客户端填这个地址——那类客户端请填根地址、/v1 或 /api/v1。
为什么请求刚发出去余额就掉了一大截?
那是图像预扣。同步图像按 n、异步图像按最多输出张数预扣,完成后按实际张数结算。视频任务按时长与参考图费预扣。以响应里的 cost 和 balance 为准。
失败了会退款吗?
生成最终失败会全额退还预扣;视频重启后会继续查询原任务,不会仅因重启就退款重提。HTTP 超时或图片字节读取错误不一定表示生成失败,请先查任务、生成历史和流水。详见计费与恢复规则。
图片链接过一段时间就 403 / 404 了?
返回的图片地址受保存期限约束。需要长期保留时,请在到期前下载并保存到自己的存储空间。
ratio 或 size 设了但出图比例不太对?
比例和尺寸参数不保证与生成文件逐像素一致。支持 size、output_size、dimensions 等字段,例如 1008x1344;请结合响应中的 requested_*、normalized_* 和实际文件尺寸核对结果。
图生图能一次传多张参考图吗?
能。上限以 GET /v1/pricing 返回的 max_reference_images 为准。支持按顺序传入多张参考图;超过上限返回 too_many_reference_images。
密钥能创建几个?弄丢了怎么办?
可创建多把密钥按用途区分。登录后可查看、复制自己的密钥。旧密钥若暂不支持查看,可录入自己保存的原值;原值遗失时请撤销旧密钥并重新创建。
怎么把几个模型的用量分开统计?
给每个模型各建一把绑定该模型的密钥,然后用 GET /v1/usage 分别看各自的调用次数和花费。这么做还顺带上了一道保险:绑定 nano-banana-2 的密钥不可能因为哪里传错参数就跑去调 gpt-image-2.5。
已经在用的密钥能改绑定的模型吗?
不能,绑定只在创建时确定。这是有意的——中途改绑定会让历史记录变得没法解释:同一把密钥前后调的是两个模型,按密钥做的用量统计就对不上了。换模型请新建一把,旧的确认没人用了再删。
调用历史能留多久?能导出吗?
默认保留 30 天,之后自动清理。要长期留存就定期拉 GET /v1/usage?scope=account 存到自己那边;单次最多返回 200 条,按 created_at 自行去重即可。
API 能管理其他用户或改站点配置吗?
不能。API Key 仅可操作所属账户的数据。
为什么 /v1/ledger 里一次生成有两条记录?
有多扣差额时,一条是预扣,一条是按实际张数退回差额。没有差额就没有退款记录,不保证每次正好两条。按流水净额核对花费。