HiAPI
Blog

Tutorial

Cómo usar grok-imagine de imagen a imagen a través de la API de hiapi: curl, Python y una solicitud funcional

Jul 11, 2026
Cómo usar grok-imagine de imagen a imagen a través de la API de hiapi: curl, Python y una solicitud funcional

grok-imagine/image-to-image recibe una o varias imágenes de referencia y un prompt de texto, y devuelve una imagen editada: puedes cambiar el estilo de una foto de producto, sustituir el fondo o fusionar hasta tres imágenes de referencia en una sola salida. En hiapi se ejecuta mediante la API unificada de tareas: crear la tarea, hacer polling (o recibir un callback) y descargar el resultado. Esta guía recorre la estructura exacta de la solicitud y ofrece ejemplos de curl y Python listos para copiar, pegar y usar directamente.

Qué vas a construir + requisitos previos

Objetivo: enviar una imagen de referencia y un prompt, obtener la URL de una imagen editada y descargarla — primero de forma interactiva mediante polling, y después con una versión de producción basada en callbacks.

Solo necesitas una cosa: una clave de API de hiapi. Obténla en tu panel de control; tiene el aspecto de sk-... y se incluye en cada llamada dentro de la cabecera Authorization: Bearer.

Tus imágenes de referencia deben ser URLs de acceso público (el modelo las obtiene del lado del servidor), así que primero alójalas en tu CDN o en tu almacenamiento de objetos.

Ejemplo mínimo funcional (curl)

Crear la tarea:

curl -X POST https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-imagine/image-to-image",
    "input": {
      "prompt": "Turn this product photo into a clean studio shot on a seamless white background with soft shadows",
      "image_urls": ["https://your-cdn.com/product.jpg"]
    }
  }'

Hay dos campos obligatorios —prompt e image_urls— y con eso ya tienes una solicitud completa. La respuesta incluye el ID de la tarea bajo data.taskId:

{
  "data": {
    "taskId": "<task-id>"
  }
}

Consultar el resultado (polling):

curl https://api.hiapi.ai/v1/tasks/<task-id> \
  -H "Authorization: Bearer sk-<your-key>"

Mientras la tarea se ejecuta, data.status informa del progreso. Cuando pasa a success, la URL de la imagen está en data.output[0].url. Si pasa a fail, data.error contiene el código de error y el mensaje.

Un detalle importante: las URLs de salida están firmadas y caducan (el payload incluye expireAt). Descarga el archivo en cuanto la tarea tenga éxito; nunca almacenes ni enlaces en caliente la URL de salida original.

curl -o result.png "<data.output[0].url>"

El mismo ejemplo en Python

import time
import requests

API = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": "Bearer sk-<your-key>"}

payload = {
    "model": "grok-imagine/image-to-image",
    "input": {
        "prompt": (
            "Turn this product photo into a clean studio shot "
            "on a seamless white background with soft shadows"
        ),
        "image_urls": ["https://your-cdn.com/product.jpg"],
        "aspect_ratio": "auto",
        "resolution": "1k",
        "output_format": "png",
    },
}

# 1. Create the task
resp = requests.post(API, json=payload, headers=HEADERS, timeout=60)
resp.raise_for_status()
task_id = resp.json()["data"]["taskId"]
print("task:", task_id)

# 2. Poll until it reaches a terminal state
while True:
    task = requests.get(f"{API}/{task_id}", headers=HEADERS, timeout=30).json()["data"]
    if task["status"] == "success":
        image_url = task["output"][0]["url"]
        break
    if task["status"] == "fail":
        raise RuntimeError(f"task failed: {task.get('error')}")
    time.sleep(5)

# 3. Download immediately — output URLs expire
with open("result.png", "wb") as f:
    f.write(requests.get(image_url, timeout=120).content)
print("saved result.png")

Esquema de entrada completo

Campo Obligatorio Tipo Descripción
prompt ✅ string Qué cambiar / aspecto objetivo
image_urls ✅ array de URLs 1–3 imágenes de referencia, deben ser de acceso público
aspect_ratio opcional enum auto, 2:1, 20:9, 19.5:9, 16:9, 4:3, 3:2, 1:1, 2:3, 3:4, 9:16, 9:19.5, 9:20, 1:2
resolution opcional enum 1k o 2k — en minúsculas
output_format opcional enum jpeg, png o webp

El esquema es estricto: cualquier campo que no reconozca se rechaza con un 400. No hay size, ni seed, ni n: si estás portando código de un modelo que usa dimensiones en píxeles (por ejemplo, size: "1024x1024"), aquí debes usar aspect_ratio + resolution. Cada tarea devuelve una imagen; para obtener variantes, envía varias tareas.

Múltiples imágenes de referencia: hasta 3 imágenes de entrada

image_urls acepta hasta tres imágenes de referencia y el modelo las fusiona; por ejemplo, una foto de producto más una imagen de fondo y una imagen de referencia de estilo. Si envías más de tres, la API rechaza directamente la solicitud:

invalid input: image_urls: maxItems: got 4, want 3

Coloca en primer lugar la imagen más importante (normalmente el sujeto) y especifica en el prompt qué aporta cada imagen de referencia.

Relación de aspecto automática

aspect_ratio: "auto" hace que el modelo deduzca la proporción de salida a partir de tu imagen de referencia en lugar de forzar un formato fijo; es el valor predeterminado adecuado para fotos de producto y para ediciones en las que quieres conservar la composición. Establece una proporción explícita solo cuando el caso de uso lo exija (por ejemplo, 9:16 para un hueco de story o 16:9 para un banner principal).

Consideraciones para producción

Usar callbacks en lugar de polling

Para cargas por lotes o del lado del servidor, omite el bucle de polling: registra un callback al crear la tarea y hiapi enviará el resultado final por POST a tu endpoint:

{
  "model": "grok-imagine/image-to-image",
  "input": {
    "prompt": "...",
    "image_urls": ["https://your-cdn.com/product.jpg"]
  },
  "callback": {
    "url": "https://your-server.com/hooks/hiapi",
    "when": "final"
  }
}

when solo admite "final": recibirás una llamada cuando la tarea llegue a success o fail, no recibirás eventos de progreso intermedios.

Regla general: polling para herramientas interactivas (hay un usuario esperando; un bucle con sleep de 5 segundos está bien) y callbacks para pipelines (hay decenas de tareas en ejecución; no querrás tener un poller por tarea). Tu manejador de callbacks debe descargar la salida de inmediato: la URL que recibe caduca igual que las demás.

Idempotencia y reintentos

La API de tareas separa el "envío" del "resultado", lo que hace que los reintentos seguros sean sencillos:

  • Persiste el taskId en el momento en que create lo devuelve. Si tu proceso se cae después, recupera consultando el ID almacenado; no lo vuelvas a crear.
  • Reintenta solo cuando la llamada a create falle y no haya devuelto un taskId (error de red, 5xx). Reenviar una solicitud que ya devolvió un ID genera una segunda tarea facturada por separado.
  • Trata status: "fail" como estado terminal. Corrige la entrada (o redirige a un plan alternativo) y envía una nueva tarea; las tareas fallidas no se reinician.

Errores frecuentes

Lo que ves Significado Cómo solucionarlo
401 — permission_denied Clave incorrecta, o la clave no tiene acceso a este modelo Revisa la clave en el panel de control
400 INVALID_REQUEST — missing required field "prompt" / "image_urls" Falta una entrada obligatoria Ambos campos son obligatorios
400 INVALID_REQUEST — additional properties '...' not allowed Campo desconocido (por ejemplo, size, seed, n) Esquema estricto: usa solo los campos de la tabla anterior
400 INVALID_REQUEST — image_urls: maxItems Más de 3 imágenes de referencia Reduce a 3
404 — task not found taskId incorrecto en el GET o perteneciente a otra cuenta Revisa el ID almacenado
status: "fail" durante el polling Aceptada pero la generación falló Lee data.error, ajusta la entrada y vuelve a enviar

Ten en cuenta que el fallo de autenticación es un 401 con "code": "permission_denied" en el cuerpo del error; conviene hacer coincidir ese código explícitamente, ya que también cubre el caso de una clave que existe pero no tiene acceso a este modelo.

Siguientes pasos

Preguntas frecuentes

¿Cuántas imágenes de referencia puedo enviar? Hasta 3 en image_urls. La API rechaza cualquier cantidad mayor (maxItems: got N, want 3).

¿Puedo establecer el tamaño de salida en píxeles? No. No hay campo size: controlas la forma con aspect_ratio (14 valores enum) y la nitidez con resolution (1k o 2k, en minúsculas). Cualquier otra cosa devuelve un 400.

¿Qué hace aspect_ratio: "auto"? Hace que el modelo siga la proporción de la imagen de referencia en lugar de forzar un formato fijo; es la opción habitual para ediciones en las que hay que conservar la composición.

¿Cuánto duran las URLs del resultado? Son URLs firmadas y con fecha de caducidad (expireAt en el payload de salida). Descarga los bytes lo antes posible tras el éxito de la tarea; no las enlaces en caliente.

¿Debo hacer polling o usar callbacks? Para uso interactivo, consultar cada ~5 segundos es suficiente. Para pipelines por lotes, pasa callback: {"url": ..., "when": "final"} y gestiona un POST por tarea; "final" es el único desencadenante admitido.

¿Puedo obtener varias variantes en una sola llamada? No: no hay parámetro n. Envía una tarea por variante; de todos modos se ejecutarán en paralelo.

¿Cuál es la diferencia con grok-imagine-quality/image-to-image? Es un nivel de renderizado con la misma estructura de solicitud y mayor fidelidad (también mayor coste). Valida con el nivel estándar y vuelve a ejecutar lo que quieras conservar en el nivel de calidad; compara el coste por imagen en la página de precios.

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