Tutoriale
URL di output delle attività HiAPI scaduti (expireAt): scarica e salva i risultati prima della scadenza
Nello stato finale output[].url include expireAt, e dopo la scadenza restituisce 404: come riconoscerlo, come scaricare in tempo e come recuperare dopo la scadenza.
Hai generato un'immagine o un video con POST /v1/tasks e, al termine dell'attività, hai ottenuto da data.output[0].url un link temp.hiapi.ai: all'epoca si apriva, ma dopo qualche giorno l'accesso restituisce una pagina HTML «Not Found»:
HTTP/2 404
content-type: text/html
Non vengono restituiti i byte dell'immagine o del video, bensì una pagina 404 di Cloudflare. La causa è una sola: gli URL di output delle attività sono link temporanei con una validità limitata; raggiunto il valore expireAt (timestamp Unix) presente nello stato finale, l'oggetto su temp.hiapi.ai viene eliminato e il link diretto non è più valido.
Comprendere prima i campi dello stato finale
Quando il polling dello stato finale di un'attività (GET /v1/tasks/{taskId}) ha esito positivo, i campi chiave sono questi:
{
"code": 200,
"data": {
"taskId": "tk-hiapi-xxxxxxxx",
"status": "success",
"storage": "temp",
"created": 1791828181,
"completed": 1791828201,
"output": [
{
"artifactId": "...",
"type": "image",
"url": "https://temp.hiapi.ai/....png",
"expireAt": 1792432981
}
]
},
"message": "success"
}
- Solo
data.status == "success"indica il successo nello stato finale (in caso di errore è"fail"; in coda o in elaborazione èqueued/handling/archiving). data.outputè un'array, e ogni elemento ha il propriourleexpireAt.expireAtè un timestamp Unix intero (non una stringa ISO). Per determinare la scadenza basta confrontarlo: è scaduto quandonow >= expireAt.- Il valore di
data.storageè"temp": è già un indizio che si tratta di archiviazione temporanea, non pensata per riferimenti a lungo termine.
Quanto dura la validità? In un campione misurato,
expireAt - completed = 604800secondi (esattamente 7 giorni). Tuttavia non inserire «7 giorni» in modo fisso nel codice: fai riferimento al valoreexpireAtdi ciascun output, poiché modelli e strategie di archiviazione diversi possono comportarsi diversamente.
Cause comuni (in ordine di probabilità)
- Aver salvato il link diretto nel database per riferimenti a lungo termine: al salvataggio è stata memorizzata l'URL temporanea
temp.hiapi.ai/..., che dopoexpireAtrestituisce 404 per tutti. È la trappola più frequente. - Non aver scaricato subito dopo aver ottenuto lo stato finale: sono passati molti giorni (oltre il TTL) prima di recuperare i byte.
- Pensare che un nuovo polling possa «rinnovare» il link: eseguendo di nuovo GET sullo stesso
taskIdsi ottengono la stessa url e lo stessoexpireAt; i metadati sono persistenti, ma l'oggetto scaduto non viene rigenerato e un nuovo GET non fornisce un nuovo link. - Confondere il 404 con un errore dell'attività: l'attività era già
successda tempo, solo l'asset di output è scaduto; sono due cose distinte.
Passaggi di correzione
- Scarica immediatamente i byte appena arriva lo stato finale. Dopo aver rilevato tramite polling
data.status == "success", esegui subito una GET su ognioutput[].urlper scaricare i dati binari, senza accodare né rimandare. - Trasferiscili nel tuo object storage (R2 / S3 / disco locale) e sostituisci con un tuo URL persistente.
- Nel database salva solo il tuo URL persistente, mai il link diretto
temp.hiapi.ai. - Verifica la scadenza prima di scaricare: scarica solo se
now < expireAt; se è già scaduto, passa direttamente alla logica di riesecuzione. - Se è scaduto, l'unica soluzione è rieseguire l'attività. Non esiste alcun «scambio del taskId con un nuovo link»: un nuovo GET sullo stesso taskId restituisce ancora quell'url non valido. Per ottenere di nuovo un risultato scaricabile, l'unica opzione è inviare di nuovo l'attività (con nuovo addebito).
- Controlla i tempi di download per le attività in batch: la prima attività completata del batch ha anche il
expireAtpiù vicino. Scarica subito in base all'ordine di completamento, non aspettare che l'intero batch sia terminato per scaricare tutto insieme, altrimenti quelle completate prima potrebbero essere vicine alla scadenza.
Esempio di verifica minima
Verifica che la tua key funzioni, che l'API delle attività produca risultati e osserva direttamente expireAt. Usa per model id l'id nudo (z-image, senza aggiungere suffissi come /text-to-image, altrimenti otterrai 400):
# 1. Invia l'attività
curl -s https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "z-image",
"input": { "prompt": "a red apple on a wooden table" }
}'
# → {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}
# 2. Esegui il polling dello stato finale con il taskId del passaggio precedente e leggi url ed expireAt
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxx \
-H "Authorization: Bearer $HIAPI_API_KEY"
# Dopo che data.status diventa "success", data.output[0].url / .expireAt sono disponibili
Se l'autenticazione fallisce, la risposta è HTTP 401 + {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}: è un problema di key, non di scadenza. Se l'attività non viene trovata, la risposta è {"code":404,"data":null,"message":"task not found"}: di solito significa che il taskId è stato copiato male o che è stata usata una key di un altro ambiente.
Link correlati
- Come inviare e monitorare le attività: Documentazione di avvio rapido HiAPI
- Controlla la tua API key e consulta la cronologia delle attività: Console
- Quali modelli sono disponibili: Marketplace dei modelli
- Esempio di pagina di un singolo modello (quello usato per la verifica in questo articolo): Z-Image text-to-image
FAQ
D: Che formato ha esattamente expireAt?
R: Un timestamp Unix intero (secondi), ad esempio 1792432981, non una stringa ISO. Basta usare now >= expireAt per determinare la scadenza.
D: Dopo la scadenza del link, è possibile eseguire di nuovo GET sull'attività per «rinnovarlo»?
R: No. Un nuovo GET sullo stesso taskId restituisce ancora l'url originale e il valore expireAt originale, ma l'oggetto è già stato eliminato. Per ottenere di nuovo un risultato scaricabile, l'unica opzione è rieseguire l'attività (con nuovo addebito).
D: Dopo la scadenza, l'accesso restituisce 403 o 404?
R: Restituisce HTTP 404, e il body è una pagina «Not Found» di Cloudflare in text/html, non i byte dell'immagine né un AccessDenied XML. Se la tua logica di download accetta solo 200, ricorda di gestire «qualsiasi risposta diversa da 200 come errore».
D: La validità è fissa a 7 giorni?
R: Nel campione misurato è di 7 giorni (604800 secondi), ma fai riferimento al valore expireAt di ciascun output e non inserire il numero di giorni in modo fisso nel codice.
D: Qual è il modo più affidabile per scaricare un batch di attività?
R: In base all'ordine di completamento: scarica i byte di chi diventa success per primo. L'output completato per primo ha anche l'expireAt più vicino, e rimandare tutto a un download unico alla fine rischia di incappare nella scadenza imminente.
Articoli correlati
Vedi tutti gli articoli →-
Tutoriale
Come chiamare hailuo-2.3-fast/image-to-video tramite l'API HiAPI: pratica con curl e Python
La prima richiesta funzionante per il livello image-to-video veloce ed economico — dall'ID del modello al download di un MP4
-
Tutoriale
Come chiamare hailuo-2.3/text-to-video tramite l'API HiAPI: curl, Python ed esempi di richiesta eseguibili
-
Tutoriale
Utilizzare Kandinsky 6.0 Pro su HiAPI per la generazione di video da testo: tutorial con curl e Python
Dimostrazione pratica guidata dalla richiesta: costruire la chiamata da prompt a clip video, inviare la richiesta, monitorare lo stato di completamento e scaricare il risultato