Saltar al contenido principal

API de Nano Banana Pro: petición JSON, YAML y guardado de imágenes

El modelo Pro es gemini-3-pro-image. Envía JSON al endpoint oficial de Interactions, convierte antes la configuración de tu aplicación y guarda los bloques de imagen por su MIME. Para PDF, separa lectura documental y generación visual.

LaoZhang AI TeamPublicadoActualizado 12 min de lectura
En esta página
Del brief JSON o YAML al contrato elegido y al guardado de todas las imágenes

Para usar la API de Nano Banana Pro, el identificador oficial es gemini-3-pro-image. Una integración nueva con Google puede partir de POST https://generativelanguage.googleapis.com/v1beta/interactions, con una clave de Gemini en la cabecera x-goog-api-key. El cuerpo lleva model, input y response_format; las imágenes de la respuesta se recuperan recorriendo steps. Es el contrato de la guía oficial de generación de imágenes, consultada el 7 de octubre de 2026.

Puedes mantener un brief en JSON o YAML, pero esos campos pertenecen a tu aplicación: hay que convertirlos al JSON que acepta Google. Y si partes de un PDF, primero necesitas leer y verificar el documento con un modelo compatible; Pro declara entradas de texto e imagen, no PDF. A continuación tienes los archivos y pasos necesarios para ambas tareas.

La primera petición oficial: Pro, 16:9 y 2K

Guarda este cuerpo como peticion.json. Solicita una imagen JPEG para una ficha de producto; no depende de un SDK ni de un helper externo.

json
{
  "model": "gemini-3-pro-image",
  "input": [
    {
      "type": "text",
      "text": "Crea una fotografía de estudio de una taza de cerámica azul mate, sin marca. Fondo marfil, luz suave lateral y espacio libre a la derecha para el diseño de una ficha de producto. No añadas texto, precios ni logotipos."
    }
  ],
  "response_format": {
    "type": "image",
    "mime_type": "image/jpeg",
    "aspect_ratio": "16:9",
    "image_size": "2K"
  },
  "store": false
}

Para enviarlo necesitas curl, una clave válida de Google disponible en el backend como GEMINI_API_KEY y un proyecto con acceso y facturación aplicables. Esta orden realiza una llamada que puede generar cargos y guarda el cuerpo de respuesta, incluso cuando contiene un error:

bash
curl --silent --show-error --fail-with-body \
  "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @peticion.json \
  --output respuesta.json

La clave es de Google; una clave de una pasarela no sirve por compartir el nombre del modelo. Según la política actual de claves, las nuevas claves de AI Studio son de autenticación por defecto desde el 28 de mayo de 2026. Las claves estándar restringidas siguen funcionando; las estándar sin restricciones se rechazan. No hay motivo para reemplazar todas las claves estándar por su nombre ni para rotarlas ante cualquier error.

store: false evita guardar esa interacción para recuperarla como conversación en el servidor y no permite usarla después mediante previous_interaction_id. No equivale a ZDR ni elimina los registros de tu aplicación. Si necesitas continuidad, elige entre historial gestionado por el servidor y enviar el historial completo en cada petición; previous_interaction_id no hereda automáticamente herramientas, instrucciones de sistema ni configuración de generación. La documentación de Interactions explica esas condiciones. Para un requisito de privacidad más amplio, consulta cómo verificar retención y ZDR por ruta.

Los ejemplos de esta página se han comprobado sin conexión: sintaxis, validación de tipos, construcción del cuerpo y extracción de respuestas sintéticas. No se ejecutó una llamada al modelo ni se midieron calidad, latencia o cargos reales.

Guarda todas las imágenes con la extensión de su MIME

Guarda el siguiente programa como guardar_imagenes.py y ejecútalo después de obtener respuesta.json:

python
import base64
import binascii
import json
import sys
from pathlib import Path

EXTENSIONES = {
    "image/png": ".png",
    "image/jpeg": ".jpg",
    "image/webp": ".webp",
}


