Tutoriale
Risolvere gli errori di rate limit (429) di HiAPI: cause e soluzioni
Quando il gateway HiAPI restituisce HTTP 429 Too Many Requests, significa che la tua API Key ha superato, in un breve intervallo di tempo, la frequenza di richieste o il limite di concorrenza consentito su https://api.hiapi.ai/v1/tasks (o sull'endpoint di polling GET /v1/tasks/{taskId}). Il body della risposta segue l'envelope di errore uniforme di HiAPI — {"error":{"type":"hiapi_error","code":"...","request_id":"..."}} — ed è accompagnato da uno status code 429. Risolverlo non richiede quasi mai di scrivere all'assistenza: basta aggiungere al client un piccolo strato di «retry + throttling». Questo articolo spiega cos'è questo errore, perché viene attivato e i passaggi concreti per farlo sparire.
Che aspetto ha un 429 di HiAPI
Una richiesta tipica, a livello di rete, si presenta più o meno così:
> POST /v1/tasks HTTP/1.1
> Host: api.hiapi.ai
> Authorization: Bearer hi-sk-...
> Content-Type: application/json
< HTTP/1.1 429 Too Many Requests
< Content-Type: application/json
<
{"error":{"type":"hiapi_error","code":"rate_limit_exceeded","request_id":"req_..."}}
Due punti chiave:
- Lo status code è
429, non401/403.401indica che la Key è errata o mancante;429indica che la Key va bene ma stai inviando troppo velocemente. Non confondere le due cose. - Il body della risposta è JSON dentro l'envelope
hiapi_error. Alcuni client HTTP espongono di default solo lo status code; se il tuo codice esegue retry in modo silenzioso senza loggare, perdi indizi di diagnostica comerequest_id.
Se chiami modelli come GPT Image 2, Nano-Banana, flux, Seedance, Wan o HappyHorse, girano tutti sullo stesso endpoint asincrono dei task e quindi condividono lo stesso conteggio della frequenza per Key.
Cause comuni (in ordine di probabilità)
Secondo la nostra esperienza, dalla più alla meno probabile:
- Fan-out a raffica con una singola Key (burst fan-out). Iteri su un batch di prompt e chiami
POST /v1/tasksin modo concorrente per ciascuno, senza un limite di concorrenza. Anche solo una decina di creazioni di task concorrenti bastano a saturare un account nuovo. - Polling aggressivo su
GET /v1/tasks/{taskId}. Un ciclo strettowhile True: poll(); sleep(0.2)conta come richieste tanto quanto la creazione dei task. Il polling sub-secondo è la causa numero uno del «ho creato un solo task eppure ricevo ancora 429». - Limite di concorrenza a livello di account. I modelli più pesanti — video (
seedance-2.0,wan2.7-video/*,happyhorse-1.0) e le varianti immagine@pro— rientrano in limiti di task concorrenti più severi. Inviare molti di questi task tutti insieme può dare 429 anche se la frequenza al minuto non è elevata. - Una sola Key condivisa tra più ambienti. dev, staging e prod usano tutti la stessa
HIAPI_API_KEY, e i volumi si sommano. Preso singolarmente ogni ambiente va bene, ma insieme spingono la Key oltre il limite. - Quota del piano esaurita. Una quota gratuita o un piano a pagamento quasi esaurito a volte si manifesta come 429 anziché come errore di fatturazione, soprattutto durante le promozioni.
Sulle soglie specifiche: il numero di richieste al minuto e i limiti di concorrenza di HiAPI dipendono dal livello del tuo account; la piattaforma non pubblica un numero fisso. Quindi i valori di concorrenza indicati sotto (5, 3, 2) sono punti di partenza empirici, non limiti ufficiali — regolali in base all'utilizzo reale nella dashboard.
Passaggi per la soluzione
Procedi in ordine. La maggior parte dei team smette di ricevere avvisi già dopo il passaggio 3.
1. Aggiungi un backoff esponenziale con jitter
Qualsiasi client che comunica con api.hiapi.ai dovrebbe, davanti a un 429, ritentare con un ritardo crescente — mai ritentare immediatamente. Un'implementazione di default sicura:
import random, time, requests
def post_task_with_backoff(body, key, *, max_retries=5):
delay = 1.0
for attempt in range(max_retries):
r = requests.post(
"https://api.hiapi.ai/v1/tasks",
headers={"Authorization": f"Bearer {key}", "Content-Type": "application/json"},
json=body, timeout=30,
)
if r.status_code != 429:
r.raise_for_status()
return r.json()
retry_after = r.headers.get("Retry-After")
wait = float(retry_after) if retry_after else delay + random.random()
time.sleep(min(wait, 30.0))
delay = min(delay * 2, 30.0)
raise RuntimeError("rate-limited after retries")
Questo codice fa due cose giuste: limita il ritardo a un massimo di 30 secondi; e dà priorità all'header Retry-After quando presente. Anche se la tua risposta 429 non include Retry-After, la strategia «tetto massimo + jitter» basta ad assorbire la maggior parte delle raffiche.
2. Limita la concorrenza del client per Key
Aggiungere un semaforo (semaphore) sul client è la singola modifica più efficace. Se non sai quale valore usare, parti da 5:
import asyncio, httpx
sem = asyncio.Semaphore(5)
async def create_task(client, body):
async with sem:
r = await client.post("https://api.hiapi.ai/v1/tasks", json=body, timeout=30)
return r.json()
Cinque task in esecuzione contemporanea sono gestibili per la maggior parte degli account. Se ricevi ancora 429, scendi a 3. I modelli video pesanti di solito richiedono un semaforo separato e più basso (prova 2).
3. Passa dal polling a callback.url
Per i carichi di produzione, il polling su GET /v1/tasks/{taskId} non è un buon default. Passa callback.url nel body della richiesta e HiAPI invierà il risultato via POST quando il task raggiunge lo stato finale:
{
"model": "Nano-Banana",
"input": { "prompt": "a calm lake at dawn", "aspect_ratio": "16:9" },
"callback": { "url": "https://your-domain.com/hiapi/callback", "when": "final" }
}
Questo comprime il pattern di richieste da O(numero di task × numero di polling) a O(numero di task) — di solito una riduzione del volume di chiamate di 10–50 volte, e un rimedio quasi immediato ai 429 da polling. Lascia GET /v1/tasks/{taskId} per il debug locale e per le chiamate una tantum a bassa frequenza.
4. Rallenta il ritmo del polling e aggiungi jitter
Se non puoi usare i callback (script offline, notebook locale, riconciliazione di fallback), non fare polling più velocemente di ogni 2–5 secondi, e aggiungi jitter per evitare che più worker procedano all'unisono:
import random, time
time.sleep(2 + random.random() * 3) # 2–5 secondi, con jitter
5. Separa le Key per ambiente
Genera una Key distinta per ogni ambiente nella pagina delle chiavi API di HiAPI — dev, staging, prod. Le raffiche di ogni ambiente sono isolate l'una dall'altra, e se una Key viene compromessa puoi revocarla singolarmente senza influire sugli altri ambienti.
6. Controlla l'utilizzo attuale
Apri la dashboard di HiAPI per verificare se hai colpito il limite di concorrenza o del piano, oppure se si è trattato solo di una breve raffica; le quote dei vari piani sono confrontabili nella pagina dei prezzi. Se l'utilizzo è molto inferiore al piano e ricevi comunque 429, la causa è quasi certamente una raffica lato client, non l'account stesso.
Verifica minima
Una volta pronto lo strato di retry, un task Nano-Banana è il modo più economico per verificare se la catena funziona. Sostituisci $HIAPI_API_KEY con la tua Key:
curl -s -X POST https://api.hiapi.ai/v1/tasks \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "Nano-Banana",
"input": { "prompt": "a single red apple on a white table", "aspect_ratio": "1:1" }
}'
Un successo assomiglia a questo: {"code":200,"data":{"taskId":"tk-hiapi-..."}}. Poi fai un polling:
curl -s -H "Authorization: Bearer $HIAPI_API_KEY" \
https://api.hiapi.ai/v1/tasks/tk-hiapi-...
Lo stato passa per queued → handling → archiving → success, e il data.output[0].url finale è la tua immagine. Se questo singolo scambio restituisce 200 ma i tuoi task in batch ricevono ancora 429, il problema è la concorrenza lato client, non la tua Key.
Domande frequenti
Ho inviato un solo request, perché ricevo comunque 429?
Quasi sempre perché il volume reale di richieste viene dal ciclo di polling, non dalla creazione dei task. Fare polling di 5 task concorrenti a intervalli di 200ms significa da solo 25 richieste al secondo. Rallenta il polling a 2–5 secondi, oppure usa callback.url.
HiAPI include sempre l'header Retry-After?
Tratta Retry-After come un valore suggerito: usalo se c'è, altrimenti ricadi sul backoff esponenziale (1s, 2s, 4s… con tetto a 30s). In ogni caso non ritentare senza ritardo — non farebbe che amplificare la raffica.
429 e 401 / 403 sono la stessa cosa?
No. 401 / 403 indicano un fallimento di autenticazione e passano per lo stesso envelope hiapi_error, ad esempio {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"req_..."}} (nei test reali il message di un 401 segnala «This API key is invalid. Check that it is correct...»). Se vedi 401/403, controlla il valore della Key nella pagina delle chiavi API — il backoff non può salvarti.
Posso semplicemente alzare il limite di frequenza?
Se il tuo traffico richiede davvero un limite di concorrenza più alto, verifica prima le quote del piano nella pagina dei prezzi, poi contatta l'assistenza da lì. In pratica, le soluzioni sopra risolvono oltre il 90% dei problemi di 429 senza modificare alcun limite.
Qual è la differenza tra un 429 su /v1/tasks e un 429 su /v1/tasks/{taskId}?
L'endpoint ti dice solo cosa stavi facendo in quel momento — entrambi condividono lo stesso budget di frequenza per Key. Il 429 sull'endpoint di creazione indica un fan-out (limita la concorrenza, passa al batch); il 429 sull'endpoint di polling indica un ciclo di polling stretto (rallenta il ritmo o passa ai callback). Per la struttura completa di request/response vedi HiAPI Quickstart e la documentazione sull'autenticazione.
Riepilogo
Il 429 è un segnale normale e recuperabile che qualsiasi gateway API di livello produttivo restituisce. Aggiungi backoff esponenziale, limita la concorrenza del client, sostituisci il polling con i callback e verifica l'utilizzo nella dashboard. Fatte bene queste quattro cose, puoi smettere del tutto di pensare al 429. Questa pagina è la versione in cinese semplificato dell'originale inglese «How to Fix HiAPI Rate Limit (429) Errors»; i dettagli tecnici sono coerenti con l'originale.
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