HiAPI
Blog

Tutorial

Cómo usar ideogram-v4.5 a través de la API de HiAPI: curl, Python y una solicitud que funciona

Oct 31, 2026
封面图:浅灰蓝底上多层半透明玻璃片交叠,折射出克制的蓝色条带,安静而具建筑感。

Qué te aporta ideogram-v4.5 en HiAPI

Cuando el texto dentro de una imagen realmente importa, ideogram-v4.5 es el modelo que debes elegir. Maquetas de pósteres, gráficos de logotipos, renderizados de packaging, tarjetas para redes sociales: cualquier escenario donde un titular mal escrito o un texto descriptivo borroso arruinaría el material es precisamente donde este modelo aporta valor. Si lo que quieres es generar texturas abstractas o paisajes fotográficos en los que nada necesita ser legible, los modelos de imagen de propósito general suelen ser más baratos y rápidos.

Este artículo es una guía de integración, no una reseña del modelo. Al terminar tendrás una solicitud que funciona, un cliente en Python que hace lo mismo y una función auxiliar reutilizable que se encarga de las partes en las que la gente suele equivocarse: el parámetro de relación de aspecto, el sondeo de tareas asíncronas y la obtención de la salida.

Hay algo que conviene interiorizar desde el principio: la generación de imágenes en HiAPI es una API de tareas asíncronas. Envías una solicitud, recibes un identificador y luego sondeas hasta que la tarea finaliza. El código que da por hecho que el cuerpo de la respuesta ya contiene la imagen no funcionará. Cada sección de este artículo gira en torno a ese patrón.

Antes de enviar la solicitud

Antes de la primera llamada necesitas cuatro cosas.

1. Clave de API

Crea una en la consola de tu cuenta de HiAPI y mantenla alejada del control de versiones. Expórtala como variable de entorno en lugar de pegarla en el script:

export HIAPI_API_KEY="your_key_here"

2. URL base

Todas las solicitudes se envían a la URL base de la API de HiAPI, añadiendo la ruta concreta del endpoint de generación. La documentación de la plataforma enumera las rutas actuales; si la documentación dice algo distinto, no codifiques de forma fija la ruta que hayas visto en un artículo de blog (incluido este).

3. Identificador del modelo

La cadena de modelo que pasas en el cuerpo de la solicitud identifica a ideogram-v4.5. Usa exactamente las mayúsculas y minúsculas que aparecen en la lista de modelos de la plataforma: los identificadores de modelo se comparan literalmente y la mínima desviación devuelve un error de validación en lugar de una sugerencia útil.

4. Referencia de parámetros

La página del modelo ideogram-v4.5 es la fuente autorizada de qué campos acepta el cuerpo de la solicitud: límite de longitud del prompt, relaciones de aspecto admitidas, formatos de salida y cualquier control de semilla o estilo. Léela antes de escribir código. Los parámetros que no aparecen allí pueden ignorarse en silencio o rechazarse, y adivinar los valores es la forma más habitual de perder tiempo depurando.

Con estas cuatro cosas listas, ya puedes enviar tu primera solicitud.

Una solicitud curl que funciona

A continuación tienes un ejemplo mínimo de envío. Si tu cuenta muestra valores distintos, sustituye la ruta del endpoint y el identificador del modelo según la documentación de la plataforma.

curl -X POST "$HIAPI_BASE_URL/<generation-path>" \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "ideogram-v4.5",
    "input": {
      "prompt": "A vintage travel poster for the Amalfi Coast, bold serif headline reading \"AMALFI\", warm sunset palette, grainy print texture"
    }
  }'

Qué hace cada parte:

  • Authorization: autenticación con bearer token. Que falte la cabecera o esté mal formada es la causa más común de un 401.
  • Content-Type: debe ser application/json. Algunos clientes HTTP no lo establecen automáticamente en las solicitudes POST, lo que provoca errores de análisis confusos en el servidor.
  • model: el identificador literal del modelo. Colócalo en el nivel superior del cuerpo de la solicitud tal como indica la documentación.
  • input.prompt: tu instrucción de generación. Como se muestra arriba, encierra entre comillas el texto que quieres que se renderice dentro de la imagen, de modo que el modelo lo trate como texto literal y no como descripción.
  • input.*: todos los demás parámetros de generación (relación de aspecto, formato, semilla, etc.) pertenecen a este objeto anidado, junto a prompt.

Un envío correcto devuelve un objeto JSON que contiene un identificador de tarea y un campo de estado. En esta respuesta no hay imagen: es el comportamiento esperado. Guarda el identificador; lo necesitarás en el paso de sondeo.

La misma llamada en Python

La versión en Python es una traducción uno a uno. Usamos requests y compartimos el mismo cuerpo de solicitud para que puedas comparar ambos lado a lado.