def guardar(respuesta, directorio):
    if "error" in respuesta:
        raise ValueError(f"La API devolvió un error: {respuesta['error']}")
    imagenes = []
    for paso in respuesta.get("steps", []):
        if paso.get("type") != "model_output":
            continue
        for bloque in paso.get("content", []):
            if bloque.get("type") != "image":
                continue
            mime = bloque.get("mime_type")
            if mime not in EXTENSIONES:
                raise ValueError(f"MIME de imagen no admitido: {mime!r}")
            datos = bloque.get("data")
            if not isinstance(datos, str) or not datos:
                raise ValueError("El bloque de imagen no contiene base64.")
            try:
                contenido = base64.b64decode(datos, validate=True)
            except (binascii.Error, ValueError) as error:
                raise ValueError("Base64 de imagen inválido.") from error
            if not contenido:
                raise ValueError("La imagen está vacía.")
            imagenes.append((EXTENSIONES[mime], contenido))
    if not imagenes:
        raise ValueError("No hay imágenes finales. Revisa la respuesta completa.")
    destino = Path(directorio)
    destino.mkdir(parents=True, exist_ok=False)
    rutas = []
    for numero, (extension, contenido) in enumerate(imagenes, 1):
        ruta = destino / f"imagen-{numero:02d}{extension}"
        ruta.write_bytes(contenido)
        rutas.append(str(ruta))
    return rutas


if __name__ == "__main__":
    respuesta = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
    for ruta in guardar(respuesta, sys.argv[2]):
        print(ruta)
bash
python3 guardar_imagenes.py respuesta.json salida-taza-001

El directorio debe ser nuevo para evitar sobrescribir una entrega anterior. El programa valida los bloques antes de escribir y conserva los bytes sin convertirlos: pedir JPEG no justifica poner .jpg a una respuesta PNG. El MIME devuelto decide la extensión; este ejemplo no comprueba internamente que los bytes formen una imagen válida. En producción, añade la apertura con tu biblioteca de imágenes y la comprobación de dimensiones antes de dar el recurso por terminado.

El formato documentado de Interactions distingue pasos model_output y contenido de imagen. El atajo del SDK output_image devuelve únicamente la última imagen; para guardar todas hay que recorrer los bloques, sin volver a guardar esa última imagen mediante el atajo. Tampoco debes tratar contenido de pensamiento como entrega final. Un HTTP 200 o una descripción de la escena, por sí solos, no prueban que haya una imagen utilizable.

De la configuración JSON o YAML al cuerpo de Google

Un brief estructurado facilita revisar qué se quiere crear. No activa Structured Output: la ficha de Pro indica que esa capacidad no está admitida. JSON es aquí el formato de transporte y, por separado, una forma de organizar datos dentro de tu aplicación.

Guarda este ejemplo como config.json. La ruta está fijada a Google Interactions para que no se pueda cambiar accidentalmente de proveedor al editar la escena.

json
{
  "ruta": "google_interactions",
  "modelo": "gemini-3-pro-image",
  "objetivo": "Fotografía de producto para una ficha de una tienda de cerámica",
  "escena": "Una taza azul mate, fondo marfil, luz suave lateral y espacio a la derecha",
  "conservar": ["color azul", "acabado mate", "forma de la taza"],
  "excluir": ["texto", "precios", "logotipos"],
  "salida": {
    "mime_type": "image/jpeg",
    "aspect_ratio": "16:9",
    "image_size": "2K"
  },
  "guardar_historial": false
}

La misma configuración se puede editar como config.yaml:

yaml
ruta: google_interactions
modelo: gemini-3-pro-image
objetivo: Fotografía de producto para una ficha de una tienda de cerámica
escena: Una taza azul mate, fondo marfil, luz suave lateral y espacio a la derecha
conservar:
  - color azul
  - acabado mate
  - forma de la taza
excluir:
  - texto
  - precios
  - logotipos
salida:
  mime_type: image/jpeg
  aspect_ratio: "16:9"
  image_size: "2K"
