要点
通过 API 生成第一张图片分三步:创建 API 密钥,向 /api/public/v1/images/generate 发送一次 POST 请求,再用返回的 id 查询任务状态,直到状态变为 completed;图片链接在 result_urls 字段里。下文给出 curl、Python 和 JavaScript 示例。标题里的“五分钟”,指的是从一个已有余额和 API 密钥的账号开始,照着这些步骤走到第一张图片完成所用的时间。注册和充值不算在内,它也不是生成一张图片的耗时,更不是对时限的承诺。
发送第一个请求前 需要准备什么?
你需要一个 Rendergrid 账号、账号里的余额和一个 API 密钥。顺序是:先创建 API 密钥,再给余额充值(在控制台的“余额与充值”页面中充值,或通过经理充值),最后发送请求。
API 密钥。 在控制台里创建 API 密钥。可用的密钥以 rg_live_ 开头,完整的密钥只在创建时显示一次,所以请立即保存。丢失的密钥无法找回,需要创建新的密钥。详细说明见密钥与鉴权。
余额。 余额以美元计,用 USDT 充值:在控制台的“余额与充值”页面中充值,或通过经理充值。可以先小额充值,因为每张图片都按它的价格扣费。充值有它自己的支付窗口,不算在本文的“五分钟”里,具体说明见 USDT 充值。
工具。 任何能发送 HTTPS 请求的语言都可以。示例用 curl、搭配 requests 包的 Python,以及 Node.js 22+ 上的 JavaScript。请把 API 密钥放进环境变量 RENDERGRID_API_KEY,所有示例都从这里读取。API 密钥就是你余额的密码:不要把它写进网站或移动应用的代码,只在服务器端发送请求。
如何发送生成请求?
生成一张图片,就是向 /api/public/v1/images/generate 发送一次 POST 请求。API 密钥放在请求头 Authorization: Bearer <key> 里,请求体是 JSON,包含这些字段:
model:模型 id,这里是nano-banana-2.1。prompt:对图片的说明。这个字段必填:提示词为空时,请求会得到400响应,并且不会扣费。最多 20,000 个字符。resolution:1K、2K或4K。不传这个字段时,Nano Banana 2.1 默认按2K生成。aspect_ratio:宽高比,例如1:1。不传这个字段时为1:1。
请求头 X-Idempotency-Key 用来防止重复扣费:每张新图片用一个新的值,重试同一个请求时沿用原来的值。详见重试不重复扣费。
下面的示例用的就是本文三张图片的提示词。先按上一节把 API 密钥放进环境变量,再运行你所用语言的那一段。
# 需要 bash、curl 和 uuidgen。每个请求使用一个幂等键。 IDEMPOTENCY_KEY="$(uuidgen)" || exit 1 curl --fail-with-body --max-time 30 \ -X POST https://api.rendergrid.io/ api/ public/ v1/ images/ generate \ -H "Authorization: Bearer $RENDERGRID_API_KEY" \ -H "Content-Type: application/json" \ -H "X-Idempotency-Key: $IDEMPOTENCY_KEY" \ -d '{ "model": "nano-banana-2.1", "prompt": "浅色书桌上摆着一本合上的亚麻封面笔记本、一支木铅笔和一只白瓷杯。镜头略微俯视,三个物件集中在画面中央,外侧留白均衡。左边窗光柔和,能看清封面织纹、木纹与陶瓷釉面。不出现文字、标志、人物或水印。", "resolution": "1K", "aspect_ratio": "1:1" }'
import os import uuid import requests API = "https://api.rendergrid.io/ api/ public/ v1" KEY = os.environ["RENDERGRID_API_KEY"] PROMPT = "浅色书桌上摆着一本合上的亚麻封面笔记本、一支木铅笔和一只白瓷杯。镜头略微俯视,三个物件集中在画面中央,外侧留白均衡。左边窗光柔和,能看清封面织纹、木纹与陶瓷釉面。不出现文字、标志、人物或水印。" response = requests.post( f"{API}/images/generate", headers={ "Authorization": f"Bearer {KEY}", # 每张新图片用新的值;重试同一个请求时沿用原来的值 "X-Idempotency-Key": str(uuid.uuid4()), }, json={ "model": "nano-banana-2.1", "prompt": PROMPT, "resolution": "1K", "aspect_ratio": "1:1", }, timeout=(10, 120), ) response.raise_for_status() creation = response.json() print(creation["id"], creation["status"], creation["cost"])
// Node.js 22+,文件扩展名为 .mjs import { randomUUID } from "node:crypto"; const API = "https://api.rendergrid.io/ api/ public/ v1"; const prompt = "浅色书桌上摆着一本合上的亚麻封面笔记本、一支木铅笔和一只白瓷杯。镜头略微俯视,三个物件集中在画面中央,外侧留白均衡。左边窗光柔和,能看清封面织纹、木纹与陶瓷釉面。不出现文字、标志、人物或水印。"; const response = await fetch(`${API}/images/generate`, { method: "POST", headers: { Authorization: `Bearer ${process.env.RENDERGRID_API_KEY}`, "Content-Type": "application/json", // 每张新图片用新的值;重试同一个请求时沿用原来的值 "X-Idempotency-Key": randomUUID(), }, body: JSON.stringify({ model: "nano-banana-2.1", prompt, resolution: "1K", aspect_ratio: "1:1", }), signal: AbortSignal.timeout(120_000), }); if (response.status !== 202) { throw new Error(`HTTP ${response.status}: ${await response.text()}`); } const creation = await response.json(); console.log(creation.id, creation.status, creation.cost);
响应为 202 Accepted,意思是“请求已接收”,而不是“图片已就绪”。响应体里有 id、status(刚接收时为 queued)、task_id 和 cost:cost 是接收请求时从余额扣除的美元金额。请保存 id,之后要用它查询结果。
金额在开始处理之前就已扣除,如果最后没有生成图片,会自动退回余额。失败的请求如何退款,见这篇讲失败请求与退款的文章。
如何查询任务状态?
图片是在后台生成的,所以收到 202 之后还要主动查询结果:用同一个 API 密钥请求 GET /api/public/v1/creations/{id},把 {id} 换成请求响应里的 id。状态有四种:
queued:请求已接收,正在排队。processing:正在生成图片。completed:已完成,图片链接在result_urls里。failed:没有得到图片,响应里有error和failure,failure包含type、code和retryable。
状态为 queued 或 processing 时,请隔 5 秒或更久再查询;收到 completed 或 failed 就停止轮询。同一个任务、同一个 API 密钥,查询不要比每 5 秒一次更频繁,否则 API 会返回 429 ERR_RATE_LIMIT。限额和带间隔的重试,见这篇讲 429 错误与限额的文章。
CREATION_ID="5b0214ae-9e39-460a-820a-f6ae3e24400b" # 请求响应中的 id curl --fail-with-body --max-time 20 \ "https://api.rendergrid.io/ api/ public/ v1/ creations/ $CREATION_ID" \ -H "Authorization: Bearer $RENDERGRID_API_KEY"
import os import time import requests API = "https://api.rendergrid.io/ api/ public/ v1" KEY = os.environ["RENDERGRID_API_KEY"] HEADERS = {"Authorization": f"Bearer {KEY}"} creation_id = "5b0214ae-9e39-460a-820a-f6ae3e24400b" # 请求响应中的 id MAX_WAIT = 180 # 秒:这是你自己设定的等待上限,不是服务承诺的时限 started = time.monotonic() while True: r = requests.get(f"{API}/creations/{creation_id}", headers=HEADERS, timeout=(5, 20)) r.raise_for_status() creation = r.json() if creation["status"] in ("completed", "failed"): break if time.monotonic() - started > MAX_WAIT: raise TimeoutError(f"{creation_id}:等待超时,请稍后再查询") time.sleep(5) # 查询频率不能高于每 5 秒一次 if creation["status"] == "completed": print(creation["result_urls"]) else: print(creation["error"], creation["failure"])
// Node.js 22+,文件扩展名为 .mjs const API = "https://api.rendergrid.io/ api/ public/ v1"; const headers = { Authorization: `Bearer ${process.env.RENDERGRID_API_KEY}` }; const creationId = "5b0214ae-9e39-460a-820a-f6ae3e24400b"; // 请求响应中的 id const MAX_WAIT_MS = 180_000; // 你自己设定的等待上限,不是服务承诺的时限 const pending = (status) => status === "queued" || status === "processing"; const started = Date.now(); let creation; do { // 查询频率不能高于每 5 秒一次 await new Promise((resolve) => setTimeout(resolve, 5000)); const res = await fetch(`${API}/creations/${creationId}`, { headers, signal: AbortSignal.timeout(20_000), }); if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`); creation = await res.json(); if (pending(creation.status) && Date.now() - started > MAX_WAIT_MS) { throw new Error(`${creationId}:等待超时,请稍后再查询`); } } while (pending(creation.status)); console.log(creation.status); console.log(creation.result_urls ?? creation.error);
要等多久,事先没有承诺:它取决于模型和负载,所以请在自己的代码里设定等待上限。最近 7 天的平均等待时间为 40 秒。
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "queued",
"task_id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"cost": 0.02
}
{
"id": "5b0214ae-9e39-460a-820a-f6ae3e24400b",
"status": "completed",
"result_urls": [
"https:// …"
]
}
生成好的文件只保存一天,轮询不会延长保存期限:请在状态变为 completed 后立即把图片保存到你自己的存储里。你也可以不轮询,改在请求里传 webhook_url,也就是一个公开的 HTTPS 地址:图片完成或失败时,我们会向它发送 creation.completed 或 creation.failed 事件,轮询可以留作备用方案。详见 Webhook 文档和这篇讲批量生成、Webhook 与幂等键的文章。
如果任务变成了 failed,这笔费用会自动退回余额。想再生成一次,请发送一个带有新 X-Idempotency-Key 的新请求:这是一次新的请求,会照常扣费。
分辨率选 1K、2K 还是 4K?
resolution 字段决定图片的尺寸档位:1K、2K 或 4K,Nano Banana 2.1 这三档都能选。它是模型的尺寸档位,不是精确的像素数;API 不接受 width 和 height 字段。
我们把同一条提示词发送了三次:分辨率分别是 1K、2K 和 4K,宽高比都是 1:1,每档只生成一次。没有挑选,也没有重来。
同一条提示词,三档分辨率
浅色书桌上摆着一本合上的亚麻封面笔记本、一支木铅笔和一只白瓷杯。镜头略微俯视,三个物件集中在画面中央,外侧留白均衡。左边窗光柔和,能看清封面织纹、木纹与陶瓷釉面。不出现文字、标志、人物或水印。
Nano Banana 2.1
nano-banana-2.1 · 1K · 1:1 · $0.02
Nano Banana 2.1,1K,1:1,一次尝试。三件物品作为一组大致位于画面中央:笔记本偏左,铅笔斜放在笔记本右侧,杯子在右上方。镜头从较高的角度俯拍,桌面占满了大半个画面,桌子的前缘和桌腿在左下角入镜。提示词要求略微俯视,这个视角明显更陡。封面的亚麻织纹和桌面的木纹清晰可辨。光线来自左上角的窗口,杯子的影子落在它右侧,边缘柔和。笔记本封面中下部的颜色略深、偏暖。杯中有少量浅褐色液体,提示词没有提到。画面中没有文字、标志、人物或水印。
Nano Banana 2.1
nano-banana-2.1 · 2K · 1:1 · $0.03
Nano Banana 2.1,2K,1:1,一次尝试。三件物品排成一行,作为一组位于画面中央:笔记本在左,杯子在右,铅笔竖放在两者之间。镜头接近垂直向下,桌面占满画面,桌子的左缘和两个圆角入镜,桌腿在下方。提示词要求略微俯视,这个视角明显更陡。封面的亚麻织纹和桌面的木纹清晰。影子都落在物体右侧,说明光从左边来,但右半边桌面上有几道斜向的明暗条带,边缘较清晰,比提示词要求的柔和窗光更硬;杯子右侧的影子边缘也偏清晰。杯子是空的,直筒形,没有把手;铅笔下端有橡皮头。画面中没有文字、标志、人物或水印。
Nano Banana 2.1
nano-banana-2.1 · 4K · 1:1 · $0.04
Nano Banana 2.1,4K,1:1,一次尝试。三件物品作为一组位于画面中央,左右两侧和上下两侧的留白大致相等:笔记本斜放在左,铅笔斜放在它右边,杯子在右。镜头从较高的角度俯拍,桌面占满了大半个画面,左上角能看到窗框和窗外虚化的景物,桌子的前缘和桌腿在左下角。提示词要求略微俯视,这个视角明显更陡。封面的亚麻纹理和桌面的木纹可辨。杯子是空的,上宽下窄,没有把手。光线柔和,来自左上方的窗口,杯子的影子浅淡地落在右侧。画面中没有文字、标志、人物或水印。
在这三张方形图片上,API 返回的文件分别是 1024×1024、2048×2048 和 4096×4096 像素。三张图片里都是笔记本、铅笔和白瓷杯,但每次的画面都不一样:这是三次独立的生成,不是同一张图的三种尺寸。笔记本的朝向和封面颜色、铅笔的摆法、杯子的形状都不同;杯子在 1K 里有少量浅褐色液体,在 2K 和 4K 里是空的;2K 的光线也比另外两张更硬。所以不要指望 4K 是“同一个画面,只是更大”:这个示例里每一档都得到了自己的构图。
这三张图片也不能说明哪一档分辨率的质量、速度或稳定性更好:每档只有一次尝试。选哪一档,要看图片的用途和价格。
价格取决于分辨率:每张图片 1K 为 $0.02,2K 为 $0.03,4K 为 $0.04。不传 resolution 时,图片会按默认分辨率生成并计费,Nano Banana 2.1 的默认分辨率是 2K。价格的详细说明见这篇讲 Nano Banana 2.1 API 价格的文章和价格页。
第一个请求主要是为了跑通整条链路:API 密钥、请求和状态查询。以后想换档位,只改 resolution 这一个字段,请求的其余部分保持不变。
如何选择宽高比?
aspect_ratio 字段决定宽高比。Nano Banana 2.1 在每一档分辨率下都可以用 1:1、16:9、9:16、4:3、3:4、2:3、3:2、5:4、4:5 和 21:9,也可以用更狭长的 1:4、1:8、4:1 和 8:1。另外还有 auto:由模型自己选择宽高比。有参考图时,宽高比通常与第一张参考图一致;没有参考图时不保证宽高比,如果你的版面取决于它,请明确指定 aspect_ratio。
值要按列表原样写:不能有空格,也不能调换数字的顺序。没有这个字段不等于 auto,而是 1:1。本文的图片都是方形的;想得到横向的宽幅图片,就把请求里的这一项改成 "aspect_ratio": "16:9"。
如果所选宽高比不在模型支持的范围内,请求会在扣费前返回 400 ERR_INVALID_REQUEST,error.details.supported 里是可用值的列表,余额不会变化。你的账号能用哪些模型、价格是多少,以 GET /models 返回的目录为准,详见模型与参数。
示例没有涵盖什么?
常见问题解答
如何通过 API 生成 Nano Banana 2.1 的第一张图片?
POST /api/public/v1/images/generate,带上 model、prompt、resolution 和 aspect_ratio 字段。202 响应里会有 id:请用它请求 GET /api/public/v1/creations/{id},查询频率不要高于每 5 秒一次,直到状态变为 completed,再从 result_urls 里的链接取得图片。1K、2K 和 4K 的每张图片各多少钱?
cost 字段里。所有模型的价格见价格页。生成好的图片会保存多久?
completed 后立即把图片保存到你自己的存储里。失败的请求要付费吗?
可以指定图片的像素尺寸吗?
width 和 height 字段,请选择分辨率和宽高比。本文这三张方形图片的文件,实际大小分别是 1024×1024、2048×2048 和 4096×4096 像素。Nano Banana Pro 的请求有什么不同?
来源
- 快速开始——Rendergrid 文档API 密钥、请求、状态和下载结果。
- 生成图片——Rendergrid 文档请求字段、
202响应和扣费前的检查。 - 任务与状态——Rendergrid 文档状态、查询间隔和结果文件的保存期限。
- 密钥与鉴权——Rendergrid 文档如何创建、传递和保管 API 密钥。
- 模型与参数——Rendergrid 文档分辨率、宽高比和默认分辨率。
- Rendergrid 价格每款模型、每档分辨率的单张价格。
- 本文的三张图片同一条提示词,1K、2K 和 4K,1:1,每档一次尝试,通过 Rendergrid 公共 API 生成。
- Rendergrid 统计Nano Banana 2.1 最近 7 天的平均等待时间。





