Documentazione

Documentazione

Errori

Kunavo restituisce payload di errore nel formato OpenAI, con codici di stato HTTP che indicano se è opportuno ripetere la richiesta. È sufficiente attenersi alla gestione standard degli errori dell’SDK OpenAI.

Ogni risposta con codice diverso da 2xx ha la stessa struttura JSON, conforme allo standard OpenAI. Per la gestione programmatica, verifica error.code; per la strategia di ripetizione, verifica status_code.

Payload di errore

{
  "error": {
    "message": "Model 'xyz-2025' is not available",
    "type": "model_not_found",
    "code": "model_not_found",
    "param": null
  }
}
CampoTipoNote
messagestringLeggibile dall’utente. Sicuro da registrare nei log; non include mai segreti.
typestringCategoria generale (authentication_error, invalid_request_error, …).
codestringIdentificatore dettagliato. Da usare per diramazioni programmatiche.
paramstring|nullQuando l'errore riguarda un campo specifico, ne indica il nome.

Codici di stato HTTP

HTTPSignificatoRetry?
400invalid_request_error — il payload non è valido.No — correggi la richiesta.
401authentication_error — chiave API non valida, mancante o revocata.No — sostituisci la chiave.
402insufficient_quota — wallet vuoto (code: insufficient_balance) o limite mensile raggiunto.No — ricarica su /app/billing. Eccezione: un'intestazione Retry-After indica che è in corso una ricarica automatica; riprova dopo.
403permission_error — la chiave è valida, ma la relativa lista di indirizzi IP consentiti non include il tuo.No — effettua la chiamata da un indirizzo consentito.
404model_not_found — ID modello sconosciuto o disabilitato.No — controlla /v1/models.
404missing_v1_prefix — un percorso endpoint su api.kunavo.com senza /v1, oppure una richiesta POST all'host base.No — imposta l'URL di base su https://api.kunavo.com/v1.
404unknown_url — nessun endpoint a quel percorso sotto /v1; il messaggio indica quello più simile.No — correggi il percorso.
408Timeout della richiesta del client.Sì, prestando attenzione all'idempotenza.
422upstream_422 — il provider upstream ha rifiutato l'input (ad es. dimensione non supportata).No — modifica l'input.
429Limite di frequenza raggiunto — troppe chiamate simultanee.Sì — backoff esponenziale.
500Errore interno di Kunavo.Sì — attendi brevemente prima di riprovare.
502upstream_error — errore del provider upstream.Sì — backoff esponenziale.
504Timeout dell'attività (la generazione di immagini o video ha superato il budget di polling).Sì, ma il costo resta a tuo carico.
Le chiamate non riuscite (4xx + 5xx) non vengono addebitate. La riga del costo in usage_logs è pari a $0. Eccezione: i timeout 504 sulle API per attività di lunga durata possono mostrare un costo upstream se l'attività è stata completata ma non siamo riusciti a consegnare il risultato — un caso raro.

Codici di errore comuni

authentication_error

  • Hai dimenticato di impostare l'intestazione Authorization: Bearer ....
  • La chiave API è stata revocata da /app/keys.
  • La chiave ha ancora il prefisso errato (deve iniziare con sk-kn-).

insufficient_quota

  • Saldo del wallet insufficiente per questa richiesta → error.code è insufficient_balance e l'errore riporta il saldo del wallet (balance_usd), l'importo riservato da questa richiesta (needed_usd) e due link: topup_url apre la pagina di fatturazione con una ricarica preimpostata, auto_recharge_url la apre nelle impostazioni di ricarica automatica. Nessuno dei due link effettua addebiti da solo.
  • Limite mensile per chiave raggiunto. Si azzera all'inizio del mese di calendario (UTC). Aumenta il limite su /app/keys.
{
  "error": {
    "message": "Wallet balance is too low for this request. Top up at https://kunavo.com/app/billing — or turn on auto-recharge there, and a saved card refills the wallet before requests are refused.",
    "type": "insufficient_quota",
    "code": "insufficient_balance",
    "param": null,
    "balance_usd": 0.0142,
    "needed_usd": 0.0381,
    "topup_url": "https://kunavo.com/app/billing?topup=20",
    "auto_recharge_url": "https://kunavo.com/app/billing?autorecharge=1&src=api_402"
  }
}