guardar_historial: false

Pon entre comillas la relación de aspecto y mantén false como booleano, no como cadena. El YAML no se envía a Google: primero se carga, se validan sus tipos y se construye una petición JSON. Guarda este programa completo como crear_peticion.py. Para JSON solo necesita Python 3; la rama YAML necesita que PyYAML ya esté disponible en tu entorno.

python
import base64
import json
import sys
from pathlib import Path

RATIOS = {"1:1", "2:3", "3:2", "3:4", "4:3", "4:5", "5:4",
          "9:16", "16:9", "21:9"}
TAMANOS = {"1K", "2K", "4K"}
MIMES = {"image/png", "image/jpeg", "image/webp"}


def claves(valor, esperadas, nombre):
    if not isinstance(valor, dict) or set(valor) != set(esperadas):
        raise ValueError(f"Campos incorrectos en {nombre}.")


def texto(valor, nombre):
    if not isinstance(valor, str) or not valor.strip():
        raise ValueError(f"{nombre} debe ser texto no vacío.")
    return valor.strip()


def lista_textos(valor, nombre):
    if not isinstance(valor, list):
        raise ValueError(f"{nombre} debe ser una lista.")
    return [texto(item, nombre) for item in valor]


def construir(config, referencia=None):
    claves(config, {"ruta", "modelo", "objetivo", "escena", "conservar",
                    "excluir", "salida", "guardar_historial"}, "config")
    if config["ruta"] != "google_interactions":
        raise ValueError("Este programa solo construye Google Interactions.")
    if config["modelo"] != "gemini-3-pro-image":
        raise ValueError("Este ejemplo requiere el modelo Pro estable.")
    if type(config["guardar_historial"]) is not bool:
        raise ValueError("guardar_historial debe ser un booleano.")
    salida = config["salida"]
    claves(salida, {"mime_type", "aspect_ratio", "image_size"}, "salida")
    for campo, opciones in [("mime_type", MIMES), ("aspect_ratio", RATIOS),
                            ("image_size", TAMANOS)]:
        valor = salida[campo]
        if not isinstance(valor, str) or valor not in opciones:
            raise ValueError(f"Valor no admitido en salida.{campo}.")
    conservar = lista_textos(config["conservar"], "conservar")
    excluir = lista_textos(config["excluir"], "excluir")
    instrucciones = [texto(config["objetivo"], "objetivo"),
                     texto(config["escena"], "escena")]
    if conservar:
        instrucciones.append("Conserva: " + ", ".join(conservar) + ".")
    if excluir:
        instrucciones.append("No incluyas: " + ", ".join(excluir) + ".")
    entrada = [{"type": "text", "text": " ".join(instrucciones)}]
    if referencia is not None:
        archivo = Path(referencia)
        mime = {".png": "image/png", ".jpg": "image/jpeg",
                ".jpeg": "image/jpeg", ".webp": "image/webp"}.get(
                    archivo.suffix.lower())
        if mime is None:
            raise ValueError("La referencia debe ser PNG, JPEG o WebP.")
        contenido = archivo.read_bytes()
        if not contenido:
            raise ValueError("La referencia está vacía.")
        entrada.append({"type": "image", "mime_type": mime,
                        "data": base64.b64encode(contenido).decode("ascii")})
    return {"model": config["modelo"], "input": entrada,
            "response_format": {"type": "image", **salida},
            "store": config["guardar_historial"]}


def cargar(ruta):
    archivo = Path(ruta)
    contenido = archivo.read_text(encoding="utf-8")
    if archivo.suffix.lower() in {".yaml", ".yml"}:
        try:
            import yaml
        except ImportError as error:
            raise SystemExit("Para YAML necesitas PyYAML en este entorno.") from error
        return yaml.safe_load(contenido)
    return json.loads(contenido)


if __name__ == "__main__":
    referencia = sys.argv[2] if len(sys.argv) == 3 else None
    peticion = construir(cargar(sys.argv[1]), referencia)
    Path("peticion.json").write_text(
        json.dumps(peticion, ensure_ascii=False, indent=2), encoding="utf-8")