import os
import json
import requests

API_KEY = os.environ["HIAPI_API_KEY"]
BASE_URL = os.environ["HIAPI_BASE_URL"]
GEN_PATH = "/<generation-path>"  # confirm in platform docs

payload = {
    "model": "ideogram-v4.5",
    "input": {
        "prompt": (
            "A vintage travel poster for the Amalfi Coast, bold serif "
            'headline reading "AMALFI", warm sunset palette, grainy print texture'
        )
    },
}

response = requests.post(
    BASE_URL + GEN_PATH,
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
    },
    data=json.dumps(payload),
    timeout=30,
)
response.raise_for_status()

job = response.json()
print(job)

Dos decisiones deliberadas:

  • json.dumps en lugar de json= mantiene el formato de transporte visiblemente idéntico al ejemplo de curl. Ambos funcionan; escribirlo de forma explícita facilita comprobar lo que realmente envías al depurar.
  • timeout=30 solo para el envío. El envío es rápido; la generación no lo es. Nunca dejes que la llamada de envío herede un timeout corto pensado para el sondeo, o acabarás informando como fallidas tareas que funcionan correctamente.

El diccionario job impreso contiene el identificador de la tarea y su estado actual. Guarda el identificador en algún sitio: el bucle de sondeo depende de él.

Controlar la relación de aspecto y el formato de salida

La relación de aspecto y el formato de salida son parámetros del cuerpo de la solicitud, no endpoints separados. Van en el mismo objeto input que el prompt:

{
  "model": "ideogram-v4.5",
  "input": {
    "prompt": "...",
    "aspect_ratio": "<ratio from docs>",
    "output_format": "<format from docs>"
  }
}

La disciplina importante aquí es no adivinar los valores. Cada modelo de generación expone enumeraciones fijas de relaciones y formatos, y distintos modelos aceptan grafías diferentes: 16:9 frente a 16x9, png frente a PNG, etc. Pasar un valor que el modelo no admite suele producir un error de validación o, peor aún, una vuelta silenciosa a la salida predeterminada que parece un fallo de tu prompt.

Así que el flujo de trabajo es:

  1. Abre la página del modelo ideogram-v4.5 en la plataforma y copia literalmente la lista de relaciones de aspecto y la de formatos de salida admitidos.
  2. Coloca esos valores en una pequeña lista blanca dentro del código, para que las entradas no válidas fallen en el punto de llamada y no en la API.
  3. Usa por defecto una relación que coincida con tu maqueta posterior. Si la imagen va a ocupar un hueco de 1200×630 en una tarjeta para redes sociales, elige un valor cercano a esa proporción en lugar de generar un cuadrado y recortar contenido.

Las imágenes con mucho texto merecen una advertencia adicional: las relaciones extremas (banners ultrapanorámicos, pósteres ultraverticales) comprimen el espacio disponible para renderizar texto. Para los titulares que realmente necesitas que sean legibles, una relación horizontal o vertical de rango medio es más segura que una proporción panorámica extrema.

Gestionar tareas asíncronas y descargar el resultado

El ciclo de vida de una generación tiene tres pasos: enviar → sondear → obtener.

Enviar

Ya dominas este paso en las secciones anteriores. La respuesta te da un identificador de tarea y un estado, por ejemplo queued o processing.

Sondear

Sondea el endpoint de estado de la tarea con ese identificador hasta que el estado indique que ha finalizado. Dos reglas mantienen este proceso en orden:

  • Duerme entre sondeos. Empieza con aproximadamente un segundo y aplica un retroceso progresivo. Martillear el endpoint de estado no hará que la tarea termine antes y corre el riesgo de activar límites de velocidad.
  • Limita el tiempo de espera. Establece un número máximo de intentos o una fecha límite y, al superarla, lanza un error explícito en lugar de entrar en un bucle infinito.
import time

def wait_for_job(job_id, headers, base_url, status_path,
                 max_attempts=60, initial_delay=1.0, factor=1.5):
    delay = initial_delay
    for _ in range(max_attempts):
        r = requests.get(
            f"{base_url}{status_path}/{job_id}",
            headers=headers,
            timeout=30,
        )
        r.raise_for_status()
        data = r.json()
        status = data.get("status")
        if status in ("succeeded", "completed", "success"):
            return data
        if status in ("failed", "error", "cancelled"):
            raise RuntimeError(f"job {job_id} ended with status {status}: {data}")
        time.sleep(delay)
        delay *= factor
    raise TimeoutError(f"job {job_id} did not finish in time")

Consulta la documentación de la plataforma para obtener las cadenas de estado y la ruta de estado exactas de tu cuenta: haz coincidir con los valores de la documentación y trata cualquier estado no reconocido como todavía en ejecución, no como éxito.

