04快速上手
Gemini API 格式的请求新
Nano Banana 系列模型接受 Google Gemini API 格式的请求:路由相同、请求体相同、响应的形式也相同。只需更换地址和密钥。
这是什么,有哪些路由
这是 Nano Banana 系列模型的一条独立路径。它在主机 https:// 的根路径上接受 Google Gemini API 格式的请求,并把请求交给与常规 API(/api/)相同的受理环节:校验、价格、限额和余额都与常规 API 相同。
| 路由 | 作用 |
|---|---|
POST /v1beta/ | 生成图片并返回一个响应。推荐使用的路由。 |
POST /v1beta/ | 同上,但以流式响应返回。带 ?alt=sse 时收到 SSE 事件;不带时收到 Google 的 JSON 数组,其中只有一个响应。 |
GET /v1beta/ | 你的密钥可以调用的模型列表。 |
GET /v1beta/ | 单个模型。 |
/v1 下只有两条 POST 路由可用:POST /v1/ 和 POST /v1/。/v1 下的其他路径都按未知路径应答。
密钥
Rendergrid 密钥有三种传递方式:放在 x-goog-api-key 请求头中,放在 Authorization: Bearer 请求头中,或放在地址参数 ?key= 中。服务器按此顺序取第一个非空的。密钥不会进入我们的日志。
已撤销、已过期、已停用或已被封禁的密钥,其表现与常规 API 相同:参见“密钥与鉴权”。
示例
示例中的密钥从环境变量 RENDERGRID_API_KEY 读取。图片以 base64 形式放在响应的 inlineData.data 字段中。
Python 和 Node.js 使用 Google 的 Gen AI SDK:pip install google-genai 和 npm install @google/genai。创建客户端时使用我们的地址 https:// 和你的 Rendergrid 密钥。Node.js 示例是 ES 模块(.mjs 文件):其中的 await 位于顶层。
单个响应 — generateContent:
curl --fail-with-body --max-time 620 \ -X POST "https://api.rendergrid.io/ v1beta/ models/ gemini-3-pro-image:generateContent" \ -H "x-goog-api-key: $RENDERGRID_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contents": [{"parts": [{"text": "A ceramic mug on marble, soft window light"}]}], "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"} } }' \ -o response.json
import os from google import genai from google.genai import types client = genai.Client( api_key=os.environ["RENDERGRID_API_KEY"], http_options=types.HttpOptions( base_url="https://api.rendergrid.io", timeout=620_000, ), ) response = client.models.generate_content( model="gemini-3-pro-image", contents="A ceramic mug on marble, soft window light", config=types.GenerateContentConfig( response_modalities=["IMAGE"], image_config=types.ImageConfig(aspect_ratio="1:1", image_size="1K"), ), ) for part in response.parts: if part.inline_data: extension = part.inline_data.mime_type.removeprefix("image/") with open("result." + extension, "wb") as file: file.write(part.inline_data.data)
import { writeFileSync } from "node:fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({ apiKey: process.env.RENDERGRID_API_KEY, httpOptions: { baseUrl: "https://api.rendergrid.io", timeout: 620_000 }, }); const response = await ai.models.generateContent({ model: "gemini-3-pro-image", contents: "A ceramic mug on marble, soft window light", config: { responseModalities: ["IMAGE"], imageConfig: { aspectRatio: "1:1", imageSize: "1K" }, }, }); for (const part of response.candidates[0].content.parts) { if (part.inlineData) { const extension = part.inlineData.mimeType.replace("image/", ""); writeFileSync(`result.${extension}`, Buffer.from(part.inlineData.data, "base64")); } }
对于耗时较长的生成,Python 中我们推荐使用不带流的 generate_content。
流式响应 — 带 alt=sse 参数的 streamGenerateContent(curl 和 Node.js):
curl --fail-with-body --no-buffer --max-time 620 \ -X POST "https://api.rendergrid.io/ v1beta/ models/ gemini-3-pro-image:streamGenerateContent?alt=sse" \ -H "x-goog-api-key: $RENDERGRID_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "contents": [{"parts": [{"text": "A ceramic mug on marble, soft window light"}]}], "generationConfig": { "responseModalities": ["IMAGE"], "imageConfig": {"aspectRatio": "1:1", "imageSize": "1K"} } }'
import { writeFileSync } from "node:fs"; import { GoogleGenAI } from "@google/genai"; const ai = new GoogleGenAI({ apiKey: process.env.RENDERGRID_API_KEY, httpOptions: { baseUrl: "https://api.rendergrid.io", timeout: 620_000 }, }); const stream = await ai.models.generateContentStream({ model: "gemini-3-pro-image", contents: "A ceramic mug on marble, soft window light", config: { responseModalities: ["IMAGE"], imageConfig: { aspectRatio: "1:1", imageSize: "1K" }, }, }); for await (const chunk of stream) { for (const part of chunk.candidates?.[0]?.content?.parts ?? []) { if (part.inlineData) { const extension = part.inlineData.mimeType.replace("image/", ""); writeFileSync(`result.${extension}`, Buffer.from(part.inlineData.data, "base64")); } } }
示例中的客户端超时为 620 秒,依据“等待响应”一节的规则。
其余路由。模型列表和单个模型:
curl --fail-with-body --max-time 30 \ "https://api.rendergrid.io/ v1beta/ models" \ -H "x-goog-api-key: $RENDERGRID_API_KEY"
curl --fail-with-body --max-time 30 \ "https://api.rendergrid.io/ v1beta/ models/ gemini-3-pro-image" \ -H "x-goog-api-key: $RENDERGRID_API_KEY"
在 /v1 下,请求体放在文件 request.json 中:它就是第一个示例中的请求体。
curl --fail-with-body --max-time 620 \ -X POST "https://api.rendergrid.io/ v1/ models/ gemini-3-pro-image:generateContent" \ -H "x-goog-api-key: $RENDERGRID_API_KEY" \ -H "Content-Type: application/json" \ -d @request.json \ -o response.json
curl --fail-with-body --no-buffer --max-time 620 \ -X POST "https://api.rendergrid.io/ v1/ models/ gemini-3-pro-image:streamGenerateContent?alt=sse" \ -H "x-goog-api-key: $RENDERGRID_API_KEY" \ -H "Content-Type: application/json" \ -d @request.json
模型
可以调用表中的标识符。Google 的标识符和我们的标识符指向同一个 Rendergrid 模型;价格和余额与常规 API 中该模型相同。
| 请求中的标识符 | Rendergrid 模型 |
|---|---|
gemini-3-pro-image | nano-banana-pro |
gemini-3.1-flash-image | nano-banana-2 |
gemini-2.5-flash-image | nano-banana-flash |
gemini-3-pro-image-preview | nano-banana-pro |
gemini-3.1-flash-image-preview | nano-banana-2 |
nano-banana-pro | nano-banana-pro |
nano-banana-2 | nano-banana-2 |
nano-banana-2.1 | nano-banana-2.1 |
nano-banana-flash | nano-banana-flash |
nano-banana-2-lite | nano-banana-2-lite |
GET /v1beta/ 只显示你的密钥可以调用的内容:先是 Google 的标识符,然后是我们的。带 -preview 的变体会被接受,但不在列表中。
如果账号没有该模型的权限,响应为 403。未知的或未开放的模型为 404。这条路径上没有其他模型:GPT 模型返回 404。
请求
请求体就是 Google generateContent 的请求体。其中被采纳的内容:
- 内容部分(part)。 一个 part 可以是
text、inlineData(mimeType和 base64 编码的data),或fileData(fileUri,以及可选的mimeType)。fileUri地址只能是 http 或 https;检查方式与常规 API 中参考图地址的检查方式相同(参见“参考图”)。 - 提示词文本。 即最后一轮用户消息中的文本 part,以换行符连接;
systemInstruction的文本排在它们前面,中间隔一个空行。 - 参考图。 参考图是所有轮次中的全部图片,用户的和模型的都算,按顺序排列。内嵌图片只能是 PNG、JPEG 和 WebP;每张只上传一次,之后以链接传递,与任何上传一样。内嵌图片和
fileUri不能在同一个请求中一起发送:响应为400。 - 画幅。
generationConfig.imageConfig.aspectRatio。允许的取值与常规 API 的aspect_ratio相同(参见“模型与参数”)。不传时:请求中有参考图则为auto,没有则为1:1;nano-banana-2-lite没有auto模式,画幅为1:1。 - 尺寸。
generationConfig.imageConfig.imageSize:1K、2K或4K。不传时为1K,而不是常规 API 中的2K。模型没有的尺寸(参见“响应”一节中的表)会被常规受理环节拒绝:400。 - 文件格式。
generationConfig.imageConfig.imageOutputOptions.mimeType:image/png或image/jpeg。不传时文件按模型自身的格式返回,不做重新编码。其他取值为400。 - 候选与模态。
responseModalities必须包含IMAGE(只有TEXT为400);candidateCount只能是 1。
{
"contents": [
{
"role": "user",
"parts": [
{ "text": "Put this mug on a marble table, soft window light" },
{ "fileData": { "mimeType": "image/png", "fileUri": "https:// example.com/ mug.png" } }
]
}
],
"generationConfig": {
"responseModalities": ["IMAGE"],
"imageConfig": { "aspectRatio": "4:5", "imageSize": "2K" }
}
}以下字段会被接受并忽略:tools、safetySettings、thinkingConfig、temperature、topP、topK、seed、thoughtSignature、cachedContent、labels。它们不影响结果,也不会引发错误。
限制。提示词文本最多 20,000 个字符;参考图最多 14 张;内嵌图片解码后最多 25 MiB,与上传文件相同(参见“参考图”);请求体最多 64 MiB。超出时为 400 INVALID_ARGUMENT,请求体超出时为 413 INVALID_ARGUMENT。这么大的请求体可能在受理之前就被入口服务器拦下:此时响应是入口服务器自己的页面,而不是 Google 格式的信封。
响应
成功的响应是 Google 的 GenerateContentResponse:图片位于 candidates[0].content.parts[0].inlineData,finishReason 为 STOP。图片类型 mimeType 由文件本身的字节判定。
{
"candidates": [
{
"content": {
"role": "model",
"parts": [{ "inlineData": { "mimeType": "image/png", "data": "iVBORw0KGgo…" } }]
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 11,
"candidatesTokenCount": 1120,
"totalTokenCount": 1131,
"candidatesTokensDetails": [{ "modality": "IMAGE", "tokenCount": 1120 }]
},
"modelVersion": "gemini-3-pro-image",
"responseId": "5b0214ae-9e39-460a-820a-f6ae3e24400b"
}modelVersion 是你请求中的模型标识符,如果你写了带 -preview 的标识符,这里保持不变。responseId 是请求 id,与 x-rendergrid-request-id 请求头中的相同。如果受理环节没能在 90 秒内应答,200 响应在 id 产生之前就已发出,则没有该请求头,id 只出现在 responseId 中。
usageMetadata:promptTokenCount 是估算值,不是模型的 token 计数:请求的字符数除以 4,向上取整。candidatesTokenCount 和 totalTokenCount 按下表计算;candidatesTokensDetails 带有相同的图片 token。Gemini 客户端用这些 token 做自己的统计,请求的价格与它们无关。表中的破折号表示该模型没有这个尺寸。
| 模型 | 1K | 2K | 4K |
|---|---|---|---|
nano-banana-pro | 1120 | 1120 | 2000 |
nano-banana-2 | 1120 | 1680 | 2520 |
nano-banana-2.1 | 1120 | 1680 | 2520 |
nano-banana-flash | 1290 | — | — |
nano-banana-2-lite | 1120 | — | — |
等待响应
图片不是瞬间生成的,连接需要保持打开。各项时限:
| 项目 | 数值 |
|---|---|
| 服务器在发出第一个字节前保持沉默 | 90 秒 |
| 此后的“仍在处理”信号 | 每 15 秒一次 |
| 等待上限 | 自请求被受理起 600 秒 |
- 最初 90 秒内服务器不发送任何内容:更早准备好的响应带着自己的 HTTP 状态码到达,错误也一样。
- 如果到第 90 秒还没有图片,服务器会回复
200,并每 15 秒发送一次 keep-alive — 表示请求仍在处理 — 之后才是响应。 - 在这样的
200之后,错误在响应体中到达:以 Google 错误对象的形式;在 SSE 中则是一个data:事件。 - 上限是自请求被受理起 600 秒:到时响应体中会出现带有文本
Generation timed out.的504 DEADLINE_EXCEEDED,并退还该金额。这条路径从不以 HTTP 502 或 504 应答;在200之前因超时而中断的生成,应答为503 UNAVAILABLE。 - 请在客户端把读取超时设为大于 90 秒,总超时设为不少于 610 秒:服务器的上限是 600 秒,达到上限时的错误响应需要来得及送达。被客户端中断的请求仍会计费。
费用
- 金额在受理请求时、开始处理之前扣除 — 与向 API 发出的同样请求相同,价格也相同。
- 图片一经生成即计费 — 与 Google 相同。
- 如果连接在你这一侧中断 — 无论是请求等待期间还是响应传送期间 — 扣费保留:图片会生成完毕,可通过请求 id(
GET /api/)和账号历史获取。public/ v1/ creations/ {id} - 如果因我们的原因没有送达图片 — 600 秒上限已到、响应在我们这一侧中断,或服务器正在停止 — 金额会自动退回余额,且只退一次。
- 失败的请求和审核拒绝不收费,与常规 API 相同:金额退回余额。
- 重复请求是新的请求,会产生新的扣费:这条路径没有幂等键。
- 如果余额不足,响应为
429 RESOURCE_EXHAUSTED(常规 API 中为402)。
错误
错误以 Google 的信封格式返回:error.code、error.message 和 error.status。
{
"error": {
"code": 404,
"message": "The requested model was not found.",
"status": "NOT_FOUND"
}
}| HTTP 状态码 | Google 状态 | 何时出现 |
|---|---|---|
400 | INVALID_ARGUMENT | 请求体、字段或参考图未通过校验(参见“请求”),或常规受理环节拒绝了该请求。 |
401 | UNAUTHENTICATED | 没有密钥或密钥无效;文本与常规 API 相同。 |
403 | PERMISSION_DENIED | 账号被封禁、密钥没有该模型的权限,或该路径对账号关闭。 |
404 | NOT_FOUND | 未知的模型或路径;这条路径上没有 GPT 模型。 |
413 | INVALID_ARGUMENT | 请求体超过 64 MiB。 |
429 | RESOURCE_EXHAUSTED | 触及频率限额、进行中任务数的限额、因访问错误被封禁,或余额不足;响应文本会说明具体是哪一种。重试前的等待时间在 Retry-After 请求头中。 |
500 | INTERNAL | 内部错误或生成失败;失败的费用会退还。 |
503 | UNAVAILABLE | 服务暂时不可用,生成没能在 200 响应之前按时完成,或内嵌图片没来得及上传。最后一种情况下会收到 Retry-After: 5,并且不扣费。 |
504 | DEADLINE_EXCEEDED | 仅出现在响应体中:在 200 之后,达到 600 秒上限时。金额会退还。 |
这条路径不会以 HTTP 状态码的形式发送 502 和 504。600 秒的上限以 504 的形式出现在已经以 200 开始的响应体内:
{
"error": {
"code": 504,
"message": "Generation timed out.",
"status": "DEADLINE_EXCEEDED"
}
}受理环节自己给出的错误文本(401、429、校验拒绝)与常规 API 相同:参见“错误码”。
审核拒绝
审核拒绝以 200 返回,与 Google 相同:
finishReason: "IMAGE_SAFETY"且没有任何 part — 模型因结果而拒绝;promptFeedback.blockReason: "SAFETY"— 因请求或参考图而拒绝;finishReason: "NO_IMAGE"— 没有图片。
{
"candidates": [{ "finishReason": "IMAGE_SAFETY", "index": 0 }],
"usageMetadata": { "promptTokenCount": 11, "totalTokenCount": 11 },
"modelVersion": "gemini-3-pro-image",
"responseId": "5b0214ae-9e39-460a-820a-f6ae3e24400b"
}这类响应不收费,与常规 API 相同:金额退回余额。
限额
适用常规 API 的限额:请求频率、突发保护和进行中的任务数(参见“限额”)。每张内嵌图片都是一次单独的上传:占用一个频率单位和一个上传限额单位。任务数限额中的名额在生成进行期间被占用,而不是在连接保持打开期间。