bash
python3 crear_peticion.py config.json
# Alternativa con la misma configuración en YAML:
python3 crear_peticion.py config.yaml
# Edición con una imagen local cuyo formato coincida con su extensión:
python3 crear_peticion.py config.json taza.png

Después utiliza la orden curl de la primera sección y guardar_imagenes.py. Así quedan conectados configuración, solicitud y archivos finales. El constructor rechaza campos adicionales y valores de otro tipo; no convierte silenciosamente "false" en verdadero ni transforma una lista de ratios en una cadena. La referencia local se codifica como base64 sin el prefijo data:image/...; su MIME debe corresponder al archivo real.

Qué puedes pedir: tamaños, proporciones y referencias

Pro admite 1K, 2K y 4K, con la K en mayúscula, y los diez ratios incluidos en el constructor. 4K no significa siempre 4096 × 4096: para 16:9, la tabla oficial indica 1376 × 768 en 1K, 2752 × 1536 en 2K y 5504 × 3072 en 4K. Es una clasificación de salida que cambia con la relación de aspecto. Tamaños y proporciones de Pro.

La guía admite hasta 14 referencias en total, con apartados para seis objetos, cinco personajes y tres referencias de estilo; otra limitación menciona cinco imágenes de alta fidelidad. Esos ámbitos no garantizan fidelidad equivalente para cualquier conjunto de catorce imágenes. Empieza por las referencias que realmente cambian la entrega y comprueba el resultado. Pedir «tres variantes» tampoco garantiza recibir exactamente tres imágenes.

Pro mantiene el razonamiento activado; no copies la opción para desactivarlo de ejemplos de otros modelos. Tampoco incorpores ratios exclusivos de Flash, seed, sampler o parámetros de Stable Diffusion por aparecer en una configuración genérica. La documentación de un campo y su disponibilidad para una ruta y modelo concretos son comprobaciones distintas. Las imágenes generadas incluyen SynthID, según la guía de Google; esto no verifica que un texto o una cifra dentro de la imagen sea correcto.

PDF: lectura documental y generación en dos fases

La ficha de gemini-3-pro-image declara entrada Image/Text y salida Image/Text. Para extraer un catálogo PDF, usa primero la ruta documentada de procesamiento de documentos, cuyo ejemplo actual emplea gemini-3.8-flash. Después pasa a Pro instrucciones verificadas y, cuando el diseño lo requiera, páginas convertidas en imágenes.

1. Construye la solicitud de lectura y comprueba las páginas

Guarda este programa como crear_lectura_pdf.py. Recibe la ruta a un PDF autorizado y genera lectura-pdf.json sin subirlo:

python
import base64
import json
import sys
from pathlib import Path

pdf = Path(sys.argv[1]).read_bytes()
if not pdf or not pdf.startswith(b"%PDF-"):
    raise SystemExit("El archivo no parece un PDF válido.")
if len(pdf) > 50_000_000:
    raise SystemExit("Reduce el archivo antes de enviarlo.")
peticion = {
    "model": "gemini-3.8-flash",
    "input": [
        {"type": "document", "mime_type": "application/pdf",
         "data": base64.b64encode(pdf).decode("ascii")},
        {"type": "text", "text": (
            "Extrae solo datos necesarios para una ficha visual del producto: "
            "nombre, color, material, texto literal de etiqueta y restricciones. "
            "Indica para cada dato el número de página del PDF y su cita. "
            "Separa los datos ausentes o ambiguos; no los completes."
        )}
    ],
    "store": False
}
Path("lectura-pdf.json").write_text(
    json.dumps(peticion, ensure_ascii=False, indent=2), encoding="utf-8")
bash
python3 crear_lectura_pdf.py catalogo.pdf
curl --silent --show-error --fail-with-body \
  "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @lectura-pdf.json \
  --output lectura-respuesta.json

