HiAPI
Blog

Tutorial

Cómo usar grok-imagine-quality/image-to-image a través de la API de hiapi: curl, Python y solicitudes funcionales

Jul 11, 2026
Cómo usar grok-imagine-quality/image-to-image a través de la API de hiapi: curl, Python y solicitudes funcionales

Esta guía te muestra cómo transformar imágenes existentes con grok-imagine-quality/image-to-image (el nivel de mayor fidelidad de la familia Grok Imagine) a través de la API de tareas unificada de hiapi. Enviarás una imagen de origen y un prompt de texto, consultarás el resultado de forma periódica y descargarás la imagen generada. Cada estructura de solicitud y respuesta que aparece a continuación está verificada contra la API en vivo.

Lo que necesitas

  • Una clave de API de hiapi — créala en el panel de control.
  • De uno a tres URL de imágenes de acceso público para usar como origen. La plataforma obtiene y normaliza tu medio de entrada en el servidor, por lo que las rutas de archivos locales y las cargas base64 no funcionan — aloja primero tus imágenes en una ubicación accesible para la API.

Eso es todo. No se necesita SDK; la API de tareas es simple HTTPS + JSON.

Modo de solicitud

grok-imagine-quality/image-to-image se ejecuta en el endpoint de tareas asíncronas: creas una tarea con POST /v1/tasks y luego consultas GET /v1/tasks/<taskId> (o registras un callback) hasta que termine.

El esquema de entrada es estricto — los campos desconocidos se rechazan con 400:

Campo Tipo Obligatorio Descripción
prompt string ✅ Qué hacer con la imagen de origen
image_urls string[] ✅ URL públicas de 1–3 imágenes de origen/referencia
aspect_ratio string – Uno de: 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 string – 1k o 2k — minúsculas (1K devuelve 400)
output_format string – jpeg, png o webp

Fíjate en lo que no hay: sin size, sin n, sin seed, sin perillas de strength ni consistency. Cuánto sigue la salida a la imagen de origen lo controlan tu prompt y las imágenes de referencia que pasas — consulta las Preguntas frecuentes a continuación.

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-quality/image-to-image",
    "input": {
      "prompt": "Turn this product photo into a clean studio shot on a light gray background with soft shadows",
      "image_urls": ["https://your-cdn.example.com/source.jpg"],
      "aspect_ratio": "1:1",
      "resolution": "2k",
      "output_format": "png"
    }
  }'

Una creación exitosa devuelve un ID de tarea:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx"
  }
}

Consulta hasta que la tarea alcance un estado terminal:

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

Mientras se ejecuta, data.status está en curso; cuando termina pasa a success y la imagen está en data.output:

{
  "code": 200,
  "data": {
    "taskId": "task_xxxxxxxxxxxx",
    "status": "success",
    "output": [
      {
        "url": "https://.../result.png?...&expireAt=...",
        "expireAt": 1760000000
      }
    ]
  }
}

⚠️ La URL de salida es temporal (fíjate en expireAt). Descarga los bytes inmediatamente después de que la tarea tenga éxito y guárdalos en tu propio almacenamiento — no enlaces en caliente la URL del resultado.

Si la tarea falla, data.status es fail y data.error lleva code y message.

Python: crear, consultar, descargar

Un script completo que solo usa requests:

import time
import requests

API_BASE = "https://api.hiapi.ai/v1/tasks"
API_KEY = "sk-<your-key>"

HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}

def create_task(prompt: str, image_urls: list[str]) -> str:
    payload = {
        "model": "grok-imagine-quality/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,   # 1-3 public URLs
            "aspect_ratio": "1:1",
            "resolution": "2k",         # lowercase: "1k" or "2k"
            "output_format": "png",
        },
    }
    r = requests.post(API_BASE, headers=HEADERS, json=payload, timeout=60)
    data = r.json()
    task_id = (data.get("data") or {}).get("taskId")
    if not task_id:
        raise RuntimeError(f"create failed: {data}")
    return task_id

def wait_task(task_id: str, timeout_s: int = 600, poll_interval: int = 5) -> dict:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{API_BASE}/{task_id}", headers=HEADERS, timeout=30)
        task = r.json().get("data") or {}
        status = task.get("status")
        if status == "success":
            return task
        if status == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(poll_interval)
    raise TimeoutError(f"task {task_id} still running after {timeout_s}s")

if __name__ == "__main__":
    task_id = create_task(
        prompt="Turn this product photo into a clean studio shot on a light gray background",
        image_urls=["https://your-cdn.example.com/source.jpg"],
    )
    print("task:", task_id)

    task = wait_task(task_id)
    url = task["output"][0]["url"]

    # The output URL expires -- download immediately and persist yourself
    img = requests.get(url, timeout=120).content
    with open("result.png", "wb") as f:
        f.write(img)
    print(f"saved result.png ({len(img)} bytes)")

Consideraciones para producción

Usa callbacks en lugar de polling

Para cualquier escenario más allá de un script de un solo uso, registra un callback y omite el bucle de polling. Añade un objeto callback de nivel superior (al mismo nivel que model e input):

{
  "model": "grok-imagine-quality/image-to-image",
  "input": { "...": "..." },
  "callback": {
    "url": "https://your-app.example.com/hooks/hiapi",
    "when": "final"
  }
}

when solo admite "final" — recibirás exactamente un POST cuando la tarea alcance un estado terminal (success o fail). Regla general:

  • Polling funciona para CLI, notebooks y trabajos por lotes, donde el proceso se mantiene vivo de todos modos. Consulta cada 3–5 segundos; no martilles con intervalos inferiores al segundo.
  • Callbacks son mejores para backends web: sin conexiones colgadas, sin hilos de trabajo ocupados durante la generación. Vuelve a obtener GET /v1/tasks/<taskId> en el servidor para verificar la carga útil, en lugar de confiar ciegamente en el cuerpo del webhook.

Idempotencia

La creación de tareas no es idempotente por sí misma — si tu proceso se cae después de POST /v1/tasks pero antes de persistir el taskId, el reintento creará (y cobrará) una segunda tarea. Persiste el taskId en tu propio almacenamiento, indexado por tu ID de trabajo interno, antes de empezar a esperar, y al reiniciar recupera consultando el taskId almacenado en lugar de crear uno nuevo.

Manejo de errores

Los errores que encontrarás en la práctica:

  • 401 permission_denied — la clave de API no es válida o no tiene acceso a este modelo. El cuerpo de la respuesta incluye un request_id que puedes enviar al soporte:

    {
      "error": {
        "code": "permission_denied",
        "message": "This API key cannot use the selected model. ...",
        "request_id": "2026...",
        "type": "hiapi_error"
      }
    }
    
  • 400 INVALID_REQUEST — violación del esquema, con un mensaje preciso. Ejemplos reales de este modelo:

    • prompt: missing required field "prompt" — olvidaste un campo obligatorio.
    • image_urls: maxItems: got 12, want 3 — demasiadas imágenes de referencia (máximo 3).
    • resolution: value must be one of '1k', '2k' — enviaste 1K/4K.
    • additional properties 'seed' not allowed — pasaste un campo que este modelo no acepta.
  • Estado terminal fail — la tarea se aceptó pero la generación falló (por ejemplo, no se pudo obtener la URL de origen). Revisa data.error.message, corrige la entrada y crea una nueva tarea.

Usa reintentos con retroceso exponencial para 5xx y errores de red; no reintentes 400 — fallarán de la misma manera hasta que corrijas la carga útil.

Elegir el nivel de calidad (y ¿qué pasa con la «consistencia»?)

La familia Grok Imagine en hiapi se divide en IDs de modelo separados por nivel y modalidad. Para imagen a imagen, puedes elegir:

El nivel es el ID de modelo — no hay ningún parámetro quality dentro de input (enviarlo devuelve 400 additional properties 'quality' not allowed). El precio por imagen de ambos niveles está en la página de precios.

Lecturas relacionadas

Preguntas frecuentes

¿Hay un parámetro de consistencia o de intensidad? No. El esquema de entrada solo acepta prompt, image_urls, aspect_ratio, resolution y output_format; cualquier otra cosa se rechaza con 400. Para controlar cuánto sigue la salida a la imagen de origen, indica explícitamente en el prompt qué debe conservarse («mantén el producto y la etiqueta idénticos, cambia solo el fondo») y pasa hasta 3 imágenes de referencia mediante image_urls.

¿Puedo subir un archivo local o enviar base64? No directamente — image_urls acepta URL y la plataforma las obtiene en el servidor. Sube el archivo a cualquier almacenamiento de acceso público (S3, R2, CDN) y pasa esa URL.

¿Cuántas imágenes de origen puedo pasar? De 1 a 3. Un array vacío falla con minItems: got 0, want 1; más de 3 falla con maxItems.

¿Qué resoluciones y relaciones de aspecto se admiten? resolution es 1k o 2k (solo minúsculas). aspect_ratio admite 14 valores desde 2:1 hasta 1:2, incluidos auto, 16:9, 1:1, 9:16 y los aptos para móvil 9:19.5/9:20.

¿Cuánto dura la URL de salida? Cada salida lleva una marca de tiempo expireAt. Trata los resultados como efímeros: descarga los bytes inmediatamente después de que la tarea tenga éxito y guárdalos tú mismo.

¿Cómo genero múltiples variantes? No hay parámetro n — crea una tarea por variante. Las tareas se ejecutan de forma independiente, así que puedes enviar varias en paralelo.

Si mi clave es correcta, ¿qué significa 401 permission_denied? La clave existe pero no puede usar este modelo (por plan o por alcance de permisos). Revisa los permisos de modelos de la clave en el panel de control, o contacta con soporte usando el request_id del cuerpo de la respuesta de error.

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