L'obiettivo delle API compatibili con OpenAI è che l'SDK funzioni subito — quindi, quando restituisce 401, il bug è quasi sempre nelle due righe modificate: base_url e api_key. Ecco i casi di errore nell'ordine in cui si verificano realmente.
L’errore
{
"error": {
"type": "invalid_api_key",
"message": "Invalid or missing API key.",
"code": "invalid_api_key"
}
}Cause e soluzioni in breve
| Causa | Soluzione |
|---|---|
| base_url senza suffisso /v1 (o con suffisso duplicato) | La maggior parte dei gateway richiede esattamente https://host/v1 — l'SDK aggiunge autonomamente /chat/completions. |
| Chiave di un host diverso | Le chiavi sk-… autenticano solo presso il servizio che le ha emesse; verifica la corrispondenza tra prefisso e host. |
| Proxy aziendale / WAF che rimuove l'header Authorization | Esegui il test da una rete pulita; configura il proxy affinché inoltri Authorization. |
| La variabile d'ambiente OPENAI_API_KEY sovrascrive la chiave esplicita | L'SDK legge le variabili d'ambiente per impostazione predefinita — in alcune configurazioni una variabile obsoleta prevale silenziosamente; passa api_key in modo esplicito. |
Verifica l'URL esatto raggiunto dall'SDK
Stampa client.base_url ed esegui GET /v1/models — è l'endpoint autenticato più economico. Se /models funziona, l'autenticazione è corretta e l'errore si trova altrove:
from openai import OpenAI
client = OpenAI(
base_url="https://api.kunavo.com/v1", # exactly one /v1
api_key="sk-kn-...", # explicit beats env vars
)
print(client.base_url)
print([m.id for m in client.models.list().data][:5])Usa Curl sullo stesso host per escludere l'SDK
Se curl con Authorization: Bearer funziona e l'SDK no, confronta la richiesta effettiva dell'SDK (imposta OPENAI_LOG=debug) — nove volte su dieci un proxy o una variabile d'ambiente ha riscritto qualcosa.
Se chiami tramite Kunavo
L'endpoint di Kunavo segue rigorosamente il formato OpenAI su https://api.kunavo.com/v1 con autenticazione Bearer, e GET /v1/models funziona come test rapido dell'autenticazione. Se il tuo codice usa api.openai.com, cambiare base_url in Kunavo è l'unica modifica necessaria — stesso SDK, stesso formato sul filo, una chiave per Claude, GPT e i modelli multimediali.
Domande frequenti
401 contro 403 su un gateway — qual è la differenza?
401 = la credenziale non è stata accettata (chiave mancante/non valida). 403 = la chiave è valida ma non autorizzata all'operazione (chiave disabilitata, account sospeso, modello non consentito). Leggi il corpo dell'errore — le API compatibili inseriscono il motivo in error.message.
Perché il mio codice funziona in locale ma restituisce 401 in CI?
CI è un ambiente diverso: il segreto non è impostato, è impostato per un servizio diverso oppure un proxy rimuove l'header. Registra repr(key[:12]) e base_url dall'interno di CI per vedere cosa viene realmente inviato.
Guide correlate
Ulteriori dettagli sul significato degli errori sono disponibili in riferimento agli errori; ottenere una chiave richiede un minuto tramite registrazione e la guida all’autenticazione.