Interrompi i tentativi su insufficient_balance, a meno che la risposta non contenga un'intestazione Retry-After — indica che è già in corso un addebito sulla carta salvata per la ricarica automatica; la stessa richiesta dovrebbe riuscire dopo pochi secondi.

permission_error

  • La chiave ha una lista di indirizzi IP consentiti e la chiamata proviene da un indirizzo esterno alla lista. Il messaggio indica l'indirizzo rilevato: aggiungilo (o aggiungi il relativo blocco CIDR) su /app/keys oppure rimuovi del tutto la lista per consentire qualsiasi indirizzo.
  • Spostare un agente su un nuovo host, un nuovo gateway NAT o un laptop connesso a un'altra rete cambia quell'indirizzo. Una chiave senza lista di indirizzi consentiti non viene mai rifiutata per questo motivo.

model_not_found

  • Slug scritto in modo errato. Usa /models per l'elenco canonico.
  • Il modello è attualmente disabilitato (interruzione del servizio upstream o revisione dei prezzi).

upstream_error

Indica che un provider upstream del modello ha restituito un errore che non siamo riusciti a tradurre in un codice più specifico. Il corpo della risposta include il messaggio originale. Cause comuni:

  • Sovraccarico lato provider.
  • Rifiuto da parte della moderazione dei contenuti (prova un prompt diverso).
  • Restrizioni di area geografica o disponibilità.

Strategia per i nuovi tentativi

Il modello robusto più semplice: backoff esponenziale con jitter solo per 429 / 5xx.

import time, random
from openai import OpenAI, RateLimitError, APIError

client = OpenAI(api_key=os.environ["KUNAVO_API_KEY"], base_url="https://api.kunavo.com/v1")

def call_with_retry(call, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            return call()
        except RateLimitError:
            if attempt + 1 == max_attempts: raise
            # 429: exponential backoff with jitter
            time.sleep(min(2 ** attempt, 30) + random.random())
        except APIError as e:
            if e.status_code and 500 <= e.status_code < 600 and attempt + 1 < max_attempts:
                time.sleep(min(2 ** attempt, 30) + random.random())
            else:
                raise

result = call_with_retry(lambda: client.chat.completions.create(
    model="claude-haiku-4-5",
    messages=[{"role": "user", "content": "hi"}],
))
  • Limita l'attesa a 30 secondi per tentativo e il totale a 5 tentativi.
  • Non riprovare con gli errori 4xx (eccetto 408 e 429). Farlo serve solo a perdere tempo.
  • La generazione di immagini e video non è idempotente: un nuovo tentativo è una nuova generazione e viene addebitato se va a buon fine. Una chiamata non riuscita non è mai stata addebitata, quindi riprovarla è sicuro. Per i video, POST /v1/videos accetta un header Idempotency-Key: un invio ripetuto con la stessa chiave restituisce la prima attività.
  • Per le chat con effetti collaterali nel tuo codice, deduplica tramite una chiave di idempotenza nel livello applicativo.

Debug dalla dashboard

Ogni chiamata API, riuscita o non riuscita, è visibile su /app/usage. Fai clic su una riga per aprire la pagina con i dettagli completi della richiesta e della risposta:

  • Codice di stato HTTP restituito al client.
  • Codice di errore upstream, se applicabile.
  • Latenza, IP della richiesta, user agent.
  • Filtrare per stato aiuta a individuare le tendenze (ad es. tutti gli errori 422 su un modello specifico).

Segnalare un problema

Se riscontri errori 5xx persistenti su un modello che dovrebbe funzionare, scrivi a support@kunavo.com indicando:

  • Lo slug del modello e un esempio del corpo della richiesta (rimuovi i dati riservati).
  • L'intervallo di tempo in cui si sono verificati gli errori.
  • L'errore code + message della risposta.
  • Se possibile, un link al registro di utilizzo da /app/usage/[id].

Tempo di risposta: un giorno lavorativo, più rapido per problemi urgenti che incidono sui ricavi.

Prossimi passi