ListenHubOpenAPI
API 参考

图片生成

通过文本提示词和参考图生成 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"。请求和响应格式 相同 —— 只有 providermodelimageConfig 不同。详见 厂商与模型矩阵

携带参考图生成

提供参考图以引导输出。每张参考图要么是 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/generationPOST /v1/images/generation/asyncPOST /v1/images/generation/estimate-credits —— 这三个端点共用同一套请求 schema。

字段类型必填说明
providerstring是¹模型厂商:googleopenaibytedance
modelstring模型名。默认 gpt-image-2。详见 厂商与模型矩阵
promptstring是²待生成图片的文本描述
referenceImagesarray用于引导生成的参考图。详见 参考图限制
referenceImages[].fileDataobject以 URL 形式提供的参考图
referenceImages[].fileData.fileUristring图片 URL —— scheme 必须为 httphttpsgs
referenceImages[].fileData.mimeTypestringMIME 类型:image/pngimage/jpegimage/webpimage/heicimage/heif
referenceImages[].inlineDataobject以 base64 编码数据形式提供的参考图
referenceImages[].inlineData.datastringbase64 编码的图片数据
referenceImages[].inlineData.mimeTypestringMIME 类型:image/pngimage/jpegimage/webpimage/heicimage/heif
imageConfigobject图片输出配置。默认 { "imageSize": "2K" }
imageConfig.imageSizestring输出分辨率:1K2K(默认)或 4K
imageConfig.aspectRatiostring宽高比。默认 1:1。详见 宽高比
imageConfig.qualitystring渲染质量:lowmediumhigh。作用于 GPT-Image-2;省略则由模型自行决定

¹ provider 在两个生成端点上必填,在 estimate-credits 上可选。 ² prompt 在两个生成端点上必填;在 estimate-credits 上可为空或省略(它只影响输入 token 预估)。

referenceImages 中的每一项必须只包含 fileDatainlineData 之一,不能同时存在。

厂商与模型矩阵

provider 选择厂商,model 选择具体模型。默认模型为 gpt-image-2

providermodel说明
googlegemini-3-pro-image质量更高、细节更丰富。NanoBanana Pro
googlegemini-3.1-flash-image生成更快。额外支持 1:4 / 4:1 / 1:8 / 8:1 比例
openaigpt-image-2提示词遵循能力强。最多 4 张参考图。aspectRatio 可选
bytedanceseedream-5-0-pro支持精准编辑(坐标 / 色号写进 prompt)。最多 10 张参考图。仅 1K / 2K

旧版 preview 模型 ID gemini-3-pro-image-previewgemini-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:44:11:88:1gemini-3.1-flash-imageseedream-5-0-pro 接受。GPT-Image-2 支持八种标准比例 (1:12:33:23:44:39:1616:921:9),并允许省略 aspectRatio 让模型 自动选择。所选模型不支持的比例会返回 400

图片尺寸

imageConfig.imageSize 接受 1K2K(默认)和 4K。尺寸越大消耗的积分越多;对于 GPT-Image-2,4K(以及 high 质量)需要有效的付费订阅。Seedream 5.0 Pro 只支持 1K2K,传 4K 返回 400。请勿写死积分成本 —— 调用 预估积分 获取精确数值。

参考图限制

模型参考图上限
gemini-3-pro-image14
gemini-3.1-flash-image14
gpt-image-24
seedream-5-0-pro10

schema 将 referenceImages 总数限制为 14 项。GPT-Image-2 有更严格的 4 张上限、Seedream 5.0 Pro 为 10 张 —— 超出返回 400fileDatainlineData 接受的 MIME 类型均为 image/pngimage/jpegimage/webpimage/heicimage/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 请求是否需要订阅。请求体与生成端点相同;此处 providerprompt 可选。

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 对象:

字段类型说明
modelstring用于预估的归一化 GA 模型 ID
imageSizestring解析出的输出尺寸
aspectRatiostring解析出的宽高比(模型自动选择时不返回)
qualitystring解析出的质量(不适用时不返回)
pixelsobject解析成功时为 { "width": number, "height": number, "size": "WxH" }
creditsnumber该配置将消耗的积分
canGenerateboolean账户有效积分余额是否足够
requiresSubscriptionboolean该配置需要有效付费计划(如 4Khigh)时为 true
pricingobject定价元数据:pricingVersionmodetoken-estimate/fixed
warningsarray提示性字符串,如 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.taskId
import 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 取值为 pendinggeneratingsuccessfail。成功时 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
  }
}
字段类型说明
taskIdstring任务标识
statusstringpendinggeneratingsuccessfail
imagesarray成功时返回;每项为 { url, mimeType }
failMsgstringstatusfail 时的失败信息
createdAtnumber创建时间(epoch 毫秒)
completedAtnumber完成时间(epoch 毫秒),完成后返回

列出任务

GET /v1/images/generation/tasks

列出你的图片任务,按时间倒序。

查询参数类型默认说明
pagenumber1页码,最小 1
pageSizenumber20每页条数,1100
statusstringpendinggeneratingsuccessfail 过滤
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
  }
}

后台任务若停留在 pendinggenerating 超过 30 分钟,会被扫描置为 fail 并附带超时 failMsg。对超过该时长仍处于非终态的任务,按失败处理并重试。

响应格式

端点是否包裹信封?响应体
POST /v1/images/generation否 —— 模型原始 JSONbase64 图片数据(见下)
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 后,同一 请求会回退到正常积分计费。

免费额度仅适用于 1K2K 尺寸。4K 请求永远不会动用 freeUsages,始终按积分计费。

一次 NanoBanana Pro relax 调用如何运行取决于你的账户类型:

  • 付费或已充值账户(活跃订阅、充值或积分包购买)即使在消费免费额度时也享有正常付费生成体验 —— 完整优先级、正常容量、正常回退。免费额度只改变计费,不会把你放进受限通道。
  • 纯免费账户(从未付费)在最低优先级免费通道上运行 NanoBanana Pro relax,有固定吞吐上限。 高峰期请求可能排队或被拒绝并返回可重试的 busy/timeout 响应。此时不消耗积分、不消耗免费额度 —— 稍后重试即可(深夜更快)。

纯免费 relax 失败会返回机读元数据,让你无需解析本地化文本即可识别:

  • failReasonfree_relax_busyfree_relax_timeout
  • retryabletrue
  • 免费额度退回后 freeUsageRolledBacktrue
  • userMessage 携带友好、可本地化的文案。

同步请求中它出现在错误响应体里;异步请求中它出现在失败的任务详情里(以及任务列表里)。两种原因都 应视为「稍后重试,未扣任何费用」。

限流与参考图模式

标准文生图请求受按用户和全局的限流约束。

参考图模式(带 inlineDatareferenceImages)受额外的服务端资源约束。高峰期 base64 请求可能被更激进地限流。遇到 429 时,读取 Retry-After 头并退避后重试。请在客户端实现指数 退避。

错误码

错误使用标准信封(code 非零);对同步端点,则使用 NanoBanana Pro 免费额度 中记录的原始错误体。

HTTP 状态含义
400请求参数无效(如所选模型不支持的宽高比)
402积分不足
429限流或服务繁忙 —— 读取 Retry-After 后重试
500图片生成失败 —— 重试请求

相关

本页内容