Crear aplicaciones con generación de imágenes mediante IA se siente como magia, hasta que te topas con la complejidad de la documentación de la API, los quebraderos de cabeza de la autenticación y las pesadillas de depuración. Ya has visto lo que puede hacer Nano Banana 2: impresionantes imágenes generadas a partir de indicaciones de texto, resultados de calidad profesional a velocidades Flash y características como la consistencia del sujeto que hacen posibles los flujos de trabajo multi-imagen. Pero, ¿integrarlo realmente en tu base de código? Ahí es donde la mayoría de los desarrolladores se quedan atascados.
Probablemente has intentado navegar por la documentación de Google, uniendo flujos de autenticación y probando manualmente solicitudes en una CLI. Quizás ya has agotado tu cuota de API depurando solicitudes mal formadas o te has preguntado por qué tus imágenes salen borrosas cada vez. La verdad es que integrar cualquier nueva API, especialmente una tan potente como Nano Banana 2, requiere más que solo leer la documentación. Necesitas un flujo de trabajo que te permita probar rápidamente, iterar sobre las indicaciones y gestionar tus llamadas a la API de manera eficiente.
En esta guía, te mostraremos todo lo que necesitas para integrar Nano Banana 2 en tus aplicaciones, desde la configuración de tu proyecto de Google Cloud hasta la escritura de código listo para producción en Python y JavaScript. Pero aquí está lo que hace que esta guía sea diferente: te mostraremos cómo probar y depurar cada paso usando Apidog, para que no solo copies código, sino que construyas un flujo de trabajo que puedas mantener y escalar.
Requisitos Previos
Antes de empezar, asegúrate de tener:
- Una cuenta de Google Cloud (o regístrate en cloud.google.com)
- Conocimientos básicos de APIs REST
- Python 3.8+ o Node.js 18+ instalados
- Un cliente de API como Apidog para realizar pruebas
Esta guía asume que estás familiarizado con la realización de solicitudes HTTP y el manejo de datos JSON. Si eres nuevo en las APIs, consulta nuestra Guía de Pruebas de API para conocer los fundamentos.
Configurando tu Proyecto de Google Cloud
Para usar la API de Nano Banana 2, necesitas un proyecto de Google Cloud con la API de Generative Language habilitada.
Paso 1: Crear un Nuevo Proyecto
- Ve a la Consola de Google Cloud
- Haz clic en "Seleccionar un proyecto" → "Nuevo Proyecto"
- Introduce un nombre de proyecto (por ejemplo, "nano-banana-image-gen")
- Haz clic en "Crear"
- Espera a que se cree el proyecto

Paso 2: Configurar Acceso a la API
- Ve a "APIs y servicios" → "Credenciales"
- Haz clic en "Crear credenciales" → "Clave de API"
- Copia tu clave de API (la necesitarás más adelante)

Consejo Pro:
Obteniendo tu Clave de API
Hay dos formas de obtener acceso a la API:
Opción 1: Consola de Google Cloud (Recomendado para Producción)
Sigue los pasos anteriores: la clave de API que creaste es tu credencial de acceso.
Opción 2: Google AI Studio (Recomendado para Desarrollo)
- Ve a Google AI Studio
- Inicia sesión con tu cuenta de Google
- Haz clic en "Obtener clave de API" en la navegación
- Haz clic en "Crear clave de API" (o selecciona un proyecto existente)
- Copia tu clave de API

