Tutoriale
hiapi /v1/tasks attività bloccata o in timeout: flusso diagnostico e strategia di retry
Hai inviato un'attività con POST https://api.hiapi.ai/v1/tasks, hai ottenuto un taskId, ma interrogando con GET /v1/tasks/{taskId} vedi che data.status resta fermo su queued o handling per diversi minuti — sembra "bloccata"; oppure il tuo ciclo di polling raggiunge il limite che hai impostato senza arrivare allo stato finale, e quindi segnala un timeout. Non affrettarti a reinviare: le attività di hiapi sono asincrone, "non ancora terminata" e "già fallita" sono due cose diverse; diagnostica con chiarezza prima di agire, così non peggiori la situazione.
Se vedi che
data.statusè giàfail, cheerror.codeèTASK_TIMEOUT, oppure se il browser/proxy restituisce un letterale HTTP 504 — quello è un altro tipo di problema (l'attività è davvero fallita, o il timeout si è verificato a livello di rete tra te e hiapi). Consulta Diagnosi dei timeout delle attività HiAPI e degli errori 504. Questo articolo tratta solo lo scenario "bloccato" in cui l'attività tarda a raggiungere lo stato finale.
Manifestazione del problema
Un'attività "bloccata", interrogata, appare più o meno così (HTTP 200, ma l'attività è ancora in uno stato non finale):
{
"data": {
"taskId": "…",
"status": "queued",
"output": null,
"error": null
}
}
Caratteristiche chiave: data.status è uno tra queued (in coda) / handling (in elaborazione) / archiving (in archiviazione), data.error è null, data.output non ha ancora contenuto. Questo indica che l'attività è sana, semplicemente non è ancora terminata.
Gli stati finali delle attività hiapi sono solo due: data.status uguale a success o fail. Finché non è uno di questi due, significa che l'attività non è conclusa — i "blocchi" si verificano quasi sempre in questa fase non finale.
Due "falsi blocchi" facilmente confondibili:
L'interrogazione restituisce direttamente
404:{"code": 404, "data": null, "message": "task not found"}Non è un blocco: il
taskIdè scritto male, l'attività non è stata creata con successo, oppure il record dell'attività è scaduto — verifica ildata.taskIdottenuto al momento dell'invio.Rifiuto sincrono già al momento dell'invio (non hai nemmeno ottenuto il
taskId), ad esempio model scritto male:{"code": 400, "data": null, "error_code": "MODEL_UNAVAILABLE", "message": "model not available via /v1/tasks"}Questi sono problemi della richiesta stessa, non attività bloccate: correggi e reinvia.
Cause comuni (ordinate per probabilità)
1. Arretrato in coda (la più comune)
Quando un modello (modello immagine, modello video o qualsiasi modello ad alto carico di calcolo) viene chiamato intensamente, la tua attività attende nella coda di quel modello di essere presa in carico da un worker.
- Segnale:
data.statusèqueued,data.errorènull, e non è passato molto tempo dall'invio. - Rimedio: rallenta il ritmo di polling, 5–10 secondi per interrogazione bastano; non girare a vuoto ogni 100ms. La maggior parte delle attività viene presa in carico entro uno o due minuti.
2. I modelli pesanti richiedono tempo
L'attività è già stata presa in carico (handling/archiving), ma questo modello impiega fisiologicamente molto tempo per completare un'esecuzione — video lunghi, alta risoluzione, molte immagini di riferimento allungano notevolmente i tempi.
- Segnale:
data.statusèhandlingoarchiving, persiste per diversi minuti ma senza errori. - Rimedio: concedi alle attività pesanti un limite di polling più ampio (lascia margine in base alle capacità del modello). Tempo lungo ≠ fallimento; non interromperla proprio quando sta per produrre il risultato.
3. Modalità di polling sbagliata (la più facilmente scambiata per "blocco")
Molti "blocchi" sono in realtà problemi del client: intervallo di polling troppo breve che confonde, nessun limite impostato, oppure limite troppo breve e abbandono prematuro.
- Segnale: il
data.statusdel server avanza normalmente, ma il tuo ciclo lancia un timeout in anticipo, oppure non stai proprio leggendodata.status. - Rimedio: usa un intervallo fisso (consigliato 5 secondi) + un limite ragionevole (circa 10 minuti per attività normali, di più per quelle pesanti). Il timeout deve essere determinato dal tuo ciclo, non aspettandoti uno stato
timeoutdal server — hiapi non ha questo stato.
4. Endpoint di callback irraggiungibile
Se all'invio dell'attività hai incluso un callback, l'attività stessa potrebbe essere già success, ma il risultato non riesce ad arrivare a te, quindi sembra "ferma".
- Segnale: interrogando attivamente
data.statusè giàsuccess,data.outputha contenuto, ma il tuo endpoint di callback non ha ricevuto nulla. - Rimedio: l'indirizzo di callback deve essere raggiungibile da Internet, accettare
POSTe restituire2xxentro circa 10 secondi; altrimenti passa al polling. Dettagli in Perché il callback delle attività hiapi non si attiva.
Passi di risoluzione
- Interroga prima lo stato, non reinviare a sensazione:
GET /v1/tasks/{taskId}, leggidata.statusedata.error. - Smista in base allo stato:
queued/handling/archiving→ è ancora in esecuzione, attendi 5–10 secondi e interroga di nuovo (cause 1 / 2).success→ attività riuscita, prendi il risultato dadata.output; se aspettavi un callback e non è arrivato → causa 4.fail→ leggidata.error.codeedata.error.message; se èTASK_TIMEOUT→ vedi guida timeout e 504.404 task not found→taskIderrato o non creato con successo; ricontrolladata.taskIdnella risposta di invio.
- output ha una scadenza: gli URL di download in
data.outputhannoexpireAt(circa 7 giorni); una volta ottenuti, salvali su disco / trasferiscili al più presto, non conservare hotlink a lungo. - Verifica che non sia un problema di autenticazione / richiesta: esegui prima l'esempio di verifica minimale qui sotto, per escludere problemi con key e model id.
- Se devi davvero ritentare, usa il backoff: vedi la sezione successiva sulla strategia di retry; non reinviare ripetutamente lo stesso body in un ciclo serrato.
Esempio di verifica minimale
Usa una richiesta minimale per confermare che key e interfaccia attività funzionino. Usa il model con id nudo (es.: gpt-image-2):
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"input": { "prompt": "a single red apple on a white background, studio lighting" }
}'
Un invio riuscito restituisce una risposta simile a {"data":{"taskId":"…","status":"queued"}}. Prendi il taskId e interroga:
curl -s "https://api.hiapi.ai/v1/tasks/<taskId>" \
-H "Authorization: Bearer $HIAPI_API_KEY"
- Se restituisce
401con body{"error":{"code":"permission_denied","type":"hiapi_error","request_id":"…"}}— il problema è la key, non l'attività. Vedi prima Diagnosi dell'errore API Key non valida. - Se l'invio viene rifiutato con
400+"error_code":"MODEL_UNAVAILABLE"— è un problema di model id. Passa l'id nudo e confronta con errore "modello non disponibile" di hiapi.
Strategia di retry che non peggiora le cose
- Backoff esponenziale: consigliato 5s → 15s → 45s.
- Massimo 3 tentativi: se fallisce anche il terzo, passa all'escalation (cambia modello, riduci la configurazione o apri un ticket); niente cicli infiniti.
- Ogni retry è una nuova attività: un
POST /v1/tasksè un nuovotaskIde può generare nuova fatturazione. hiapi non offre un "reinvia idempotente" garantito — non aspettarti che reinviare lo stesso body riutilizzi la vecchia attività. - Quando incontri un 429, rallenta la velocità di invio, non quella di polling: vedi Come risolvere l'errore di rate limit (429) di hiapi.
Un esempio Python affidabile di polling + backoff:
import time, os, requests
BASE = "https://api.hiapi.ai/v1/tasks"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"}
def submit_and_wait(body, poll_interval=5, max_wait=600):
r = requests.post(BASE, json=body, headers=HEADERS, timeout=30)
r.raise_for_status()
task_id = r.json()["data"]["taskId"]
deadline = time.time() + max_wait
while time.time() < deadline:
time.sleep(poll_interval)
data = requests.get(f"{BASE}/{task_id}", headers=HEADERS, timeout=30).json()
status = (data.get("data") or {}).get("status")
if status == "success":
return data["data"]["output"]
if status == "fail":
raise RuntimeError(data["data"].get("error"))
# queued / handling / archiving → continua ad attendere
raise TimeoutError(f"task {task_id} non ha raggiunto lo stato finale entro {max_wait}s")
Nota che la determinazione dello stato finale riconosce solo success e fail; tutti gli altri stati (queued / handling / archiving) continuano ad attendere, e il timeout è deciso dal tuo max_wait.
Quando passare all'escalation
- Con retry con backoff per 3 volte, ogni volta lo stesso
data.error.code→ non è un jitter transitorio, cambia input o modello. - L'attività resta a lungo in
queuedsenza alcun progresso → vai alla console hiapi per vedere se ci sono notifiche della piattaforma, e apri un ticket con ilrequest_id. data.statusè giàsuccessma il callback non arriva mai → smetti di affidarti al callback per quell'endpoint e passa al polling.
Link interni correlati
- Diagnosi dei timeout delle attività HiAPI e degli errori 504 — quando l'attività fallisce davvero con
TASK_TIMEOUT, o quando vedi un 504 letterale. - Perché il callback delle attività hiapi non si attiva — articolo dedicato al "falso blocco" dovuto al mancato callback.
- Diagnosi dell'errore API Key non valida|Errore modello non disponibile|Errore di rate limit 429
FAQ
D: Quanto tempo equivale a "timeout"? Esiste una durata di timeout uniforme?
R: Non c'è un numero uniforme, dipende dal modello; le attività pesanti (video lunghi, alta risoluzione) richiedono più tempo. Inoltre hiapi non ha uno stato timeout lato server — il cosiddetto timeout è di solito il tuo ciclo di polling che raggiunge il limite che hai impostato. Un'attività che va davvero in timeout lato server sarà data.status:"fail" + error.code:"TASK_TIMEOUT"; in quel caso vedi guida timeout e 504.
D: L'attività è in queued da 30 secondi, conviene annullare e riprovare?
R: No. 30 secondi rientrano nella norma per qualsiasi modello non banale; attendi almeno due minuti prima di considerare un retry.
D: Si può annullare un'attività in esecuzione? R: In genere l'annullamento non è supportato; anche se fosse possibile, la coda / lo slot di calcolo sono di solito già occupati. Conviene lasciarla completare e interrogare il risultato.
D: La stessa richiesta funzionava ieri, oggi è bloccata? R: Nella stragrande maggioranza dei casi è arretrato in coda a livello di modello (causa 1). Passa a un modello con capacità simili, oppure attendi 5–10 minuti che la coda si riduca e riprova.
D: Ogni attività va in timeout, è un problema del mio account? R: Vai prima alla console hiapi per vedere se ci sono notifiche a livello di account, poi verifica se sei soggetto a rate limit (vedi guida 429). Se è tutto normale e solo un certo modello fallisce, allora è probabilmente la coda o il backend di quel modello, non il tuo account.
D: Ritentare un'attività bloccata / in timeout comporta una doppia fatturazione?
R: Ogni POST /v1/tasks è una nuova attività fatturata. Le attività fallite che non producono risultati di solito non addebitano il costo di produzione, ma la coda / lo slot di calcolo potrebbero essere già occupati. Se ti interessa il costo, verifica a posteriori nella pagina di utilizzo.
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