No pases esta respuesta a Pro automáticamente. Lee los bloques de texto de steps[].content[] dentro de model_output, contrasta las citas con el PDF y conserva una ficha de revisión, por ejemplo: «página 3, taza azul mate, confirmado» y «página 8, etiqueta literal, confirmado». Si una cifra, un acento o una restricción son ambiguos, detén esa parte de la entrega hasta aclararla. Pedir citas ayuda a revisar; no asegura que sean correctas.

La ruta documental admite hasta 50 MB o 1.000 páginas, sujeta también al contexto total del modelo. El script aplica un límite conservador de 50.000.000 bytes y no cuenta páginas ni valida todo el PDF. Varios documentos y el texto adicional comparten contexto. Esos límites corresponden al procesamiento documental, no a la entrada directa de Pro. Límites de documentos.

2. Entrega a Pro el brief verificado y la referencia necesaria

Construye config.json con los datos que acabas de confirmar, usando exactamente los campos de la sección de configuración. Por ejemplo, sustituye objetivo por «Ficha visual de la taza descrita en la página 3 del catálogo» y conservar por sus características verificadas. Guarda por separado la ficha de revisión y las páginas de origen: son trazabilidad de tu aplicación, no campos nuevos de la API.

Si necesitas conservar la apariencia del producto o del diseño, renderiza esa página. Esta orden requiere las herramientas Poppler ya disponibles y crea pagina-3.png:

bash
pdftoppm -f 3 -l 3 -singlefile -png -r 150 catalogo.pdf pagina-3
python3 crear_peticion.py config.json pagina-3.png

Envía ahora peticion.json con la orden inicial y guarda las imágenes de respuesta.json. Si basta con los datos textuales, ejecuta crear_peticion.py config.json sin referencia. No conviertas un catálogo entero en una lista indiscriminada de imágenes: selecciona la página que cumple una función concreta y registra recorte, resolución y origen. Para material sensible, aprueba el tratamiento de datos antes de enviarlo a cualquiera de las dos rutas.

Google generateContent y proveedores tienen contratos distintos

generateContent sigue plenamente admitido; Interactions es la recomendación de Google para proyectos nuevos, según su documentación de transición. Puedes conservar una integración existente, pero cambia conjuntamente el cuerpo y el lector de respuesta.

RutaCredencial y campos de peticiónDónde se recupera la imagen
Google InteractionsClave Google, x-goog-api-key; input, response_formatsteps de tipo model_output, bloques image con data y mime_type
Google generateContentClave Google, x-goog-api-key; contents[].parts[], generationConfigcandidates[].content.parts[], inlineData.data y inlineData.mimeType
LaoZhang, ruta nativa compatibleClave del proveedor, Bearer; contents, generationConfig.imageConfigPartes de candidates con inlineData, según su documentación
LaoZhang, Chat CompletionsClave del proveedor, Bearer; messages, model, stream: falseFormato documentado por el proveedor para esa ruta

Para reconocer una solicitud de compatibilidad, este es el cuerpo básico de texto e imagen de generateContent; no lleva input ni response_format de Interactions:

json
{
  "contents": [{
    "parts": [{"text": "Crea una fotografía de una taza azul mate sobre fondo marfil."}]
  }],
  "generationConfig": {
    "responseModalities": ["TEXT", "IMAGE"]
  }
}

El endpoint oficial es https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-image:generateContent. La guía de compatibilidad y la referencia de la API muestran opciones de imagen con diferencias entre ejemplos y clientes. Para el recorrido completo con tamaño y proporción de esta página, utiliza el contrato explícito de Interactions; no construyas un cuerpo híbrido a partir de ambas guías. El programa guardar_imagenes.py tampoco es un lector de candidates.

Si generateContent rechaza una referencia con Unsupported file URI type, consulta cómo corregir el valor de archivo y conservar la edición. Una URL HTTPS admitida en esa ruta no implica que Pro tenga URL Context ni que el mismo campo funcione en Interactions.

