Dokumentasi
Kesalahan
Kunavo mengembalikan isi kesalahan berformat OpenAI dengan kode status HTTP yang menunjukkan apakah Anda perlu mencoba ulang. Gunakan penanganan kesalahan standar OpenAI SDK agar tidak mengalami masalah.
Setiap respons non-2xx memiliki bentuk JSON yang sama — standar OpenAI. Cocokkan error.code untuk penanganan terprogram dan status_code untuk kebijakan percobaan ulang.
Isi kesalahan
{
"error": {
"message": "Model 'xyz-2025' is not available",
"type": "model_not_found",
"code": "model_not_found",
"param": null
}
}| Kolom | Tipe | Catatan |
|---|---|---|
message | string | Dapat dibaca manusia. Aman untuk dicatat dalam log; tidak pernah menyertakan rahasia. |
type | string | Kategori umum (authentication_ |
code | string | Pengidentifikasi terperinci. Gunakan untuk percabangan terprogram. |
param | string|null | Jika error terkait dengan field tertentu, sebutkan nama field tersebut. |
Kode status HTTP
| HTTP | Makna | Retry? |
|---|---|---|
| 400 | invalid_ — payload Anda tidak valid. | Tidak — perbaiki permintaan. |
| 401 | authentication_ — API key buruk / tidak ada / dicabut. | Tidak — rotasi key. |
| 402 | insufficient_ — saldo dompet kosong (code: insufficient_) atau batas bulanan tercapai. | Tidak — isi saldo di /app/Retry-After berarti pengisian saldo otomatis sedang berlangsung; coba lagi setelahnya. |
| 403 | permission_ — key valid, tetapi daftar izin IP-nya tidak mencakup alamat Anda. | Tidak — lakukan panggilan dari alamat yang diizinkan. |
| 404 | model_ — ID model tidak dikenal atau dinonaktifkan. | Tidak — periksa /v1/models. |
| 404 | missing_ — path endpoint di api./v1, atau POST ke host dasar. | Tidak — atur URL dasar ke https://api. |
| 404 | unknown_url — tidak ada endpoint di path tersebut di bawah /v1; pesan menyebutkan endpoint terdekat. | Tidak — perbaiki path. |
| 408 | Waktu tunggu permintaan klien habis. | Ya, dengan memperhatikan idempotensi. |
| 422 | upstream_422 — penyedia upstream menolak input Anda (misalnya, ukuran tidak didukung). | Tidak — sesuaikan input. |
| 429 | Dibatasi oleh laju — terlalu banyak panggilan serentak. | Ya — jeda eksponensial. |
| 500 | Error internal Kunavo. | Ya — jeda singkat. |
| 502 | upstream_ — penyedia upstream gagal. | Ya — jeda eksponensial. |
| 504 | Waktu tugas habis (pembuatan gambar / video melampaui batas polling kami). | Ya, tetapi perkirakan akan ada biaya. |
POST /v1/videos, POST /v1/audio/music/jobs, atau permintaan gambar dengan async atau webhook_url: "https://…"): tugas mungkin telah dibuat sebelum terjadi kesalahan, dan tugas yang sudah ada akan berjalan serta ditagih setelah selesai.Anggap respons 5xx pada pengiriman seperti itu sebagai hasil yang belum diketahui, bukan kegagalan. Kirim header Idempotency-Key pada setiap pengiriman seperti itu: setelah respons 5xx, permintaan yang sama dengan kunci yang sama akan mengembalikan tugas jika sudah ada dan memulainya jika belum ada.
Panggilan yang jawabannya tidak pernah sampai kepada Anda juga bukan panggilan yang gagal. Permintaan sinkron yang berjalan melampaui batas waktu klien Anda tetap berjalan hingga selesai dan ditagih. Stream yang Anda tutup lebih awal juga tetap berjalan hingga selesai dan ditagih untuk seluruh respons, bukan hanya untuk bagian yang sudah Anda baca.
Kode error umum
authentication_error
- Lupa mengatur header
Authorization: Bearer .... - API key dicabut dari
/app/keys. - Key masih memiliki prefiks yang salah (harus diawali dengan
sk-kn-).
insufficient_quota
- Saldo dompet terlalu rendah untuk permintaan ini →
error.codeadalahinsufficient_balance, dan error tersebut menyertakan jumlah saldo dompet (balance_usd), jumlah yang perlu ditahan untuk permintaan ini (needed_usd), serta dua tautan:topup_urlmembuka halaman penagihan dengan pengisian saldo yang sudah terpilih, sedangkanauto_recharge_urlmembukanya di pengaturan pengisian saldo otomatis. Kedua tautan tidak dengan sendirinya membebankan biaya apa pun. - Batas bulanan per key tercapai. Batas direset pada awal bulan kalender (UTC). Naikkan batas di
/app/keys.
{
"error": {
"message": "Wallet balance is too low for this request. Top up at https://kunavo.com/app/billing. Once a top-up has been paid, you can also turn on auto-recharge there: a saved card then refills the wallet when its balance falls under a threshold you choose.",
"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"
}
}Respons 402 karena saldo dompet berarti jumlah yang perlu ditahan untuk permintaan melebihi balance_usd dikurangi jumlah yang ditahan oleh permintaan dan tugas yang sedang berjalan. Jika pengisian saldo otomatis aktif, Kunavo terlebih dahulu mengisi saldo dompet melalui metode pembayaran yang tersimpan, tetapi hanya apabila balance_usd berada di bawah ambang pengisian otomatis yang Anda tetapkan dan batasan pengisian mengizinkannya, lalu mencoba permintaan itu sekali lagi. Jika pengisian tidak dilakukan atau tidak mencukupi, permintaan ditolak, sehingga respons 402 tetap bisa muncul meskipun pengisian saldo otomatis aktif.
Hentikan percobaan ulang pada insufficient_balance kecuali respons memiliki header Retry-After — header tersebut berarti pengisian saldo otomatis sedang menagih kartu tersimpan Anda, dan permintaan yang sama seharusnya berhasil beberapa detik kemudian.
GET /v1/balance mengembalikan saldo dompet, jumlah yang ditahan untuk tugas yang masih berjalan, dan sisa setiap batas bulanan. Anda dapat memanggilnya kapan saja: tidak diperlukan permintaan yang ditolak untuk melihat angka-angka ini. Respons 402 untuk batas bulanan tidak menyertakan balance_usd maupun needed_usd: pesannya menyebutkan batas mana yang telah tercapai, dan endpoint tersebut menunjukkan sisa setiap batas. Lihat Saldo.
permission_error
- Key memiliki daftar izin IP dan panggilan Anda berasal dari alamat di luar daftar tersebut. Pesan menyebutkan alamat yang terdeteksi — tambahkan alamat itu (atau blok CIDR-nya) di
/app/keys, atau hapus seluruh daftar izin agar semua alamat diizinkan. - Memindahkan agen ke host baru, gateway NAT baru, atau laptop di jaringan lain akan mengubah alamat tersebut. Key tanpa daftar izin tidak akan pernah ditolak karena alasan ini.
model_not_found
- Slug salah eja. Gunakan /models untuk daftar kanonis.
- Model saat ini dinonaktifkan (gangguan upstream atau peninjauan harga).
upstream_error
Menunjukkan bahwa penyedia model upstream mengembalikan error yang tidak dapat kami terjemahkan menjadi kode yang lebih spesifik. Isi respons mencakup pesan asli. Penyebab umum:
- Beban berlebih di sisi penyedia.
- Penolakan moderasi konten (coba prompt lain).
- Pembatasan wilayah / ketersediaan.
Strategi percobaan ulang
Pola tangguh yang paling sederhana: jeda eksponensial dengan jitter hanya untuk 429 / 5xx.
import os
import random
import time
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"}],
))- Batasi waktu tunggu hingga 30 detik per percobaan dan total hingga 5 percobaan.
- Jangan coba ulang 4xx (kecuali 408 dan 429). Melakukannya hanya membuang waktu.
- Pembuatan gambar, video, dan musik tidak idempoten: percobaan ulang memulai pembuatan baru dan ditagih jika berhasil. Untuk video, musik, dan gambar, header
Idempotency-Keyditerima pada pengiriman asinkron (POST /v1/videos,POST /v1/audio/music/jobs, dan kedua endpoint gambar dengan"async": trueatauwebhook_url): pengiriman ulang dengan kunci yang sama mengembalikan tugas pertama. - Untuk chat yang memiliki efek samping dalam kode Anda sendiri, lakukan deduplikasi melalui kunci idempotensi di lapisan aplikasi Anda.
Men-debug dari dasbor
Setiap panggilan API — berhasil maupun gagal — terlihat di /app/usage. Klik baris mana pun untuk membuka halaman detail permintaan/respons lengkap:
- Kode status HTTP yang dikembalikan kepada klien.
- Kode error upstream (jika berlaku).
- Latensi, IP permintaan, agen pengguna.
- Memfilter berdasarkan status membantu menemukan pola (misalnya, semua respons 422 pada model tertentu).
Melaporkan insiden
Jika Anda melihat error 5xx yang terus terjadi pada model yang seharusnya berfungsi, kirim email ke support@kunavo.com dengan informasi berikut:
- Slug model dan contoh isi permintaan (samarkan rahasia).
- Rentang waktu terjadinya kegagalan.
- Error
code+messagedari respons. - Jika memungkinkan, tautan log penggunaan dari
/app/usage/[id].
Waktu respons satu hari kerja; lebih cepat untuk masalah mendesak yang berdampak pada pendapatan.