La clave de AI Studio es excelente para desarrollo y pruebas. Para producción, usa la clave de la Consola de Google Cloud para una mejor gestión y seguridad.
Tu Primera Solicitud de API
Hagamos una simple solicitud de generación de imágenes para verificar que todo funciona.
Usando cURL
curl -X POST \
"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp-image-generation:predict?key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "Un simpático personaje de plátano con gafas de sol, estilo dibujo animado divertido",
"number_of_images": 1
}'
Entendiendo la Respuesta
{
"predictions": [
{
"image": {
"mimeType": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg=="
},
"generatedImageId": "img_abc123xyz",
"metadata": {
"prompt": "Un simpático personaje de plátano con gafas de sol, estilo dibujo animado divertido",
"seed": 12345,
"finishReason": "SUCCESS"
}
}
],
"metadata": {
"modelVersion": "gemini-3.1-flash-image-preview",
"processingTimeMs": 1250,
"contentAuthenticity": {
"synthID": "enabled",
"c2pa": "enabled"
}
}
}
El campo data contiene una imagen PNG codificada en base64. Deberás decodificarla para guardar o mostrar la imagen.
Integración en Python
Aquí te mostramos cómo integrar Nano Banana 2 en tus aplicaciones Python:
Instalando la Biblioteca Cliente
pip install google-generativeai
Generación Básica de Imágenes
import google.generativeai as genai
import base64
import os
# Configure the API with your key
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
# Create the model
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# Generate an image
response = model.generate_images(
prompt="Una oficina moderna y minimalista con iluminación natural, plantas de interior, escritorio de pie, calidad 4k",
number_of_images=1
)
# Save the image
if response.generated_images:
image_data = response.generated_images[0].image_bytes
with open("output_image.png", "wb") as f:
f.write(image_data)
print("Image saved to output_image.png")
Generación Avanzada de Imágenes con Parámetros
import google.generativeai as genai
from PIL import Image
import io
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# Generate with advanced parameters
response = model.generate_images(
prompt="Un paisaje urbano futurista por la noche con luces de neón, coches voladores, estética cyberpunk",
number_of_images=1,
aspect_ratio="16:9",
negative_prompt="borroso, baja calidad, distorsionado, feo",
safety_filter_level="block_medium_and_above"
)
# Process the response
for idx, generated_image in enumerate(response.generated_images):
# Convert to PIL Image
image = Image.open(io.BytesIO(generated_image.image_bytes))
# Save with custom name
image.save(f"generated_image_{idx}.png")
# Access metadata
print(f"Image {idx}: {generated_image.finish_reason}")
print(f"Seed: {generated_image.seed}")
Generación por Lotes de Imágenes
import google.generativeai as genai
import os
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# Generate multiple images at once
prompts = [
"Un coche deportivo rojo en una carretera de montaña",
"Un acogedor interior de cafetería",
"Un diseño de dormitorio minimalista",
"Un atardecer tropical en la playa"
]
# Generate all images
for idx, prompt in enumerate(prompts):
response = model.generate_images(
prompt=prompt,
number_of_images=1,
aspect_ratio="16:9"
)
if response.generated_images:
image_data = response.generated_images[0].image_bytes
with open(f"image_{idx + 1}.png", "wb") as f:
f.write(image_data)
print(f"Generated: image_{idx + 1}.png")
Ejemplo de Consistencia de Personajes
import google.generativeai as genai
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
# Base character description
base_character = "Un robot de dibujos animados amigable con cuerpo redondo, ojos azules, antena en la cabeza, esquema de color blanco y azul claro"
# Generate base character (note the seed for consistency)
response1 = model.generate_images(
prompt=base_character + ", vista frontal, pose de pie",
number_of_images=1,
seed=42 # Important: note this seed
)
base_seed = response1.generated_images[0].seed
print(f"Base character seed: {base_seed}")
# Generate variations using the same seed
poses = [
"pose sentado",
"saludando con la mano",
"sosteniendo una pelota",
"caminando"
]
for pose in poses:
response = model.generate_images(
prompt=f"{base_character}, {pose}, mismo personaje que la semilla {base_seed}",
number_of_images=1,
seed=base_seed # Same seed maintains consistency
)
if response.generated_images:
filename = f"robot_{pose.replace(' ', '_')}.png"
with open(filename, "wb") as f:
f.write(response.generated_images[0].image_bytes)
print(f"Generated: {filename}")
Integración en JavaScript/Node.js
Instalando la Biblioteca Cliente
npm install @google/generative-ai
Generación Básica de Imágenes
const { GoogleGenerativeAI } = require("@google/generative-ai");
const fs = require("fs");
const path = require("path");
// Initialize with API key
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function generateImage() {
// Get the model
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
// Generate image
const result = await model.generateImages({
prompt: "Un hermoso atardecer sobre el océano con siluetas de palmeras",
numberOfImages: 1,
});
// Process the response
if (result.generatedImages && result.generatedImages.length > 0) {
const imageData = result.generatedImages[0].imageBytes;
// Save to file
fs.writeFileSync("sunset.png", Buffer.from(imageData, "base64"));
console.log("Image saved to sunset.png");
// Log metadata
console.log("Seed:", result.generatedImages[0].seed);
console.log("Finish Reason:", result.generatedImages[0].finishReason);
}
}
generateImage().catch(console.error);
Manejo de Respuestas Base64
const { GoogleGenerativeAI } = require("@google/generative-ai");
const fs = require("fs");
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function generateAndProcessImage() {
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
const result = await model.generateImages({
prompt: "Retrato profesional de una persona con ropa de negocios, iluminación de estudio",
numberOfImages: 1,
aspectRatio: "1:1",
resolution: "1024x1024"
});
const generatedImage = result.generatedImages[0];
// Decode base64
const imageBuffer = Buffer.from(generatedImage.imageBytes, "base64");
// Save with metadata in filename
const filename = `portrait_${generatedImage.seed}.png`;
fs.writeFileSync(filename, imageBuffer);
return {
filename,
seed: generatedImage.seed,
finishReason: generatedImage.finishReason
};
}
generateAndProcessImage()
.then(info => console.log("Generated:", info))
.catch(err => console.error("Error:", err));
Ejemplo de API REST con Express.js
const express = require("express");
const { GoogleGenerativeAI } = require("@google/generative-ai");
const multer = require("multer");
const fs = require("fs");
const app = express();
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
app.use(express.json());
// Image generation endpoint
app.post("/api/generate", async (req, res) => {
try {
const { prompt, aspect_ratio, negative_prompt, number_of_images } = req.body;
const model = genAI.getGenerativeModel({
model: "gemini-2.0-flash-exp-image-generation",
});
const result = await model.generateImages({
prompt,
numberOfImages: number_of_images || 1,
aspectRatio: aspect_ratio || "1:1",
negativePrompt: negative_prompt
});
// Convert images to base64 for response
const images = result.generatedImages.map((img, idx) => ({
id: idx,
seed: img.seed,
finishReason: img.finishReason,
data: img.imageBytes // Base64 encoded
}));
res.json({
success: true,
images,
metadata: {
modelVersion: result.response?.metadata?.modelVersion,
processingTimeMs: result.response?.metadata?.processingTimeMs
}
});
} catch (error) {
console.error("Generation error:", error);
res.status(500).json({
success: false,
error: error.message
});
}
});
// Batch generation endpoint
app.post("/api/generate/batch", async (req, res) => {
try {
const { prompts } = req.body;
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
const results = [];
for (const prompt of prompts) {
const result = await model.generateImages({
prompt,
numberOfImages: 1
});
results.push({
prompt,
seed: result.generatedImages[0]?.seed,
success: !!result.generatedImages[0]
});
}
res.json({ success: true, results });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});
Parámetros Avanzados
Nano Banana 2 admite varios parámetros para ajustar la generación de tus imágenes:
Referencia de Parámetros
| Parámetro | Tipo | Descripción | Ejemplo |
|---|---|---|---|
prompt | string | Descripción textual de la imagen deseada | "Un gato sentado en una alfombra" |
number_of_images | entero | Número de imágenes a generar (1-4) | 2 |
aspect_ratio | string | Relación de aspecto de la imagen | "16:9", "1:1", "4:3" |
resolution | string | Resolución de salida | "1024x1024", "2048x2048" |
negative_prompt | string | Elementos a excluir | "borroso, marca de agua" |
seed | entero | Semilla aleatoria para la reproducibilidad | 12345 |
safety_filter_level | string | Filtrado de contenido | "block_medium_and_above" |
Opciones de Resolución
# Available resolutions
resolutions = [
"512x512", # Miniatura, redes sociales
"768x768", # Imágenes web pequeñas
"1024x1024", # Cuadrado estándar
"1024x768", # Paisaje 4:3
"1280x720", # HD ready
"1920x1080", # Full HD
"2048x2048", # Alta calidad
"3840x2160" # 4K
]
# Using specific resolution
response = model.generate_images(
prompt="Fotografía de producto profesional de un reloj",
resolution="2048x2048"
)
Relaciones de Aspecto
aspect_ratios = [
"1:1", # Cuadrado (publicaciones de Instagram)
"4:3", # Foto estándar
"16:9", # Paisaje (YouTube, web)
"9:16", # Retrato (Historias, TikTok)
"21:9", # Ultrawide
"3:4", # Retrato estándar
"2:3" # Foto de retrato
]
# Using specific aspect ratio
response = model.generate_images(
prompt="Diseño interior de oficina moderno",
aspect_ratio="16:9"
)
Manejo de Respuestas
Analizando la Estructura de la Respuesta
import google.generativeai as genai
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
response = model.generate_images(
prompt="Un castillo de fantasía en una montaña",
number_of_images=2
)
# Access predictions (generated images)
for idx, image in enumerate(response.generated_images):
print(f"Imagen {idx + 1}:")
print(f" - Semilla: {image.seed}")
print(f" - Razón de finalización: {image.finish_reason}")
print(f" - Longitud de Bytes de la Imagen: {len(image.image_bytes)}")
# Access metadata
print("\nMetadatos:")
print(f" - Versión del Modelo: {response.response.metadata.model_version}")
print(f" - Tiempo de Procesamiento: {response.response.metadata.processing_time_ms}ms")
print(f" - SynthID: {response.response.metadata.content_authenticity.synth_id}")
Convirtiendo a Diferentes Formatos
from PIL import Image
import io
import base64
def image_to_different_formats(image_bytes):
"""Convertir la imagen generada a múltiples formatos."""
# Load as PIL Image
img = Image.open(io.BytesIO(image_bytes))
# Save as PNG
img.save("image.png", "PNG")
# Save as JPEG (with quality)
img.save("image.jpg", "JPEG", quality=95)
# Convert to WebP (smaller file size)
img.save("image.webp", "WEBP", quality=85)
# Get base64 for embedding
buffered = io.BytesIO()
img.save(buffered, format="PNG")
base64_str = base64.b64encode(buffered.getvalue()).decode()
return base64_str
Manejo de Errores
Un manejo adecuado de errores es esencial para las aplicaciones en producción:
Manejo de Errores en Python
import google.generativeai as genai
from google.api_core.exceptions import (
ResourceExhausted,
InvalidArgument,
ServiceUnavailable
)
genai.configure(api_key=os.environ.get("GEMINI_API_KEY"))
model = genai.GenerativeModel("gemini-3.1-flash-image-preview")
def generate_image_with_retry(prompt, max_retries=3):
"""Generate image with retry logic."""
for attempt in range(max_retries):
try:
response = model.generate_images(
prompt=prompt,
number_of_images=1
)
return response
except ResourceExhausted as e:
# Rate limit or quota exceeded
print(f"Límite de tasa excedido (intento {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
import time
time.sleep(2 ** attempt) # Retraso exponencial
else:
raise Exception("Límite de tasa excedido. Por favor, inténtelo de nuevo más tarde.")
except InvalidArgument as e:
# Invalid prompt or parameters
raise ValueError(f"Solicitud inválida: {e}")
except ServiceUnavailable as e:
# Service temporarily unavailable
print(f"Servicio no disponible (intento {attempt + 1}/{max_retries})")
if attempt < max_retries - 1:
import time
time.sleep(5) # Esperar 5 segundos
else:
raise Exception("Servicio no disponible. Por favor, inténtelo de nuevo más tarde.")
return None
# Usage
try:
result = generate_image_with_retry("Un hermoso paisaje")
if result:
print("Imagen generada con éxito")
except Exception as e:
print(f"Error: {e}")
Manejo de Errores en JavaScript
const { GoogleGenerativeAI } = require("@google/generative-ai");
const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY);
async function generateImageWithRetry(prompt, maxRetries = 3) {
const model = genAI.getGenerativeModel({
model: "gemini-3.1-flash-image-preview",
});
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const result = await model.generateImages({
prompt,
numberOfImages: 1
});
return result;
} catch (error) {
console.error(`Fallo en el intento ${attempt + 1}:`, error.message);
if (error.message.includes("RESOURCE_EXHAUSTED")) {
// Rate limited
const delay = Math.pow(2, attempt) * 1000;
console.log(`Límite de tasa excedido. Reintentando en ${delay}ms...`);
await new Promise(resolve => setTimeout(resolve, delay));
} else if (error.message.includes("INVALID_ARGUMENT")) {
// Invalid prompt
throw new Error(`Solicitud inválida: ${error.message}`);
} else if (attempt === maxRetries - 1) {
throw error;
}
}
}
return null;
}
// Usage
generateImageWithRetry("Un sereno lago de montaña al amanecer")
.then(result => {
if (result) {
console.log("Imagen generada con éxito");
}
})
.catch(err => {
console.error("No se pudo generar la imagen:", err.message);
});
Códigos de Error Comunes
| Código de Error | Descripción | Solución |
|---|---|---|
| 400 | Parámetros de solicitud inválidos | Verificar la indicación, relación de aspecto, resolución |
| 403 | Clave de API inválida o sin permisos | Verificar clave de API y permisos |
| 429 | Límite de tasa excedido | Implementar retirada, reducir frecuencia de solicitudes |
| 500 | Error interno del servidor | Reintentar con retirada exponencial |
| 503 | Servicio no disponible | Esperar y reintentar |
Pruebas con Apidog
Apidog es una excelente herramienta para probar y depurar tu integración con la API de Nano Banana 2:
Configurando tu Espacio de Trabajo en Apidog
- Abre Apidog y crea un nuevo proyecto
- Añade variables de entorno:
GEMINI_API_KEY: your_api_key_here
BASE_URL: https://generativelanguage.googleapis.com/v1beta

