API de Nano Banana 2.1: tu primera imagen en cinco minutos
Crea una clave de API, envía una solicitud a Nano Banana 2.1 y consulta el estado de la tarea hasta recibir la imagen. Ejemplo completo en curl, Python y JavaScript, con las resoluciones y las relaciones de aspecto que puedes elegir.
Redacción de RendergridSobre la redacción
En resumen
Para generar tu primera imagen con Nano Banana 2.1 necesitas una clave de API y saldo. Envías una solicitud POST a /images/generate, guardas el id de la respuesta 202 y consultas GET /creations/{id} hasta que el estado sea completed. Con resolution eliges 1K, 2K o 4K, y con aspect_ratio, la relación de aspecto.
Los cinco minutos del título son lo que lleva seguir esta guía, desde una cuenta que ya tiene saldo y una clave hasta la primera imagen terminada. No incluyen el registro ni la recarga, y no son un tiempo de generación ni una garantía.
¿Qué necesitas antes de empezar?
Los primeros pasos son siempre los mismos: crear una clave, recargar el saldo y generar.
Una clave de API. Créala como explica la página Claves y acceso. Empieza por
rg_live_, se muestra completa una sola vez y no se puede recuperar: guárdala en una variable de entorno del servidor, nunca en el código de un sitio web ni de una aplicación para teléfonos.Saldo en la cuenta. La recarga es solo en USDT: se hace en la sección «Saldo y recargas» del portal o a través de un gestor de cuenta, y tiene su propia ventana de pago, de 30–50 minutos, fuera de los cinco minutos de la guía. El cargo se hace por cada imagen.
Un lenguaje que envíe solicitudes HTTPS. Los ejemplos usan curl, Python con el paquete
requestsy JavaScript con Node.js 22 o superior.
¿Cómo envías la primera solicitud?
Una solicitud POST a /api/public/v1/images/generate pide una imagen. Lleva tu clave en el encabezado Authorization: Bearer y un cuerpo en JSON. Estos son los cuatro campos del ejemplo:
model: obligatorio. Aquí,nano-banana-2.1.prompt: obligatorio, hasta 20 000 caracteres.resolution: opcional,1K,2Ko4K. Si la omites, Nano Banana 2.1 genera en 2K.aspect_ratio: opcional, por ejemplo16:9. Si la omites, la imagen sale en1:1.
El encabezado X-Idempotency-Key lleva la clave de idempotencia: usa una nueva para cada imagen nueva y la misma si repites la misma solicitud, así no pagas dos veces. El ejemplo pide la escena de las tres imágenes de esta guía, en 1K y en 1:1:
# Hacen falta bash, curl y uuidgen. Una clave de idempotencia nueva por solicitud. 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": "Arma una escena de escritorio con un cuaderno cerrado de cubierta de lino, un lápiz de madera y una taza blanca de cerámica. La cámara mira desde un poco arriba. Agrupa los tres objetos al centro con márgenes parejos; la luz suave de una ventana a la izquierda revela las distintas texturas. Sin texto, logotipos, personas ni marcas de agua.", "resolution": "1K", "aspect_ratio": "1:1" }'
import os import uuid import requests key = os.environ["RENDERGRID_API_KEY"] PROMPT = "Arma una escena de escritorio con un cuaderno cerrado de cubierta de lino, un lápiz de madera y una taza blanca de cerámica. La cámara mira desde un poco arriba. Agrupa los tres objetos al centro con márgenes parejos; la luz suave de una ventana a la izquierda revela las distintas texturas. Sin texto, logotipos, personas ni marcas de agua." response = requests.post( "https://api.rendergrid.io/ api/ public/ v1/ images/ generate", headers={ "Authorization": f"Bearer {key}", # nueva en cada imagen nueva; la misma al repetir la misma solicitud "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+, archivo .mjs import { randomUUID } from "node:crypto"; const API = "https://api.rendergrid.io/ api/ public/ v1"; const prompt = "Arma una escena de escritorio con un cuaderno cerrado de cubierta de lino, un lápiz de madera y una taza blanca de cerámica. La cámara mira desde un poco arriba. Agrupa los tres objetos al centro con márgenes parejos; la luz suave de una ventana a la izquierda revela las distintas texturas. Sin texto, logotipos, personas ni marcas de agua."; const response = await fetch(`${API}/images/generate`, { method: "POST", headers: { Authorization: `Bearer ${process.env.RENDERGRID_API_KEY}`, "Content-Type": "application/json", // nueva en cada imagen nueva; la misma al repetir la misma solicitud "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);
La respuesta es 202 Accepted: significa «solicitud aceptada», no «imagen lista». cost es el importe en dólares que se cargó por la imagen, escrito como número. Guarda el id: con él consultas el resultado. Abajo ves las dos respuestas, la 202 al enviar y la 200 cuando la tarea termina:
{
"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:// …"
]
}
¿Cómo compruebas el estado de la tarea?
Pasa el id a GET /api/public/v1/creations/{id}. El estado es queued (en cola), processing (en proceso), completed (completada) o failed (fallida). Con completed y failed dejas de consultar: son finales. Consulta como máximo una vez cada 5 segundos por clave y por tarea: una consulta más frecuente recibe 429 ERR_RATE_LIMIT, y entonces espera al menos lo que indique Retry-After.
CREATION_ID="5b0214ae-9e39-460a-820a-f6ae3e24400b" # el id de la respuesta 202 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" # el id de la respuesta 202 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 time.sleep(5) # como máximo una consulta cada 5 segundos if creation["status"] == "completed": print(creation["result_urls"]) else: print(creation["error"], creation["failure"])
// Node.js 22+, archivo .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"; // el id de la respuesta 202 let creation; do { // como máximo una consulta cada 5 segundos await new Promise((resolve) => setTimeout(resolve, 5000)); const res = await fetch(`${API}/creations/${creationId}`, { headers }); if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`); creation = await res.json(); } while (["queued", "processing"].includes(creation.status)); console.log(creation.status); console.log(creation.result_urls ?? creation.error);
Cuando el estado es completed, la respuesta trae result_urls, los enlaces a los archivos. Úsalos tal cual y guarda la imagen en tu propio almacenamiento enseguida: los archivos se conservan un día, y consultar el estado no prolonga ese plazo.
No hay un plazo prometido para la espera: depende del modelo y de la carga.
Tiempo promedio de espera de los últimos 7 días — 40 s.Los bucles del ejemplo esperan sin límite: en producción limita el tiempo total de espera y guarda el id. Si se agota el tiempo de espera de tu cliente, la tarea no se cancela: puedes seguir consultándola con el mismo id.
En lugar de consultar, puedes pasar webhook_url en la solicitud y recibir un evento cuando la tarea llegue a completed o a failed; deja la consulta como vía de reserva, porque la notificación puede retrasarse o no llegar. Hay más en Webhooks y en el artículo sobre lotes, webhooks e idempotencia.
¿Qué hacer si la tarea termina en failed?
Una tarea failed trae error, un texto para mostrar, y failure con type, code y retryable: construye tu lógica con failure.type y failure.code, no con error. Una solicitud fallida es gratis: el importe vuelve de inmediato al saldo (cómo funciona el reembolso). Para un nuevo intento envía una solicitud nueva con una clave de idempotencia nueva: la anterior no reinicia la tarea, y el intento nuevo es una operación de pago nueva.
¿Qué resolución eliges: 1K, 2K o 4K?
resolution acepta 1K, 2K o 4K. El precio por imagen depende de ella: $0,02 en 1K, $0,03 en 2K y $0,04 en 4K, siempre en dólares estadounidenses (todos los modelos están en la página de precios). Si omites resolution, la imagen se genera y se cobra en la predeterminada, 2K.
Para ver qué cambia, enviamos el mismo prompt tres veces, una por resolución, en 1:1 y con un solo intento cada una:
Prompt: escritorio con cuaderno, lápiz y taza
Arma una escena de escritorio con un cuaderno cerrado de cubierta de lino, un lápiz de madera y una taza blanca de cerámica. La cámara mira desde un poco arriba. Agrupa los tres objetos al centro con márgenes parejos; la luz suave de una ventana a la izquierda revela las distintas texturas. Sin texto, logotipos, personas ni marcas de agua.
Nano Banana 2.1
nano-banana-2.1 · 1K · 1:1 · $0,02
Nano Banana 2.1, 1K, 1:1, un intento. El cuaderno de lino beige queda a la izquierda del centro, con la trama del tejido y el canto de las páginas a la vista. El lápiz descansa a su derecha, casi paralelo al borde del cuaderno y con la punta hacia abajo a la izquierda, y la taza blanca, de esmalte irregular, está arriba a la derecha. La cámara mira desde un ángulo alto y la mesa llena casi todo el encuadre: la vista es más alta de lo que pedía el prompt, que decía «desde un poco arriba». La ventana se ve en la esquina superior izquierda y las sombras caen hacia la derecha, de modo que la luz llega desde la izquierda, como pide el prompt; la sombra del lápiz, en cambio, tiene un borde más definido de lo que sugiere una luz suave. El grupo queda centrado en el encuadre, pero se aparta del prompt en los márgenes: ocupa casi todo el ancho, con márgenes laterales estrechos y mucho más espacio arriba y abajo. No hay texto, logotipos, personas ni marcas de agua.
Nano Banana 2.1
nano-banana-2.1 · 2K · 1:1 · $0,03
Nano Banana 2.1, 2K, 1:1, un intento. El cuaderno, de lino gris pardo con hilos más claros e irregulares, queda cerca del centro. El lápiz está sobre la cubierta, en diagonal y con la punta hacia arriba a la izquierda, y la taza blanca, lisa y con reflejos, está arriba a la derecha. La cámara mira desde un ángulo alto y la mesa llena casi todo el encuadre: la vista es más alta de lo que pedía el prompt, que decía «desde un poco arriba». Las sombras caen hacia la derecha, así que la luz parece venir de la izquierda, pero no se distingue la ventana. El grupo queda cerca del centro, pero los márgenes no son parejos y el prompt pedía que lo fueran: hay más margen a la izquierda que a la derecha y más arriba que abajo. No hay texto, logotipos, personas ni marcas de agua.
Nano Banana 2.1
nano-banana-2.1 · 4K · 1:1 · $0,04
Nano Banana 2.1, 4K, 1:1, un intento. El cuaderno de lino beige claro, con una trama fina y vertical, queda a la izquierda del centro. El lápiz está a su derecha, con la punta hacia arriba, y la taza blanca, de esmalte mate, arriba a la derecha. La cámara mira desde un ángulo alto y la mesa llena casi todo el encuadre: la vista es más alta de lo que pedía el prompt, que decía «desde un poco arriba». En la esquina superior izquierda hay una zona muy clara, de la ventana; las sombras caen hacia la derecha, así que la luz llega desde la izquierda, como pide el prompt, aunque la sombra del lápiz tiene un borde más definido de lo que sugiere una luz suave. En la esquina inferior izquierda se ven la pata y el borde frontal de la mesa, que el prompt no mencionaba. El grupo queda centrado, con los márgenes izquierdo y derecho casi iguales y el superior y el inferior casi iguales; es la imagen que más se acerca a lo que pide el prompt, aunque los márgenes laterales son más estrechos que los verticales. No hay texto, logotipos, personas ni marcas de agua.
Aquí, cada resolución fue una solicitud aparte, no una ampliación de la anterior; con el mismo prompt, la composición cambió en cada una: el cuaderno es beige en 1K, gris pardo en 2K y beige claro en 4K; el lápiz queda junto al cuaderno en 1K y en 4K, y encima de él en 2K; la taza tiene un esmalte irregular en 1K, es lisa y con reflejos en 2K y de esmalte mate en 4K.
El prompt pedía agrupar los tres objetos al centro con márgenes parejos. En los tres el grupo queda centrado o cerca del centro, pero sin márgenes parejos del todo: en 1K ocupa casi todo el ancho y en 2K el margen izquierdo es mayor que el derecho. El de 4K se acerca más. El prompt también pedía mirar «desde un poco arriba», y en los tres la cámara queda más alta. En los tres no hay texto, logotipos, personas ni marcas de agua.
Los archivos de estas tres solicitudes midieron 1 024, 2 048 y 4 096 píxeles por lado. La resolución es un nivel de tamaño del modelo, no un número exacto de píxeles: width y height no se aceptan, así que comprueba las dimensiones del archivo que recibes.
¿Cómo eliges la relación de aspecto?
aspect_ratio recibe un valor exacto, como 16:9, sin espacios ni cifras invertidas. Nano Banana 2.1 admite 1:1, 16:9, 9:16, 4:3, 3:4, 2:3, 3:2, 5:4, 4:5 y 21:9, además de 1:4, 1:8, 4:1 y 8:1, en las tres resoluciones, y el valor auto.
Sin aspect_ratio, la imagen sale en 1:1: que falte el campo no significa auto. Con auto, el modelo elige la relación por sí solo, y sin imágenes de referencia no se garantiza cuál será; si tu diseño depende de ella, indícala de forma explícita. Las tres imágenes de esta guía son 1:1.
Si pides una relación que el modelo no genera, la API responde 400 ERR_INVALID_REQUEST antes del cargo, y error.details.supported trae la lista de valores admitidos. Los parámetros del modelo están también en su página.
¿Qué no cubre este artículo?
- Tres imágenes no son una medición. Cada resolución se probó una vez con un solo prompt: no sirven para estimar velocidad, calidad ni fiabilidad, y con tus prompts el resultado puede ser otro.
- Los cinco minutos no son un tiempo de generación. La espera depende del modelo y de la carga.
- Una imagen por solicitud. Para más, envía solicitudes distintas con claves de idempotencia distintas, dentro de los límites de la cuenta: 120 solicitudes por minuto y 100 tareas en cola o en proceso.
- Solo texto. Los ejemplos no usan imágenes de referencia.
Si trabajas con Nano Banana Pro, tienes la guía de inicio rápido de su API. Para los límites y el error 429, lee el artículo sobre los límites de solicitudes.
Una solicitud fallida es gratis
Prueba el prompt de esta guía
Abre Nano Banana 2.1 en la zona de pruebas, escribe tu prompt y, cuando te convenza, pásalo a tu código.
Probar Nano Banana 2.1Preguntas frecuentes
¿Cuánto cuesta la primera imagen?
cost de la respuesta 202.¿Cuánto tarda en estar lista la imagen?
¿Cuánto tiempo se conservan las imágenes?
result_urls se conservan un día: descárgalos en cuanto el estado sea completed.¿Qué pasa si la tarea termina en failed?
failure.type y failure.code; para un nuevo intento, envía una solicitud nueva con una clave de idempotencia nueva.¿Qué recibo si repito la misma solicitud con la misma clave?
202, con los mismos id, status, task_id y cost. No hay imagen nueva ni cargo nuevo, y esa respuesta puede seguir mostrando queued.Fuentes
- Documentación de Rendergrid: inicio rápidoClave, primera solicitud, estado y descarga.
- Documentación de Rendergrid: crear una imagenCampos de la solicitud y respuesta
202. - Documentación de Rendergrid: tareas y estadosEstados, frecuencia de consulta y conservación de los archivos.
- Documentación de Rendergrid: claves y accesoFormato de la clave y cómo enviarla.
- Documentación de Rendergrid: modelos y parámetrosResoluciones, relaciones de aspecto y resolución predeterminada.
- Precios de RendergridPrecio por imagen de cada modelo y resolución.
- Las tres imágenes de esta guíaCada una fue una solicitud a la API de Rendergrid, un intento por resolución.





