Inti dari API yang kompatibel dengan OpenAI adalah SDK langsung berfungsi — jadi ketika muncul 401, bug hampir selalu berada pada dua baris yang Anda ubah: base_url dan api_key. Berikut mode kegagalan dalam urutan kemunculannya di dunia nyata.
Error
{
"error": {
"type": "invalid_api_key",
"message": "Invalid or missing API key.",
"code": "invalid_api_key"
}
}Ringkasan penyebab dan perbaikan
| Penyebab | Perbaikan |
|---|---|
| base_url tidak memiliki sufiks /v1 (atau menggandakannya) | Sebagian besar gateway menginginkan https://host/v1 persis — SDK menambahkan /chat/completions sendiri. |
| Kunci dari host lain | Kunci sk-… hanya mengautentikasi terhadap layanan yang menerbitkannya; periksa kecocokan prefix ↔ host. |
| Proxy perusahaan / WAF menghapus header Authorization | Uji dari jaringan yang bersih; konfigurasikan proxy agar meneruskan Authorization. |
| Variabel env OPENAI_API_KEY menimpa kunci eksplisit Anda | SDK membaca env secara default — variabel env lama dapat menang secara diam-diam dalam beberapa pengaturan; teruskan api_key secara eksplisit. |
Verifikasi URL persis yang dipanggil SDK
Cetak client.base_url dan panggil GET /v1/models — endpoint terautentikasi termurah. Jika /models berfungsi, autentikasi baik dan error Anda berada di tempat lain:
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])Lakukan curl ke host yang sama untuk mengesampingkan SDK
Jika curl dengan Authorization: Bearer berhasil tetapi SDK tidak, bandingkan permintaan aktual SDK (atur OPENAI_LOG=debug) — sembilan dari sepuluh kali, proxy atau variabel lingkungan menulis ulang sesuatu.
Jika Anda melakukan panggilan melalui Kunavo
Endpoint Kunavo berbentuk ketat seperti OpenAI di https://api.kunavo.com/v1 dengan autentikasi Bearer, dan GET /v1/models berfungsi sebagai uji autentikasi. Jika kode Anda berjalan terhadap api.openai.com, mengarahkan base_url ke Kunavo adalah satu-satunya perubahan — SDK yang sama, format wire yang sama, satu kunci untuk model Claude, GPT, dan media.
Pertanyaan umum
401 vs 403 pada gateway — apa perbedaannya?
401 = kredensialnya sendiri tidak diterima (kunci hilang/tidak valid). 403 = kuncinya valid tetapi tidak diizinkan melakukan tindakan tersebut (kunci dinonaktifkan, akun ditangguhkan, model tidak diizinkan). Baca isi error — API yang kompatibel menempatkan alasannya di error.message.
Mengapa kode saya bekerja secara lokal tetapi menghasilkan 401 di CI?
CI adalah lingkungan yang berbeda: secret belum diatur, diatur untuk layanan yang berbeda, atau proxy menghapus header. Catat repr(key[:12]) dan base_url dari dalam CI untuk melihat apa yang sebenarnya dikirim.
Panduan terkait
Detail semantik error lainnya tersedia di referensi error; mendapatkan kunci hanya perlu satu menit melalui pendaftaran dan panduan autentikasi.