Generación de imágenes (asíncrona, por trabajos) con Google Nano Banana 2.1, la versión mejorada de Nano Banana 2 lanzada en octubre de 2026. Para texto a imagen basta el prompt; para editar, pon las referencias en image o images (URL, data: URI o base64) o llama a /v1/images/edits. Al enviar recibes al instante un id de trabajo (HTTP 202); consulta GET /v1/images/jobs/{id} para obtener la imagen. Proporciones como 1:1, 3:4, 2:3, 9:16, 4:3, 3:2 y 16:9 en 1K / 2K / 4K, y también formatos anchos 4:1, 1:4, 8:1 y 1:8. Se cobra por imagen; las solicitudes fallidas no se cobran.
Probar en el Playground →Inicio rápido
Tres pasos: enviar el trabajo, consultarlo y quedarte con el enlace de la imagen. Sustituye YOUR_API_KEY por tu clave y los comandos de abajo funcionan tal cual.
curl https://nezhagate.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "nano-banana-2.1", "prompt": "An orange cat on a windowsill watching the rain, warm desk lamp, cinematic, shallow depth of field", "size": "16:9", "resolution": "2K"}'{
"id": "img_7f3c9a1e2b4d6f8a0c1e3b5d",
"object": "image.generation.job",
"status": "queued",
"created": 1791281500,
"model": "nano-banana-2.1"
}curl https://nezhagate.com/v1/images/jobs/img_7f3c9a1e2b4d6f8a0c1e3b5d \ -H "Authorization: Bearer YOUR_API_KEY"
{
"id": "img_7f3c9a1e2b4d6f8a0c1e3b5d",
"object": "image.generation.job",
"status": "succeeded",
"created": 1791281500,
"model": "nano-banana-2.1",
"data": [
{"url": "https://img.nezhagate.com/i/2be8cd16d37f3a4b9c0e1f2a3b4c5d6e.png"}
],
"usage": {"images": 1, "resolution": "2K", "model": "nano-banana-2.1"}
}Paso 3 · data[0].url es la imagen (PNG). Se guarda 60 días; descárgala a tu propio almacenamiento si la necesitas más tiempo.
import time
import requests
BASE = "https://nezhagate.com/v1"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY"}
# 1. enviar
job = requests.post(f"{BASE}/images/generations", headers=HEADERS, json={
"model": "nano-banana-2.1",
"prompt": "An orange cat on a windowsill watching the rain, warm desk lamp, cinematic, shallow depth of field",
"size": "16:9",
"resolution": "2K",
}).json()
if "error" in job:
raise SystemExit(job["error"]["message"])
# 2. consultar cada 3 segundos hasta que termine
while job["status"] not in ("succeeded", "failed"):
time.sleep(3)
job = requests.get(f"{BASE}/images/jobs/{job['id']}", headers=HEADERS).json()
# 3. descargar la imagen
if job["status"] == "succeeded":
url = job["data"][0]["url"]
with open("nano-banana-2.1.png", "wb") as f:
f.write(requests.get(url).content)
print("saved", url)
else:
print("failed:", job["error"]["message"])Autenticación
Authorization: Bearer YOUR_API_KEY Content-Type: application/json
Crea una clave API en la consola para empezar.
Cuerpo de la petición
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| model | string | Sí | ID del modelo; aquí nano-banana-2.1. |
| prompt | string | Sí | Prompt de texto que describe la imagen. |
| size | string | No | Relación de aspecto de salida. Recomendado: pasa una relación (1:1, 3:4, 2:3, 9:16, 4:3, 3:2, 16:9) y el modelo renderiza de forma nativa con esa proporción, sin recortar el sujeto. También se aceptan tamaños en píxeles (p. ej. 1024x1024, 1024x1536, 1536x1024). Por defecto 1:1 (cuadrada). |
| resolution | string | No | Nivel de resolución: 1K (por defecto) / 2K / 4K, con cobro según el nivel. Úsalo con una proporción en size, p. ej. {"size": "16:9", "resolution": "2K"}; los píxeles exactos de cada nivel están en «Proporción, resolución y tamaño de salida», más abajo. Si size es un tamaño en píxeles (p. ej. 2048x1152), el nivel lo decide su lado más largo. |
| n | integer | No | Siempre 1: cada trabajo devuelve una imagen. Un valor mayor sigue devolviendo una imagen y cobrando una; para varias imágenes envía varios trabajos a la vez. |
| image | string | No | Imagen a imagen: una imagen de referencia como URL pública, data: URI o base64 en bruto. Si está presente, la petición ejecuta una verdadera transformación imagen a imagen que preserva la identidad en el tamaño y la proporción elegidos, equivalente a llamar a /v1/images/edits. |
| images | array | No | Varias imágenes de referencia, hasta 8 (si mandas más, solo se usan las 8 primeras): un array de cadenas o de objetos {"image_url": "..."}; cada una es una URL pública, un data: URI o base64, de hasta 16 MB. Enviarlas activa imagen a imagen, igual que /v1/images/edits. Para una sola referencia también sirve el campo image de arriba. |
Ejemplo de petición
# 1) submit -> 202 {"id":"img_...","status":"queued"}
curl https://nezhagate.com/v1/images/generations -H 'Authorization: Bearer YOUR_API_KEY' -H 'Content-Type: application/json' -d '{"model": "nano-banana-2.1", "prompt": "a serene ink-wash poster, lots of negative space", "size": "16:9", "resolution": "2K"}'
# 2) poll until status=succeeded
curl https://nezhagate.com/v1/images/jobs/img_3f9a...c2 -H 'Authorization: Bearer YOUR_API_KEY'Respuesta
{
"id": "img_3f9a...c2",
"object": "image.generation.job",
"status": "queued",
"model": "nano-banana-2.1"
}Precio
Se cobra por imagen y el precio depende solo del nivel de resolución: la proporción y si es texto a imagen o imagen a imagen no cambian nada. Al enviar se retiene el precio del nivel y, si el trabajo falla, se reembolsa por completo. 1 crédito = $0.005.
| Nivel | Créditos por imagen | USD por imagen |
|---|---|---|
| 1K | 3 | $0.015 |
| 2K | 5 | $0.025 |
| 4K | 8 | $0.04 |
Cada trabajo devuelve exactamente una imagen: envíes el n que envíes, recibes una imagen y pagas una. Para varias imágenes, envía varios trabajos a la vez (una cuenta genera hasta 50 al mismo tiempo).
Proporción, resolución y tamaño de salida
Pon la proporción en size y el nivel en resolution (1K por defecto, 2K o 4K). El modelo dibuja directamente en la proporción elegida; no dibuja un cuadrado para recortarlo después. La imagen entregada tiene un lado largo de 1024 / 2048 / 4096 píxeles y el otro sigue la proporción. Proporciones habituales:
| Proporción | 1K | 2K | 4K |
|---|---|---|---|
| 1:1 | 1024x1024 | 2048x2048 | 4096x4096 |
| 3:4 | 768x1024 | 1536x2048 | 3072x4096 |
| 2:3 | 683x1024 | 1365x2048 | 2731x4096 |
| 9:16 | 576x1024 | 1152x2048 | 2304x4096 |
| 4:3 | 1024x768 | 2048x1536 | 4096x3072 |
| 3:2 | 1024x683 | 2048x1365 | 4096x2731 |
| 16:9 | 1024x576 | 2048x1152 | 4096x2304 |
Además de estas siete, 4:5, 5:4, 21:9, 1:4, 4:1, 1:8 y 8:1 también se dibujan de forma nativa (con la misma regla del lado largo). Cualquier otra proporción se dibuja en la forma horizontal, vertical o cuadrada más cercana y luego se recorta a la tuya, lo que puede cortar parte de la imagen.
size también puede ser un tamaño en píxeles (p. ej. 1536x1024): la imagen se entrega exactamente con ese tamaño y el nivel lo decide el lado más largo: hasta 1536 es 1K, hasta 2048 es 2K y por encima es 4K. resolution solo acepta 1K / 2K / 4K (en mayúsculas o minúsculas); cualquier otro valor se ignora y el nivel sale de size, 1K por defecto. Sin size obtienes un cuadrado 1:1.
Imagen a imagen e imágenes de referencia
- Envía image (una imagen) o images (varias, hasta 8; si mandas más, solo se usan las 8 primeras) y el trabajo pasa a ser imagen a imagen; explica en el prompt qué quieres cambiar. POST /v1/images/edits admite los mismos parámetros.
- Cada referencia puede ser una URL pública de imagen (http o https), un data: URI o base64 sin más, de hasta 16 MB cada una, en un formato común como JPEG, PNG o WebP.
- La URL tiene que descargar la imagen en sí: no una página web, ni una dirección que pida iniciar sesión o bloquee el hotlinking. Una referencia que no podemos leer se rechaza al enviar con un 400 y el motivo; no se crea ningún trabajo ni se cobra nada.
- La proporción de salida la decide size, no la referencia. Para mantener la proporción original, pon en size la de la imagen.
- Alojamos las referencias por ti y las guardamos 7 días.
curl https://nezhagate.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "nano-banana-2.1", "prompt": "Keep the people, change the background to a beach at night with warm string lights", "images": ["https://example.com/people.jpg", "https://example.com/beach.jpg"], "size": "3:4", "resolution": "2K"}'Estado del trabajo y campos
GET /v1/images/jobs/{id} siempre devuelve id, object (image.generation.job), status, created (segundos Unix) y model; los demás campos dependen del estado:
| status | Significado | Campos adicionales |
|---|---|---|
| queued | En cola | queue_position (trabajos por delante del tuyo), eta_seconds (espera estimada en segundos, orientativa) |
| processing | Generando | — |
| succeeded | Listo | data[].url (el enlace de la imagen; nuestro alojamiento la guarda 60 días); usage.images (imágenes entregadas), usage.resolution (nivel cobrado) |
| failed | Fallido; el importe retenido al enviar se ha reembolsado por completo | error.message, error.type, error.code |
Consulta cada 2-3 segundos. Una cuenta genera hasta 50 imágenes a la vez; los demás trabajos esperan en orden de envío, y un trabajo que no ha empezado a los 15 minutos falla y se reembolsa por completo. Los registros de los trabajos se guardan 3 días; después, el id devuelve 404, pero el enlace de la imagen sigue siendo válido durante sus 60 días. Solo la cuenta que envió un trabajo puede consultarlo.
Cuánto tarda
Tiempo habitual desde el envío hasta el resultado, como referencia. Imagen a imagen tarda de unos segundos a una docena más; un trabajo que la pasarela repite en otra línea puede tardar 1-2 minutos.
| Nivel | Tiempo habitual |
|---|---|
| 1K | 25–40 s |
| 2K | 25–50 s |
| 4K | 35–80 s |
Errores y reembolsos
Todos los errores tienen la misma forma, {"error": {"message", "type", "code", "param"}}; decide según code.
Errores devueltos al enviar (no se crea ningún trabajo ni se cobra nada)
| HTTP | code | Causa | Qué hacer |
|---|---|---|---|
| 400 | missing_prompt | prompt está vacío | Añade un prompt |
| 400 | model_not_found | El id del modelo es incorrecto o no está disponible ahora | Revisa el id; /v1/models lista los disponibles |
| 400 | invalid_request | No se puede leer una imagen de referencia (enlace roto, no es una imagen, más de 16 MB...); message dice cuál y por qué | Usa un enlace directo a la imagen o envíala en base64 |
| 401 | invalid_api_key | La clave es incorrecta, se ha borrado o está desactivada | Revisa la clave en la consola |
| 402 | insufficient_quota | No hay saldo suficiente para retener este trabajo | Recarga y vuelve a intentarlo |
| 429 | rate_limit_exceeded | Se superó el límite por minuto fijado en esta clave | Reduce la frecuencia o sube el límite de la clave en la consola |
| 503 | model_maintenance | El modelo está en mantenimiento | Inténtalo más tarde; consulta la página de estado |
| 503 | service_unavailable | Un error temporal de nuestro lado (p. ej. al guardar tu referencia) | Vuelve a intentarlo en un momento |
Trabajos fallidos (el trabajo se aceptó y terminó con status failed; la retención se reembolsa por completo)
| Situación | Qué verás | Qué hacer |
|---|---|---|
| El prompt o una referencia no pasó la revisión de seguridad de Google | error.message como Content blocked | Reescribe el prompt o cambia la referencia; reenviarlo sin cambios suele volver a rechazarse |
| Una línea de generación falló o agotó el tiempo (antes reintentamos en otras líneas y solo devolvemos el fallo si fallan todas) | error.code como upstream_error o upstream_timeout, con el motivo en message | Vuelve a enviarlo |
| El trabajo esperó 15 minutos sin empezar | error.message lo indica | Vuelve a enviarlo más tarde |
Usa un webhook en lugar de consultar
En producción, añade callback_url al enviar. Cuando el trabajo termine, bien o mal, enviaremos por POST a esa URL el mismo JSON que devuelve la consulta, como image.completed o image.failed, con cabeceras de firma que puedes verificar. También puedes fijar una URL para toda la cuenta en Ajustes > Webhook. Documentación de webhooks
curl https://nezhagate.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "nano-banana-2.1", "prompt": "An orange cat on a windowsill watching the rain, warm desk lamp, cinematic, shallow depth of field", "size": "1:1", "callback_url": "https://your-domain.com/webhook"}'