HiAPI
Blog

Tutorial

Cómo usar seedream-4.5/image-to-image a través de la API de hiapi: curl, Python y solicitudes disponibles

Jul 10, 2026
Cómo usar seedream-4.5/image-to-image a través de la API de hiapi: curl, Python y solicitudes disponibles

Para editar imágenes con seedream-4.5, solo tienes que enviar un POST a la API de tareas unificada de hiapi, hacer un breve sondeo y descargar el resultado. Esta guía ofrece solicitudes curl funcionales y un script completo de Python para seedream-4.5/image-to-image, junto con una descripción precisa de los campos de entrada (verificada contra la API en línea), el uso con múltiples imágenes de referencia y los errores que realmente encontrarás.

Qué vas a construir y qué necesitas

Objetivo: enviar una o varias imágenes de origen junto con instrucciones de edición a seedream-4.5/image-to-image y recuperar la URL de la imagen terminada.

Requisitos previos:

  • Una clave de API de hiapi, obtenida desde tu consola. Cada solicitud a continuación la usa como token Bearer.
  • Las imágenes de origen deben estar alojadas en URLs de acceso público. La API las descarga en el servidor; las rutas de archivos locales o las URLs privadas no funcionan.

El modelo se ejecuta en el endpoint de tareas asíncronas: POST /v1/tasks crea la tarea, GET /v1/tasks/<taskId> informa del estado y la imagen terminada aparece en data.output[0].url.

Descripción de los campos de entrada (verificada)

seedream-4.5/image-to-image tiene cuatro campos de entrada obligatorios y no acepta otros; la especificación de campos es estricta y los campos desconocidos se rechazan con un 400:

Campo Tipo Restricción
prompt string Instrucciones de edición
image_urls array de strings URLs públicas, hasta 14 imágenes
aspect_ratio string Uno de 1:1, 4:3, 3:4, 16:9, 9:16, 2:3, 3:2, 21:9
resolution string Solo 2K o 4K

Hay dos puntos que conviene destacar: no existe un parámetro n (una salida por tarea; si necesitas varias variantes, crea varias tareas en paralelo); y a diferencia de image-to-image de seedream-5.0-pro (que acepta 1K/2K), la versión 4.5 exige 2K o 4K. Enviar 1K aquí devuelve un error de validación.

Solicitud mínima funcional: curl

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

Una creación exitosa devuelve el ID de tarea en data.taskId. Consúltalo:

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

Cuando data.status alcanza success, la URL de la imagen está en data.output[0].url. Si es fail, el motivo está en data.error.

Script completo de Python

No se necesita SDK, solo requests y un bucle de sondeo:

import time
import requests

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

def edit_image(prompt: str, image_urls: list[str],
               aspect_ratio: str = "1:1", resolution: str = "2K") -> bytes:
    # 1. Create the task
    resp = requests.post(API_BASE, headers=HEADERS, json={
        "model": "seedream-4.5/image-to-image",
        "input": {
            "prompt": prompt,
            "image_urls": image_urls,   # public URLs, max 14
            "aspect_ratio": aspect_ratio,
            "resolution": resolution,   # "2K" or "4K"
        },
    }, timeout=60)
    resp.raise_for_status()
    task_id = resp.json()["data"]["taskId"]

    # 2. Poll until terminal state
    deadline = time.time() + 600
    while time.time() < deadline:
        task = requests.get(f"{API_BASE}/{task_id}",
                            headers=HEADERS, timeout=30).json()["data"]
        if task["status"] == "success":
            url = task["output"][0]["url"]
            # 3. Output URLs expire -- download immediately
            return requests.get(url, timeout=120).content
        if task["status"] == "fail":
            err = task.get("error") or {}
            raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
        time.sleep(5)
    raise TimeoutError(f"task {task_id} did not finish in 600s")

png = edit_image(
    "Turn this product shot into a clean studio photo on a seamless white background",
    ["https://your-cdn.example.com/source.jpg"],
)
with open("edited.png", "wb") as f:
    f.write(png)

Fíjate en el comentario del paso 3: las URLs de salida llevan una marca de tiempo de caducidad. En cuanto la tarea finaliza con éxito, debes persistir los bytes en tu propio almacenamiento; no guardes solo la URL devuelta y confíes en que seguirá funcionando mañana.

Edición con múltiples imágenes de referencia

image_urls acepta hasta 14 imágenes en una sola tarea. Es una herramienta muy útil para tareas de transferencia de estilo y composición: pasa la imagen que quieres editar junto con las imágenes de referencia y describe en el prompt cómo combinarlas.

{
  "model": "seedream-4.5/image-to-image",
  "input": {
    "prompt": "Apply the color grading and lighting style of the second image to the first image, keep the subject unchanged",
    "image_urls": [
      "https://your-cdn.example.com/subject.jpg",
      "https://your-cdn.example.com/style-reference.jpg"
    ],
    "aspect_ratio": "3:2",
    "resolution": "2K"
  }
}

El orden importa para el prompt, no para la API: haz referencia a las imágenes por su posición ("la primera imagen", "la segunda imagen") para que el modelo sepa cuál es cuál.

Consideraciones para producción

Usa callbacks en lugar de sondeo. Para cualquier escenario que vaya más allá de un script, añade un objeto callback de nivel raíz al crear la tarea y omite por completo el bucle de sondeo:

{
  "model": "seedream-4.5/image-to-image",
  "input": { "...": "..." },
  "callback": { "url": "https://yourapp.com/hooks/hiapi", "when": "final" }
}

Cuando la tarea termina, hiapi envía por POST el estado final de la tarea a tu URL. El sondeo es adecuado para herramientas CLI y notebooks; para un backend web, lo correcto es usar callbacks; de lo contrario, mantendrás ocupado un proceso de trabajo durante las decenas de segundos que requiere una edición en 2K.

Idempotencia. La creación de tareas no es idempotente: reintentar la creación tras un tiempo de espera de red puede generar (y facturar) dos tareas. Guarda el taskId en el momento en que lo recibas y, antes de crear una nueva tarea al reintentar, comprueba si ya existe una tarea activa.

Manejo de errores. Los dos tipos de fallo que encontrarás primero:

  • 401 permission_denied: la clave es incorrecta o esa clave no tiene acceso a este modelo. El cuerpo de la respuesta se parece a {"error": {"code": "permission_denied", "message": "This API key cannot use the selected model...", "request_id": "..."}}. Incluye el request_id cuando contactes con soporte.
  • 400 INVALID_REQUEST: incumplimiento de la especificación de campos, con un mensaje preciso: valor de resolution incorrecto, más de 14 elementos en image_urls, un campo desconocido o image_urls que no es un array. Todos estos se detectan antes de que la tarea se ejecute, por lo que no generan coste.

Las tareas fallidas informan status: "fail" en la propia tarea, junto con un objeto error; trátalo como un caso distinto de los errores HTTP, tal como hace el script de Python anterior.

Precios

El coste por imagen depende de la resolución. Consulta las tarifas actuales en la página de precios. Las solicitudes rechazadas en la fase de validación (400) nunca inician una tarea, por lo que los errores de especificación de campos durante la integración son gratuitos.

Lecturas relacionadas

Preguntas frecuentes

¿Puedo pasar un archivo local o una imagen en base64 en lugar de una URL? No. image_urls debe ser un array de URLs de acceso público; la plataforma las descarga y normaliza en el servidor. Sube primero a tu propio almacenamiento (S3, R2, cualquier CDN) y luego pasa la URL.

¿Cuántas imágenes de referencia admite seedream-4.5 image-to-image? Hasta 14 por tarea. Si se supera, se devuelve un 400 con un mensaje que incluye image_urls: maxItems.

¿Por qué recibo un 400 cuando configuro resolution en 1K? El endpoint image-to-image de la versión 4.5 solo acepta 2K o 4K. La opción 1K pertenece a image-to-image de seedream-5.0-pro; las enumeraciones difieren entre series de distintos niveles.

¿Puedo generar varias variantes en una sola solicitud? No; la especificación de campos no incluye un parámetro n y rechaza los campos desconocidos. Crea una tarea por variante y ejecútalas en paralelo; cada tarea devuelve una sola salida.

¿Cuánto tiempo es válida la URL del resultado? Las URLs de salida llevan firma y tiempo de caducidad. Descarga la imagen en cuanto la tarea finalice con éxito y guárdala por tu cuenta, en lugar de enlazar directamente la salida de la tarea.

¿Cuál es la diferencia entre un error HTTP y una tarea fallida? Un error HTTP (400/401) significa que la solicitud nunca llegó a ser una tarea: corrige el payload o la clave y vuelve a enviarla. Una tarea que termina con status: "fail" fue aceptada pero no pudo completarse; el motivo está en el objeto error de la tarea y, para fallos transitorios, normalmente lo correcto es reintentar con las mismas entradas.

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