Obtener

Cuando la tarea indica que ha finalizado, la respuesta incluye la ubicación de la salida (normalmente una URL). Descárgala con un GET normal y escribe los bytes en disco. La URL de salida puede tener caducidad, así que descárgala cuanto antes en lugar de guardar la URL para usarla más tarde. Todo lo necesario para escribir este bucle proviene de la estructura de la respuesta de envío: no hay una API separada de "obtener imagen" que aprender.

Encapsular en una función auxiliar reutilizable

Tres scripts independientes que reimplementan el sondeo son un problema de mantenimiento. Empaquétalo una sola vez.

import os, json, time, requests

class IdeogramClient:
    def __init__(self, base_url, api_key, gen_path, status_path,
                 poll_attempts=60, poll_factor=1.5):
        self.base_url = base_url.rstrip("/")
        self.gen_path = gen_path
        self.status_path = status_path
        self.poll_attempts = poll_attempts
        self.poll_factor = poll_factor
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json",
        }

    def generate(self, prompt, **params):
        body = {"model": "ideogram-v4.5", "input": {"prompt": prompt, **params}}
        r = requests.post(self.base_url + self.gen_path,
                          headers=self.headers,
                          data=json.dumps(body), timeout=30)
        r.raise_for_status()
        job = r.json()
        done = self._wait(job["id"])
        url = done["output"]["url"]  # confirm shape in docs
        return self._download(url)

    def _wait(self, job_id):
        delay = 1.0
        for _ in range(self.poll_attempts):
            r = requests.get(f"{self.base_url}{self.status_path}/{job_id}",
                             headers=self.headers, timeout=30)
            r.raise_for_status()
            data = r.json()
            if data.get("status") in ("succeeded", "completed", "success"):
                return data
            if data.get("status") in ("failed", "error", "cancelled"):
                raise RuntimeError(data)
            time.sleep(delay)
            delay *= self.poll_factor
        raise TimeoutError(job_id)

    def _download(self, url):
        r = requests.get(url, timeout=60)
        r.raise_for_status()
        return r.content

Usarlo requiere una sola llamada: img_bytes = IdeogramClient(...).generate("...", aspect_ratio="<from docs>"). Ajusta la forma de acceder a done["output"]["url"] y las cadenas de estado para que coincidan con la estructura de respuesta de la documentación: estos dos puntos son los que más probablemente necesiten ajustes según la cuenta.

Errores comunes y técnicas de depuración

La mayoría de los fallos de la primera semana encajan en cinco categorías.

401 / 403: autenticación. Falta la clave, tiene espacios por un copiar y pegar, o falta el prefijo Bearer . Imprime los cuatro primeros y los cuatro últimos caracteres de la clave que estás enviando realmente; el salto de línea final que arrastran los archivos de entorno es el culpable clásico.

400: JSON mal formado o campo desconocido. Si el cuerpo de la solicitud se monta concatenando cadenas, las comillas sin escapar del prompt rompen el JSON. Construye el cuerpo como un diccionario y serialízalo con json.dumps. Si el JSON se analiza correctamente, el siguiente sospechoso es un nombre de parámetro que el modelo no acepta: compara tus claves carácter por carácter con la página del modelo.

404 / modelo no encontrado. Normalmente es un identificador de modelo mal escrito o con mayúsculas y minúsculas incorrectas, o una ruta de endpoint obsoleta. Copia ambos desde la documentación de la plataforma, no de memoria ni de un tutorial antiguo.

429: límite de velocidad. Casi siempre se debe a un sondeo demasiado agresivo. Aumenta el retardo inicial de sondeo y el factor de retroceso. En el lado del envío, añade reintentos con jitter para respuestas 429 y 5xx, pero no reintentes errores de validación 4xx: fallarán de la misma manera todas las veces.

La tarea tiene éxito pero la imagen no se abre. Comprueba que estás descargando bytes y no una página JSON de error; llamar a raise_for_status() en el GET de descarga detecta la mayoría de estos casos. Verifica también que tratas la URL de descarga como de vida corta en lugar de cachearla entre sesiones.

Si tienes dudas, registra el cuerpo completo de la respuesta y el código de estado de cada llamada de la cadena: envío, cada sondeo y descarga. La API suele decir claramente qué ha fallado; el problema suele ser que nunca lo miramos.

Con un envío funcional, un bucle de sondeo y un manejo de errores razonable, ideogram-v4.5 se integra en una tubería real igual que cualquier otra llamada a un modelo de HiAPI.

Artículos relacionados

Ver todos los artículos →

Empieza a crear con artefactos de IA persistentes

Consigue tu API key y llama a modelos de imagen, vídeo y audio a través de una única API basada en tasks.

Leer la documentación de la API