Tutorial
Cómo usar seedream-5.0-pro/image-to-image con la API de hiapi: curl, Python y un ejemplo de solicitud ejecutable
Seedream 5.0 Pro es el modelo de imagen insignia de ByteDance, y su endpoint de imagen a imagen (image-to-image) recibe una o varias imágenes de referencia junto con una instrucción de texto y devuelve el resultado editado: reestilizar, cambiar el fondo, limpiar fotos de producto, componer varias imágenes. En hiapi se ejecuta sobre la API unificada de tareas asíncronas: primero creas la tarea, luego consultas el estado en bucle (o recibes un callback) y por último descargas la salida. Todos los parámetros, valores de enumeración y mensajes de error que aparecen a continuación se han verificado contra la API en producción antes de publicar esta guía.
Qué vas a construir y qué necesitas
Objetivo: enviar una imagen de referencia y una instrucción de edición a seedream-5.0-pro/image-to-image, recuperar la imagen editada y guardarla en local.
Necesitas dos cosas:
- Una clave de API de hiapi: obténla en tuconsola. Debe ir en la cabecera
Authorization: Bearer sk-.... - URLs de imagen accesibles públicamente: la API descarga tus imágenes de referencia en el servidor, por lo que deben ser accesibles por HTTPS. Una URL prefirmada de tu propio bucket funciona sin problema;
localhosto rutas privadas, no. Si la URL no se puede descargar, recibirás un error normalizado en lugar de un fallo silencioso.
Parámetros (verificados)
El ID del modelo es seedream-5.0-pro/image-to-image, exactamente como lo devuelve GET /v1/models. Los cuatro campos de entrada son obligatorios:
| Campo | Tipo | Obligatorio | Valores / notas |
|---|---|---|---|
prompt |
string | Sí | Instrucción de edición. |
image_urls |
array de strings | Sí | 1–10 URLs de imagen accesibles públicamente. Siempre un array, aunque solo haya una imagen. |
aspect_ratio |
string | Sí | match_input_image, 1:1, 4:3, 3:4, 16:9, 9:16, 3:2, 2:3, 21:9 |
resolution |
string | Sí | 1K o 2K |
Hay dos puntos que suelen provocar errores:
- El schema es estricto. Los campos desconocidos se rechazan: enviar
n,sizeoseeddevuelve 400 conadditional properties ... not allowed. En hiapi, el schema de entrada de cada modelo es distinto (algunos usansizey otrosaspect_ratio), así que no copies campos entre familias de modelos. - Aquí
resolutionsolo admite1K/2K. Otros endpoints de seedream aceptan conjuntos de resoluciones diferentes, por lo que conviene confirmarlo en cada endpoint en lugar de darlo por supuesto.
Ejemplo mínimo ejecutable: curl
Crear la tarea:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer sk-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "seedream-5.0-pro/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-bucket.example.com/product.jpg"],
"aspect_ratio": "match_input_image",
"resolution": "2K"
}
}'
Si la creación se realiza correctamente, el ID de la tarea se devuelve en data.taskId (respuesta simplificada):
{ "data": { "taskId": "<your-task-id>" } }
Consulta el estado en bucle hasta que la tarea alcance un estado terminal:
curl -s https://api.hiapi.ai/v1/tasks/YOUR_TASK_ID \
-H "Authorization: Bearer sk-YOUR_KEY"
data.status acabará siendo success (tu URL de imagen estará en data.output[0].url) o fail, con los detalles en data.error.code y data.error.message.
Script completo de Python: crear, consultar y descargar
Usa solo la biblioteca estándar, sin instalar nada:
import json
import time
import urllib.request
API = "https://api.hiapi.ai/v1/tasks"
KEY = "sk-YOUR_KEY"
def call(url, payload=None):
req = urllib.request.Request(
url,
data=json.dumps(payload).encode() if payload is not None else None,
headers={
"Authorization": f"Bearer {KEY}",
"Content-Type": "application/json",
},
method="POST" if payload is not None else "GET",
)
with urllib.request.urlopen(req) as resp:
return json.load(resp)
# 1. Create the edit task
create = call(API, {
"model": "seedream-5.0-pro/image-to-image",
"input": {
"prompt": "Restyle this living room as a Scandinavian interior, keep the layout and window positions",
"image_urls": ["https://your-bucket.example.com/room.jpg"],
"aspect_ratio": "match_input_image",
"resolution": "2K",
},
})
task_id = create["data"]["taskId"]
print("task created:", task_id)
# 2. Poll until terminal state
while True:
task = call(f"{API}/{task_id}")["data"]
if task["status"] == "success":
break
if task["status"] == "fail":
err = task.get("error") or {}
raise RuntimeError(f"task failed: {err.get('code')} {err.get('message')}")
time.sleep(5)
# 3. Download immediately -- output URLs expire
image_url = task["output"][0]["url"]
urllib.request.urlretrieve(image_url, "edited.png")
print("saved edited.png")
Consideraciones para producción
En un servidor, es mejor usar callbacks que consultar en bucle. Al crear la tarea, añade un objeto callback de nivel superior y hiapi hará un POST a tu endpoint una sola vez cuando la tarea alcance el estado terminal:
{
"model": "seedream-5.0-pro/image-to-image",
"input": { "...": "..." },
"callback": { "url": "https://your-server.example.com/hiapi-hook", "when": "final" }
}
En el manejador, trata el callback como una señal, no como la fuente de la verdad: extrae el ID de la tarea y vuelve a solicitar tú mismo GET /v1/tasks/<id> antes de actuar en consecuencia. Para scripts, notebooks y tareas puntuales, seguir consultando en bucle sigue siendo lo adecuado; basta con mantener el intervalo en torno a 5 segundos.
Haz que los reintentos sean idempotentes. Al crear una tarea, guarda tu propia correspondencia entre la imagen de origen y taskId. Si el proceso se cae a mitad de la consulta, vuelve a enlazar con el taskId guardado en lugar de reenviar la edición: reenviarla genera una segunda tarea facturable.
Descarga la salida de inmediato. La URL de data.output[0].url tiene caducidad (incluye una hora de expiración). Descarga los bytes y guárdalos en tu propio bucket; nunca enlaces directamente la URL de salida de la tarea en contenido de cara al usuario.
Errores que encontrarás en la práctica:
401conpermission_denied: la clave de API falta o tiene un formato incorrecto. Comprueba que la cabecera sea exactamenteAuthorization: Bearer sk-....400conINVALID_REQUEST: infracción del schema de entrada. Los mensajes de error son precisos, por ejemploresolution: value must be one of '1K', '2K'oimage_urls: maxItems: got 11, want 10.image_urls must be an array: pasaste una cadena sin más. Aunque haya una sola imagen, envuélvela en una lista.
Siguientes pasos
- Página del modelo: seedream-5.0-pro/image-to-image: capacidades y estado actual.
- El precio por imagen figura en lapágina de precios.
- Una opción de edición más económica para pipelines de alta concurrencia: cómo usar seedream-5.0-lite imagen a imagen.
- Para elegir entre modelos: las mejores APIs de imagen a imagen de 2026 compara la misma tarea de edición en tres modelos.
- Referencia completa de la API: documentación de hiapi.
Preguntas frecuentes
¿Cuántas imágenes de referencia puedo enviar como máximo?
Hasta 10 URLs en image_urls. El límite se aplica en el servidor: 11 imágenes devuelven maxItems: got 11, want 10.
¿La salida puede mantener la relación de aspecto de la imagen de entrada?
Sí: asigna match_input_image a aspect_ratio. Para ediciones y reestilizados suele ser lo que quieres; elige una proporción concreta como 16:9 solo si buscas recomponer la imagen a propósito.
¿seedream-5.0-pro imagen a imagen admite 4K?
No. Este endpoint solo acepta 1K y 2K. Si solicitas cualquier otro valor, recibirás un 400 con la lista de valores permitidos.
¿Mis URLs de imagen tienen que ser públicas? Deben poder descargarse por HTTPS desde los servidores de hiapi. Las URLs prefirmadas (S3, R2, GCS) funcionan bien y te permiten mantener el bucket privado.
¿Cuánto cuesta cada imagen con seedream-5.0-pro imagen a imagen? El precio se factura por imagen generada correctamente y varía según la resolución: consulta lapágina de precios en vivo para conocer la tarifa actual.
¿En qué se diferencia de seedream-5.0-lite imagen a imagen? Pro es el nivel insignia, orientado a ediciones más difíciles y de mayor fidelidad; lite es la opción más rápida y económica para grandes volúmenes. La estructura de la solicitud es similar, así que la forma más clara de decidir es ejecutar la misma tarea de edición con ambos; empieza por laguía de lite y compara los resultados con tus propias imágenes de referencia.
Artículos relacionados
Ver todos los artículos →-
Tutorial
Cómo llamar a hailuo-2.3-fast/image-to-video a través de la API de HiAPI: práctica con curl y Python
La primera solicitud ejecutable del nivel rápido y de bajo coste de imagen a vídeo: del ID del modelo a la descarga del MP4
-
Tutorial
Cómo llamar a hailuo-2.3/text-to-video mediante la API de HiAPI: curl, Python y ejemplos de solicitud ejecutables
-
Tutorial
Uso de Kandinsky 6.0 Pro texto a video en HiAPI: tutorial con curl y Python
Demostración práctica centrada en la solicitud: construir la llamada de prompt a clip de video, enviar la solicitud, sondear el estado de finalización y descargar el resultado