Creando Solicitudes de API
Endpoint: POST /models/gemini-3.1-flash-image-preview:predict
Encabezados:
Authorization: Bearer {{GEMINI_API_KEY}}
Content-Type: application/json

Cuerpo de la Solicitud:
{
"prompt": "{{prompt}}",
"number_of_images": 1,
"aspect_ratio": "1:1"
}
Parámetros de Consulta:
key: {{GEMINI_API_KEY}}
Escribiendo Scripts de Prueba
// Prueba: Generación exitosa
pm.test("Generación de imagen exitosa", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.predictions).to.have.property('image');
pm.expect(jsonData.predictions[0].metadata.finishReason).to.eql('SUCCESS');
});
// Prueba: La respuesta contiene metadatos
pm.test("La respuesta tiene los metadatos requeridos", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.metadata).to.have.property('modelVersion');
pm.expect(jsonData.metadata).to.have.property('processingTimeMs');
});
// Prueba: Autenticidad del contenido verificada
pm.test("Autenticidad del contenido habilitada", function() {
var jsonData = pm.response.json();
pm.expect(jsonData.metadata.contentAuthenticity.synthID).to.eql('enabled');
});
// Prueba: Tiempo de respuesta aceptable
pm.test("Tiempo de respuesta inferior a 5 segundos", function() {
pm.expect(pm.response.responseTime).to.be.below(5000);
});
Creando una Colección para Pruebas por Lotes
Guarda estas solicitudes en Apidog para construir una colección de pruebas:
- Generación Básica - Generación de una sola imagen
- Generación por Lotes - Múltiples indicaciones
- Consistencia de Personaje - Prueba con la misma semilla
- Manejo de Errores - Prueba de indicación inválida
- Prueba de Rendimiento - Múltiples solicitudes concurrentes
Mejores Prácticas para Producción
Al implementar Nano Banana 2 en producción:
1. Protege tu Clave de API
# Nunca codifiques las claves de API directamente
# Usa variables de entorno
import os
API_KEY = os.environ.get("GEMINI_API_KEY")
# O usa un gestor de secretos
# AWS Secrets Manager, HashiCorp Vault, etc.
2. Implementa Caché
import hashlib
import redis
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def generate_image_cached(prompt, seed=None):
"""Generar imagen con caché."""
# Create cache key from prompt + seed
cache_key = f"image:{hashlib.md5(f'{prompt}:{seed}'.encode()).hexdigest()}"
# Check cache
cached = redis_client.get(cache_key)
if cached:
return cached
# Generate new image
response = model.generate_images(prompt=prompt, seed=seed)
image_data = response.generated_images[0].image_bytes
# Cache for 24 hours
redis_client.setex(cache_key, 86400, image_data)
return image_data
3. Límite de Tasa
from flask import Flask, request, jsonify
from flask_limiter import Limiter
app = Flask(__name__)
limiter = Limiter(app, key_func=lambda: request.headers.get("X-API-Key"))
@app.route("/generate", methods=["POST"])
@limiter.limit("10 per minute") # Ajustar según tu cuota
def generate():
# Tu lógica de generación
pass
4. Monitoreo y Registro
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def generate_with_logging(prompt):
logger.info(f"Generando imagen para la indicación: {prompt[:50]}...")
start_time = time.time()
try:
response = model.generate_images(prompt=prompt)
elapsed = time.time() - start_time
logger.info(f"Generado con éxito en {elapsed:.2f}s")
return response
except Exception as e:
elapsed = time.time() - start_time
logger.error(f"Fallo después de {elapsed:.2f}s: {e}")
raise
5. Webhook para Procesamiento Asíncrono
Para trabajos por lotes grandes, usa webhooks:
# Request with webhook
response = model.generate_images(
prompt="Generar 10 imágenes de productos",
number_of_images=10,
webhook_url="https://your-server.com/webhook/nano-banana"
)
# Your webhook handler
@app.route("/webhook/nano-banana", methods=["POST"])
def handle_webhook():
data = request.json
if data["status"] == "completed":
images = data["images"]
# Procesar imágenes completadas
elif data["status"] == "failed":
# Manejar el fallo
pass
return jsonify({"received": True})
Conclusión
La API de Nano Banana 2 ofrece una forma potente de integrar la generación de imágenes por IA en tus aplicaciones. Con soporte para múltiples lenguajes de programación, parámetros flexibles y un manejo robusto de errores, puedes construir desde simples generadores de imágenes hasta complejos flujos de trabajo de producción.
Puntos clave:
- Para empezar se requiere un proyecto de Google Cloud y una clave de API
- Los SDK de Python y JavaScript facilitan la integración
- Los parámetros avanzados como semillas e indicaciones negativas te dan un control preciso
- Apidog ayuda a probar y depurar tu integración con la API
- Las implementaciones en producción necesitan seguridad, caché, limitación de tasa y monitoreo
Comienza con los ejemplos básicos de esta guía, luego añade progresivamente características avanzadas a medida que te familiarices con la API.
Siguiente Paso:
