Tutorial
¿Los URL de salida de HiAPI han caducado? Descárgalos en 7 días o conviértelos en almacenamiento persistente
Por qué los enlaces de salida de las tareas dejan de funcionar, qué significa expireAt y las dos soluciones: descargar de inmediato o conservar los archivos en HiAPI con almacenamiento persistente.
TL;DR
- Los enlaces de salida que devuelve
POST /v1/tasksson temporales: unos 7 días después de completarse la tarea se eliminan. El campoexpireAtde cada salida indica la hora exacta de caducidad en segundos Unix. - Un enlace caducado no se puede recuperar. Volver a consultar la tarea solo devuelve el mismo enlace, y volver a ejecutar la tarea se cobra de nuevo.
- Dos soluciones: descargar los archivos justo después de que la tarea termine con éxito, o conservarlos en HiAPI con
"storage": "persistent"($0.05 por GB al mes). También puedes convertir una salida temporal en almacenamiento persistente en cualquier momento antes de que caduque.
Cómo se ve una tarea completada
Este es el detalle real de una tarea de GET https://api.hiapi.ai/v1/tasks/{taskId}:
{
"code": 200,
"message": "success",
"data": {
"taskId": "tk-hiapi-01M59F0HVM9QSCYPDT4BHABD3K",
"model": "grok-imagine/text-to-image",
"status": "success",
"created": 1792392841,
"completed": 1792392863,
"storage": "temp",
"output": [
{
"type": "image",
"url": "https://temp.hiapi.ai/.../01M59F0HVM9QSCYPDT4BHABD3K-0.png",
"expireAt": 1792997663
}
]
}
}
storage: "temp"es el nivel predeterminado.expireAtmenoscompletedda 604,800 segundos, exactamente 7 días. Revisamos cuatro tareas (dos imágenes y dos videos) y las cuatro tenían una ventana de retención de 7 días.statuspasa porqueued,handlingyarchiving, y termina ensuccessofail. Solo estos dos últimos son estados finales.
Por qué los enlaces dejan de funcionar "de repente"
- Guardas el enlace en lugar del archivo. En una fila de base de datos, un campo de CMS o una página de Notion queda guardado un URL de
temp.hiapi.ai; la primera semana funciona y después nadie puede abrirlo. - Los archivos se obtienen demasiado tarde. Alguna cola va a buscar el resultado días después, cuando ya pasó el
expireAt. - El trabajo por lotes omite el paso de subida. Los registros parecen correctos, pero una semana después los archivos ya no están.
- La salida de una tarea se usa como entrada de otra. Hoy funciona, pero si el segundo trabajo se vuelve a ejecutar después de que caduque el enlace, fallará.
Solución 1: descargar en la misma ruta de código
# pip install requests; export HIAPI_KEY=your-key first
import os, time, requests
API = "https://api.hiapi.ai/v1/tasks"
H = {"Authorization": f"Bearer {os.environ['HIAPI_KEY']}"}
def run_and_save(model, inp, path, timeout_s=600):
r = requests.post(API, json={"model": model, "input": inp}, headers=H, timeout=30).json()
if r.get("code") != 200:
raise RuntimeError(r)
task_id = r["data"]["taskId"] # store this before polling
deadline = time.time() + timeout_s
while time.time() < deadline:
d = requests.get(f"{API}/{task_id}", headers=H, timeout=30).json()["data"]
if d["status"] == "success":
out = d["output"][0]
with open(path, "wb") as f: # or upload to S3 / R2 here
f.write(requests.get(out["url"], timeout=120).content)
return task_id, out["expireAt"]
if d["status"] == "fail":
raise RuntimeError(d.get("error"))
time.sleep(3)
raise TimeoutError(task_id)
run_and_save("z-image", {"prompt": "a red ceramic teapot on a wooden table", "aspect_ratio": "1:1"},
"teapot.png")
Guarda tu propio URL de almacenamiento en la base de datos, no el enlace de HiAPI. Si el proceso se cae después del envío, vuelve a consultar el taskId guardado en lugar de crear una tarea nueva; el archivo sigue ahí dentro de los 7 días.
Solución 2: conservar la salida en HiAPI
Si no quieres montar tu propio almacenamiento, puedes pedirle a HiAPI que conserve los archivos:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "z-image",
"storage": "persistent",
"input": {"prompt": "a red ceramic teapot on a wooden table", "aspect_ratio": "1:1"}
}'
storage va en el nivel superior, al mismo nivel que model, no dentro de input. Revisa data.storage en el detalle de la tarea: si no tienes saldo suficiente o superas el límite de almacenamiento, la salida vuelve silenciosamente a temp aunque la tarea siga siendo exitosa.
¿Ya tienes algunas salidas temporales que quieres conservar? Conviértelas antes de que caduquen. Primero obtén sus id con GET /v1/storages y luego:
curl -s -X POST https://api.hiapi.ai/v1/storages/promote \
-H "Authorization: Bearer $HIAPI_KEY" \
-H "Content-Type: application/json" \
-d '["90216", "90215"]'
Cada llamada admite hasta 50 id. La respuesta lista los id accepted y rejected, y da un motivo para cada id rechazado, por ejemplo cap_exceeded. La conversión se ejecuta en segundo plano; los archivos conservan su ruta original y se migran al dominio persistente. También puedes hacer la conversión en Dashboard → Storage.
temp (predeterminado) |
persistent |
|
|---|---|---|
| Duración de retención | Aproximadamente 7 días | Hasta que lo elimines |
| Costo | Gratis | $0.05 por GB al mes, facturado por día |
| Descarga | Gratis | Gratis |
| Límite de tamaño | Ninguno | 100 GB por cuenta de forma predeterminada |
Ejemplo de costo: almacenar 5 GB durante un mes cuesta $0.25; 50 GB cuesta $2.50. Después de eliminar archivos con POST /v1/storages/delete, el cobro se detiene a partir del día siguiente. Los archivos persistentes no se pueden volver a convertir en almacenamiento temporal.
Si tu saldo no puede cubrir el costo de almacenamiento durante 3 días consecutivos, los archivos persistentes entran en un periodo de gracia de 7 días y recibes un correo. Si recargas saldo, los archivos se conservan; si el periodo de gracia termina sin recarga, los archivos se eliminan.
Qué solución usar
- Ya tienes S3, R2 o un CDN: usa la solución 1. Descarga una vez y luego sirve los archivos desde tu propio almacenamiento.
- Quieres que los enlaces sigan siendo válidos sin montar tu propio almacenamiento: usa la solución 2, con
"storage": "persistent". - Solo necesitas conservar unos pocos resultados: deja todas las salidas en
tempy convierte solo las que quieras conservar.
FAQ
¿Cuánto tiempo se conservan los enlaces de salida?
Aproximadamente 7 días después de completarse la tarea. La hora exacta está en expireAt de cada salida (segundos Unix).
¿Consultar la tarea de nuevo da un enlace nuevo?
No. GET /v1/tasks/{taskId} devuelve el mismo enlace. Una vez caducado, el archivo desaparece salvo que lo hayas convertido a persistente.
¿Volver a ejecutar la tarea cuesta dinero?
Sí. La nueva tarea se cobra otra vez, así que guardar los archivos la primera vez es la opción más económica.
¿Los enlaces de salida son públicos?
Sí. Cualquiera que tenga el URL puede descargar el archivo, pero la ruta es aleatoria y no se puede adivinar. Por ahora no se ofrecen enlaces firmados ni privados.
¿El almacenamiento persistente también cuenta los videos?
Sí. Cada archivo de imagen, video y audio que conserves cuenta para el tamaño de almacenamiento.
Consulta la referencia completa en la documentación de Output Storage y en la documentación de detalle de tareas.
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