Cuándo usar la ruta de LaoZhang

Si tu aplicación ya utiliza una clave y facturación de LaoZhang y necesita proporción personalizada o 2K/4K, su documentación de Pro indica la ruta https://api.laozhang.ai/v1beta/models/gemini-3-pro-image:generateContent, con Bearer del proveedor y generationConfig.imageConfig. Su ruta https://api.laozhang.ai/v1/chat/completions está documentada para generación 1:1/1K; no traslades a ella el objeto response_format de Google para forzar 4K.

Aviso: laozhang.ai es un servicio propio. Sus precios son nuestra tarifa, no una comparación independiente.

La documentación pública del proveedor, fechada el 24 de septiembre y consultada el 7 de octubre de 2026, anuncia 0,09 USD por llamada y cobro una vez por HTTP 200, incluso sin imagen. Confirma el precio vigente en su consola antes de elegirlo por coste. Ese importe es una tarifa publicada del proveedor, no una factura observada ni el precio oficial de Google. Si necesitas el contrato directo de Google, empieza con la ruta oficial mostrada arriba; si necesitas una pasarela, verifica además su respuesta, límites y tratamiento de datos para tu uso.

Comprobación del contrato, respuesta de imagen y cobro del proveedor

Precio, claves y cuota: calcula la entrega, no solo la petición

En la tabla oficial de precios, Pro no tiene una fila de API gratuita. En Standard, la salida de imagen cuesta 120 USD por millón de tokens: 1.120 tokens para 1K/2K equivalen a 0,1344 USD por imagen —la tabla muestra 0,134 USD— y 2.000 tokens para 4K equivalen a 0,24 USD. A esto pueden sumarse entrada, texto o razonamiento de salida, búsquedas y otros cargos aplicables. No confundas una prueba de AI Studio con una asignación gratuita de API Pro.

Por ejemplo, cien imágenes de 2K representan 13,44 USD solo de salida de imagen Standard, suponiendo que cada llamada produzca una y no haya repeticiones. El coste por imagen aprovechable aumenta si parte de los resultados debe descartarse. El ejemplo no estima una factura completa.

Batch publica una tarifa de salida de imagen inferior, pero necesita su ruta propia: no existe un endpoint documentado /interactions/batch en las fuentes consultadas. Además, la ficha del modelo marca Flex y Priority como no admitidos mientras la tabla de precios contiene filas para ellos. Esa discrepancia impide recomendarlos como opciones disponibles para tu cuenta solo por su precio. Precios y capacidades de Pro.

Los límites de Google se aplican por proyecto, no por clave. Crear varias claves del mismo proyecto no multiplica RPM, TPM, RPD ni el límite de imágenes por minuto. Revisa los valores efectivos de tu proyecto; los ejemplos de niveles no son tu cuota actual. Límites oficiales.

Distinción entre clave, facturación y cuota del proyecto

Cómo diagnosticar errores sin repetir una generación a ciegas

Primero lee el cuerpo del error, además del estado HTTP. En Interactions, el campo error.code distingue causas que requieren acciones diferentes. Esta tabla se basa en la referencia de errores; un proveedor puede usar otro formato.

Estado o códigoPrimera comprobaciónSiguiente acción
400, invalid_request o parameter_unknownJSON final, nombres, tipos y modelo de la rutaReduce al cuerpo inicial; quita campos de tu configuración que no se hayan transformado
400, failed_preconditionMensaje de condición pendiente, por ejemplo facturaciónResuelve esa condición; repetir el mismo cuerpo no la corrige
401, authenticationEmisor de la clave y cabeceraComprueba que la credencial corresponde al endpoint, sin mostrarla en los registros
402, payment_requiredEstado de pago indicado por el servicioDetén los reintentos automáticos
403, permission_deniedPermiso exigido por el mensajeDistingue autorización de autenticación y revisa el ámbito afectado
404, model_not_found o not_foundIdentificador, versión y endpointUsa el Pro estable; no des por vigente un alias preview de otro proveedor
429rate_limit_exceeded, quota_exceeded o too_many_requestsIdentifica si falta cuota o sobra concurrencia antes de aplicar esperas
500, 503 o 504Error transitorio, capacidad o tiempo de esperaUsa reintentos limitados con espera y variación aleatoria; comprueba antes si existe resultado o ID recuperable
Sin imagen o bloqueo de contenidoBloques de respuesta y motivo de seguridadConserva el diagnóstico; no reduzcas controles de seguridad como solución

La lista oficial de retiradas sitúa la transición del preview de Pro al estable en junio de 2026; no anuncia el cierre de gemini-3-pro-image. La presencia de un modelo nuevo de la familia no cambia el identificador Pro de este tutorial.

Para investigar, registra hora, endpoint, modelo, tamaño solicitado, estado, código, identificador de petición si aparece y número de intentos. Protege el contenido y las credenciales de esos registros. Un timeout puede dejar una generación ya iniciada; reenviar inmediatamente puede duplicar trabajo y coste. La política de fallos o reembolsos debe comprobarse en la ruta que cobra, sin inferir que un 5xx siempre es gratuito.

Preguntas frecuentes

¿Puedo enviar el YAML directamente a Nano Banana Pro?

No en el contrato oficial de esta guía. Carga el YAML en tu aplicación, valida sus tipos y conviértelo a JSON con model, input y response_format. Los campos de escena o de negocio no son parámetros de Google.

¿Un prompt JSON obliga a Pro a devolver JSON válido?

No. El formato JSON de una petición y Structured Output son funciones distintas; la ficha de Pro marca Structured Output como no admitido. El brief de esta página se convierte en instrucciones de texto para generar imágenes.

¿Puedo usar un PDF como imagen de referencia sin convertirlo?

Pro declara entrada de texto e imagen, no PDF. Lee el documento con un modelo compatible, comprueba los datos y renderiza solo las páginas necesarias si precisas una referencia visual. La guía documental no amplía por sí sola las entradas de Pro.

¿Por qué solo se guarda una imagen aunque haya varias?

Puede que estés usando output_image, que da la última, o que solo leas el primer bloque. Recorre todos los pasos finales model_output y sus bloques image, como hace el programa de guardado. No sumes además el atajo del SDK, porque duplicarías esa última imagen.

¿4K siempre produce una imagen cuadrada de 4096 píxeles?

No. La proporción determina las dimensiones; Google documenta 5504 × 3072 para Pro 16:9 a 4K. Comprueba las dimensiones del archivo entregado si tu diseño necesita una medida exacta. Tabla oficial de tamaños.

¿Crear otra API key elimina el error 429?

No cuando ambas claves pertenecen al mismo proyecto: comparten sus límites. Identifica la causa en el cuerpo del error y ajusta concurrencia o cuota según corresponda. Límites por proyecto.

Fuentes11

Páginas externas que cita esta guía, en el orden en que aparecen. Última actualización: 7 oct 2026.

  1. 1.guía oficial de generación de imágenesai.google.dev/gemini-api/docs/image-generation
  2. 2.política actual de clavesai.google.dev/gemini-api/docs/api-key
  3. 3.documentación de Interactionsai.google.dev/gemini-api/docs/interactions-overview
  4. 4.ficha de Proai.google.dev/gemini-api/docs/models/gemini-3-pro-image
  5. 5.ruta documentada de procesamiento de documentosai.google.dev/gemini-api/docs/document-processing
  6. 6.guía de compatibilidadai.google.dev/gemini-api/docs/generate-content/image-generation
  7. 7.referencia de la APIai.google.dev/api/generate-content
  8. 8.tabla oficial de preciosai.google.dev/gemini-api/docs/pricing
  9. 9.Límites oficialesai.google.dev/gemini-api/docs/rate-limits
  10. 10.referencia de erroresai.google.dev/gemini-api/docs/api-errors
  11. 11.lista oficial de retiradasai.google.dev/gemini-api/docs/deprecations