图片生成
通过文本提示词和参考图生成 AI 图片,支持同步与异步任务,并可预估积分消耗。
图片生成 API 将文本提示词(可选地由参考图引导)转化为一张或多张图片。你可以用三种方式调用:
- 同步 ——
POST /v1/images/generation会阻塞到图片生成完成,并在响应体中返回模型原始输出 (base64 图片数据)。 - 异步 ——
POST /v1/images/generation/async立即返回taskId,随后轮询GET /v1/images/generation/tasks/{taskId}获取结果(托管图片 URL)。 - 先预估 ——
POST /v1/images/generation/estimate-credits返回积分成本以及账户是否可生成, 不消耗任何额度。
所有端点都需要 API key(Authorization: Bearer $LISTENHUB_API_KEY)。在
listenhub.ai/settings/api-keys 创建 key。
两个生成端点返回数据的方式不同。同步端点直接在响应体中返回模型原始 JSON(不包裹在标准
{ code, message, data } 信封里)。异步和预估端点使用标准包裹信封。详见
响应格式。
生成图片(同步)
POST /v1/images/generation
从文本提示词生成图片,并阻塞到图片就绪。可选地提供参考图以引导风格或内容。响应体是模型原始输出 —— 包含 base64 图片数据的 JSON。
基础生成
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"model": "gemini-3-pro-image",
"prompt": "A serene mountain landscape at sunset with a reflective lake",
"imageConfig": {
"aspectRatio": "16:9",
"imageSize": "2K"
}
}'const response = await fetch(
'https://api.marswave.ai/openapi/v1/images/generation',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
provider: 'google',
model: 'gemini-3-pro-image',
prompt: 'A serene mountain landscape at sunset with a reflective lake',
imageConfig: {
aspectRatio: '16:9',
imageSize: '2K',
},
}),
},
)
const data = await response.json()
// data.candidates[0].content.parts[0].inlineData 中是生成的图片import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'provider': 'google',
'model': 'gemini-3-pro-image',
'prompt': 'A serene mountain landscape at sunset with a reflective lake',
'imageConfig': {
'aspectRatio': '16:9',
'imageSize': '2K',
},
},
)
data = response.json()
# data['candidates'][0]['content']['parts'][0]['inlineData'] 中是生成的图片要使用 GPT-Image-2,将 provider 设为 "openai"、model 设为 "gpt-image-2"。请求和响应格式
相同 —— 只有 provider、model 和 imageConfig 不同。详见
厂商与模型矩阵。
携带参考图生成
提供参考图以引导输出。每张参考图要么是 URL(fileData),要么是 base64 内联数据
(inlineData)。你可以在一次请求中混用两种格式。
使用图片 URL
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"model": "gemini-3-pro-image",
"prompt": "Transform this scene into a watercolor painting style",
"referenceImages": [
{
"fileData": {
"fileUri": "https://example.com/my-photo.jpg",
"mimeType": "image/jpeg"
}
}
],
"imageConfig": {
"aspectRatio": "1:1",
"imageSize": "2K"
}
}'const response = await fetch(
'https://api.marswave.ai/openapi/v1/images/generation',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
provider: 'google',
model: 'gemini-3-pro-image',
prompt: 'Transform this scene into a watercolor painting style',
referenceImages: [
{
fileData: {
fileUri: 'https://example.com/my-photo.jpg',
mimeType: 'image/jpeg',
},
},
],
imageConfig: {
aspectRatio: '1:1',
imageSize: '2K',
},
}),
},
)
const data = await response.json()import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'provider': 'google',
'model': 'gemini-3-pro-image',
'prompt': 'Transform this scene into a watercolor painting style',
'referenceImages': [
{
'fileData': {
'fileUri': 'https://example.com/my-photo.jpg',
'mimeType': 'image/jpeg',
}
}
],
'imageConfig': {
'aspectRatio': '1:1',
'imageSize': '2K',
},
},
)
data = response.json()使用 base64 内联数据
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"model": "gemini-3-pro-image",
"prompt": "Create a cartoon version of this portrait",
"referenceImages": [
{
"inlineData": {
"data": "<BASE64_ENCODED_IMAGE>",
"mimeType": "image/png"
}
}
]
}'import { readFileSync } from 'fs'
const imageBase64 = readFileSync('reference.png').toString('base64')
const response = await fetch(
'https://api.marswave.ai/openapi/v1/images/generation',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
provider: 'google',
model: 'gemini-3-pro-image',
prompt: 'Create a cartoon version of this portrait',
referenceImages: [
{
inlineData: {
data: imageBase64,
mimeType: 'image/png',
},
},
],
}),
},
)
const data = await response.json()import os
import base64
import requests
with open('reference.png', 'rb') as f:
image_base64 = base64.b64encode(f.read()).decode('utf-8')
response = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'provider': 'google',
'model': 'gemini-3-pro-image',
'prompt': 'Create a cartoon version of this portrait',
'referenceImages': [
{
'inlineData': {
'data': image_base64,
'mimeType': 'image/png',
}
}
],
},
)
data = response.json()请求参数
以下参数适用于 POST /v1/images/generation、POST /v1/images/generation/async 和
POST /v1/images/generation/estimate-credits —— 这三个端点共用同一套请求 schema。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
provider | string | 是¹ | 模型厂商:google、openai 或 bytedance |
model | string | 否 | 模型名。默认 gpt-image-2。详见 厂商与模型矩阵 |
prompt | string | 是² | 待生成图片的文本描述 |
referenceImages | array | 否 | 用于引导生成的参考图。详见 参考图限制 |
referenceImages[].fileData | object | 否 | 以 URL 形式提供的参考图 |
referenceImages[].fileData.fileUri | string | 是 | 图片 URL —— scheme 必须为 http、https 或 gs |
referenceImages[].fileData.mimeType | string | 是 | MIME 类型:image/png、image/jpeg、image/webp、image/heic 或 image/heif |
referenceImages[].inlineData | object | 否 | 以 base64 编码数据形式提供的参考图 |
referenceImages[].inlineData.data | string | 是 | base64 编码的图片数据 |
referenceImages[].inlineData.mimeType | string | 是 | MIME 类型:image/png、image/jpeg、image/webp、image/heic 或 image/heif |
imageConfig | object | 否 | 图片输出配置。默认 { "imageSize": "2K" } |
imageConfig.imageSize | string | 否 | 输出分辨率:1K、2K(默认)或 4K |
imageConfig.aspectRatio | string | 否 | 宽高比。默认 1:1。详见 宽高比 |
imageConfig.quality | string | 否 | 渲染质量:low、medium 或 high。作用于 GPT-Image-2;省略则由模型自行决定 |
¹ provider 在两个生成端点上必填,在 estimate-credits 上可选。
² prompt 在两个生成端点上必填;在 estimate-credits 上可为空或省略(它只影响输入 token 预估)。
referenceImages 中的每一项必须只包含 fileData 或 inlineData 之一,不能同时存在。
厂商与模型矩阵
provider 选择厂商,model 选择具体模型。默认模型为 gpt-image-2。
provider | model | 说明 |
|---|---|---|
google | gemini-3-pro-image | 质量更高、细节更丰富。NanoBanana Pro |
google | gemini-3.1-flash-image | 生成更快。额外支持 1:4 / 4:1 / 1:8 / 8:1 比例 |
openai | gpt-image-2 | 提示词遵循能力强。最多 4 张参考图。aspectRatio 可选 |
bytedance | seedream-5-0-pro | 支持精准编辑(坐标 / 色号写进 prompt)。最多 10 张参考图。仅 1K / 2K |
旧版 preview 模型 ID gemini-3-pro-image-preview 和 gemini-3.1-flash-image-preview 作为入参
仍被接受,并会归一化为上面对应的 GA ID。新接入请直接发送 GA ID。
宽高比
imageConfig.aspectRatio 默认为 1:1。schema 接受以下比例:
| 比例 | 说明 |
|---|---|
1:1 | 正方形 |
2:3 | 竖向 |
3:2 | 横向 |
3:4 | 竖向 |
4:3 | 横向 |
9:16 | 竖屏 / 移动端 |
16:9 | 宽屏 |
21:9 | 超宽屏 |
1:4 | 仅 Flash |
4:1 | 仅 Flash |
1:8 | 仅 Flash |
8:1 | 仅 Flash |
1:4、4:1、1:8 和 8:1 仅 gemini-3.1-flash-image 与 seedream-5-0-pro 接受。GPT-Image-2 支持八种标准比例
(1:1、2:3、3:2、3:4、4:3、9:16、16:9、21:9),并允许省略 aspectRatio 让模型
自动选择。所选模型不支持的比例会返回 400。
图片尺寸
imageConfig.imageSize 接受 1K、2K(默认)和 4K。尺寸越大消耗的积分越多;对于
GPT-Image-2,4K(以及 high 质量)需要有效的付费订阅。Seedream 5.0 Pro 只支持 1K 和
2K,传 4K 返回 400。请勿写死积分成本 —— 调用
预估积分 获取精确数值。
参考图限制
| 模型 | 参考图上限 |
|---|---|
gemini-3-pro-image | 14 |
gemini-3.1-flash-image | 14 |
gpt-image-2 | 4 |
seedream-5-0-pro | 10 |
schema 将 referenceImages 总数限制为 14 项。GPT-Image-2 有更严格的 4 张上限、Seedream 5.0 Pro 为 10 张 —— 超出返回 400。
fileData 和 inlineData 接受的 MIME 类型均为 image/png、image/jpeg、image/webp、
image/heic 和 image/heif。
Seedream 5.0 Pro 精准编辑
Seedream 5.0 Pro 支持精准编辑:指定图中某块区域改成什么,而不是整图重新生成。
没有独立的编辑端点,也没有 mask 或 region 参数 —— 编辑就是同一个生成端点,把源图放进
referenceImages,把「改哪、改成什么」写进 prompt。模型能直接识别以图片左上角为原点的
绝对像素坐标,以及行业色号。
{
"provider": "bytedance",
"model": "seedream-5-0-pro",
"prompt": "左上角为绝对坐标的原点,把左上:(376,363) 右下:(701,638) 区域内的内容改成绿色,其余区域保持不变",
"referenceImages": [
{
"fileData": {
"fileUri": "https://assets.listenhub.ai/your-source-image.png",
"mimeType": "image/png"
}
}
],
"imageConfig": { "imageSize": "2K", "aspectRatio": "1:1" }
}如果你的产品有框选、圈选、箭头等可视化编辑手势,需要在自己的前端把手势转换成坐标串
(或把标注烧进参考图)后再写进 prompt —— 服务端只做原样透传,不解析坐标。
编辑时建议让 aspectRatio 与源图真实比例一致,比例不符时模型可能整图重构而非局部修改。
预估积分
POST /v1/images/generation/estimate-credits
返回给定配置的积分成本以及账户是否可生成,不消耗积分、不调用模型。用它在确认前展示价格,或检查
4K / high 请求是否需要订阅。请求体与生成端点相同;此处 provider 和 prompt 可选。
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation/estimate-credits" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"imageConfig": {
"imageSize": "2K",
"aspectRatio": "1:1",
"quality": "medium"
}
}'const response = await fetch(
'https://api.marswave.ai/openapi/v1/images/generation/estimate-credits',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'gpt-image-2',
imageConfig: { imageSize: '2K', aspectRatio: '1:1', quality: 'medium' },
}),
},
)
const { data } = await response.json()
console.log(data.credits, data.canGenerate)import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation/estimate-credits',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'model': 'gpt-image-2',
'imageConfig': {'imageSize': '2K', 'aspectRatio': '1:1', 'quality': 'medium'},
},
)
data = response.json()['data']
print(data['credits'], data['canGenerate'])预估响应
包裹在标准信封中。data 对象:
| 字段 | 类型 | 说明 |
|---|---|---|
model | string | 用于预估的归一化 GA 模型 ID |
imageSize | string | 解析出的输出尺寸 |
aspectRatio | string | 解析出的宽高比(模型自动选择时不返回) |
quality | string | 解析出的质量(不适用时不返回) |
pixels | object | 解析成功时为 { "width": number, "height": number, "size": "WxH" } |
credits | number | 该配置将消耗的积分 |
canGenerate | boolean | 账户有效积分余额是否足够 |
requiresSubscription | boolean | 该配置需要有效付费计划(如 4K、high)时为 true |
pricing | object | 定价元数据:pricingVersion、mode(token-estimate/fixed) |
warnings | array | 提示性字符串,如 reference_image_input_tokens_not_included |
{
"code": 0,
"message": "",
"data": {
"model": "gpt-image-2",
"imageSize": "2K",
"aspectRatio": "1:1",
"quality": "medium",
"pixels": { "width": 2048, "height": 2048, "size": "2048x2048" },
"credits": 6,
"canGenerate": true,
"requiresSubscription": false,
"pricing": { "pricingVersion": "...", "mode": "token-estimate" },
"warnings": []
}
}异步生成
对于耗时较长或高分辨率的任务,提交任务后轮询结果,而不是长时间占用一个请求连接。
创建异步任务
POST /v1/images/generation/async
请求体与同步端点相同。立即返回 202 和一个 taskId;生成在后台运行,生成结果以托管 URL 形式
持久化保存。
curl -X POST "https://api.marswave.ai/openapi/v1/images/generation/async" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"provider": "google",
"model": "gemini-3-pro-image",
"prompt": "An astronaut riding a horse on Mars, photorealistic",
"imageConfig": { "imageSize": "4K", "aspectRatio": "16:9" }
}'const res = await fetch(
'https://api.marswave.ai/openapi/v1/images/generation/async',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
provider: 'google',
model: 'gemini-3-pro-image',
prompt: 'An astronaut riding a horse on Mars, photorealistic',
imageConfig: { imageSize: '4K', aspectRatio: '16:9' },
}),
},
)
const { data } = await res.json()
const taskId = data.taskIdimport os
import requests
res = requests.post(
'https://api.marswave.ai/openapi/v1/images/generation/async',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'provider': 'google',
'model': 'gemini-3-pro-image',
'prompt': 'An astronaut riding a horse on Mars, photorealistic',
'imageConfig': {'imageSize': '4K', 'aspectRatio': '16:9'},
},
)
task_id = res.json()['data']['taskId']响应(202):
{
"code": 0,
"message": "",
"data": { "taskId": "65f0...", "status": "pending" }
}获取单个任务
GET /v1/images/generation/tasks/{taskId}
轮询单个任务的状态和结果。status 取值为 pending、generating、success 或 fail。成功时
images 中是托管的结果 URL。
curl "https://api.marswave.ai/openapi/v1/images/generation/tasks/65f0abc..." \
-H "Authorization: Bearer $LISTENHUB_API_KEY"{
"code": 0,
"message": "",
"data": {
"taskId": "65f0abc...",
"status": "success",
"images": [
{ "url": "https://.../0.png", "mimeType": "image/png" }
],
"createdAt": 1750000000000,
"completedAt": 1750000020000
}
}| 字段 | 类型 | 说明 |
|---|---|---|
taskId | string | 任务标识 |
status | string | pending、generating、success 或 fail |
images | array | 成功时返回;每项为 { url, mimeType } |
failMsg | string | status 为 fail 时的失败信息 |
createdAt | number | 创建时间(epoch 毫秒) |
completedAt | number | 完成时间(epoch 毫秒),完成后返回 |
列出任务
GET /v1/images/generation/tasks
列出你的图片任务,按时间倒序。
| 查询参数 | 类型 | 默认 | 说明 |
|---|---|---|---|
page | number | 1 | 页码,最小 1 |
pageSize | number | 20 | 每页条数,1–100 |
status | string | — | 按 pending、generating、success 或 fail 过滤 |
curl "https://api.marswave.ai/openapi/v1/images/generation/tasks?page=1&pageSize=20&status=success" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"{
"code": 0,
"message": "",
"data": {
"items": [
{ "taskId": "65f0...", "status": "success", "images": [/* ... */], "createdAt": 1750000000000, "completedAt": 1750000020000 }
],
"page": 1,
"pageSize": 20,
"total": 1
}
}后台任务若停留在 pending 或 generating 超过 30 分钟,会被扫描置为 fail 并附带超时
failMsg。对超过该时长仍处于非终态的任务,按失败处理并重试。
响应格式
| 端点 | 是否包裹信封? | 响应体 |
|---|---|---|
POST /v1/images/generation | 否 —— 模型原始 JSON | base64 图片数据(见下) |
POST /v1/images/generation/async | 是 | { taskId, status } |
POST /v1/images/generation/estimate-credits | 是 | 预估对象 |
GET /v1/images/generation/tasks | 是 | 分页 { items, page, pageSize, total } |
GET /v1/images/generation/tasks/{taskId} | 是 | 任务对象 |
同步端点直接返回模型原始输出(不包裹)。成功的响应体以 base64 数据包含生成的图片:
{
"candidates": [
{
"content": {
"parts": [
{
"inlineData": {
"mimeType": "image/png",
"data": "<BASE64_ENCODED_IMAGE>"
}
}
]
}
}
]
}将 data 字段从 base64 解码即可得到图片文件。异步路径会替你持久化图片,并在任务对象上返回
托管 url —— 无需做 base64 解码。
NanoBanana Pro 免费额度
API key 调用与 web、Labnana 应用共享同一个账户级免费额度(freeUsages)余额。你可以持续通过
注册、邀请和签到赚取额度,再通过 API 消费。通过
GET /v1/user/subscription 查询实时余额,读取其
freeUsages 映射。
当匹配的余额大于 0 时,一次 1K / 2K 请求会消费一次免费生成而非积分。余额降到 0 后,同一
请求会回退到正常积分计费。
免费额度仅适用于 1K 和 2K 尺寸。4K 请求永远不会动用 freeUsages,始终按积分计费。
一次 NanoBanana Pro relax 调用如何运行取决于你的账户类型:
- 付费或已充值账户(活跃订阅、充值或积分包购买)即使在消费免费额度时也享有正常付费生成体验 —— 完整优先级、正常容量、正常回退。免费额度只改变计费,不会把你放进受限通道。
- 纯免费账户(从未付费)在最低优先级免费通道上运行 NanoBanana Pro relax,有固定吞吐上限。 高峰期请求可能排队或被拒绝并返回可重试的 busy/timeout 响应。此时不消耗积分、不消耗免费额度 —— 稍后重试即可(深夜更快)。
纯免费 relax 失败会返回机读元数据,让你无需解析本地化文本即可识别:
failReason为free_relax_busy或free_relax_timeout。retryable为true。- 免费额度退回后
freeUsageRolledBack为true。 userMessage携带友好、可本地化的文案。
同步请求中它出现在错误响应体里;异步请求中它出现在失败的任务详情里(以及任务列表里)。两种原因都 应视为「稍后重试,未扣任何费用」。
限流与参考图模式
标准文生图请求受按用户和全局的限流约束。
参考图模式(带 inlineData 的 referenceImages)受额外的服务端资源约束。高峰期 base64
请求可能被更激进地限流。遇到 429 时,读取 Retry-After 头并退避后重试。请在客户端实现指数
退避。
错误码
错误使用标准信封(code 非零);对同步端点,则使用
NanoBanana Pro 免费额度 中记录的原始错误体。
| HTTP 状态 | 含义 |
|---|---|
400 | 请求参数无效(如所选模型不支持的宽高比) |
402 | 积分不足 |
429 | 限流或服务繁忙 —— 读取 Retry-After 后重试 |
500 | 图片生成失败 —— 重试请求 |