HiAPI
Blog

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.

Oct 22, 2026
URL di output delle attività HiAPI scaduti (expireAt): scarica e salva i risultati prima della 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 proprio url e expireAt.
  • expireAt è un timestamp Unix intero (non una stringa ISO). Per determinare la scadenza basta confrontarlo: è scaduto quando now >= 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 = 604800 secondi (esattamente 7 giorni). Tuttavia non inserire «7 giorni» in modo fisso nel codice: fai riferimento al valore expireAt di ciascun output, poiché modelli e strategie di archiviazione diversi possono comportarsi diversamente.

Cause comuni (in ordine di probabilità)

  1. Aver salvato il link diretto nel database per riferimenti a lungo termine: al salvataggio è stata memorizzata l'URL temporanea temp.hiapi.ai/..., che dopo expireAt restituisce 404 per tutti. È la trappola più frequente.
  2. Non aver scaricato subito dopo aver ottenuto lo stato finale: sono passati molti giorni (oltre il TTL) prima di recuperare i byte.
  3. Pensare che un nuovo polling possa «rinnovare» il link: eseguendo di nuovo GET sullo stesso taskId si ottengono la stessa url e lo stesso expireAt; i metadati sono persistenti, ma l'oggetto scaduto non viene rigenerato e un nuovo GET non fornisce un nuovo link.
  4. Confondere il 404 con un errore dell'attività: l'attività era già success da tempo, solo l'asset di output è scaduto; sono due cose distinte.

Passaggi di correzione

  1. Scarica immediatamente i byte appena arriva lo stato finale. Dopo aver rilevato tramite polling data.status == "success", esegui subito una GET su ogni output[].url per scaricare i dati binari, senza accodare né rimandare.
  2. Trasferiscili nel tuo object storage (R2 / S3 / disco locale) e sostituisci con un tuo URL persistente.
  3. Nel database salva solo il tuo URL persistente, mai il link diretto temp.hiapi.ai.
  4. Verifica la scadenza prima di scaricare: scarica solo se now < expireAt; se è già scaduto, passa direttamente alla logica di riesecuzione.
  5. 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).
  6. Controlla i tempi di download per le attività in batch: la prima attività completata del batch ha anche il expireAt più 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

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.

Inizia a creare con artefatti IA persistenti

Ottieni la tua chiave API e chiama modelli di immagini, video e audio tramite un'unica API basata sui task.

Leggi la documentazione API