Batas laju
kenari membatasi seberapa cepat kamu memanggil API di beberapa tempat. Halaman ini mendaftar setiap batas, error yang dikembalikan, dan cara mencoba ulang. Untuk format error dan kode lainnya, lihat Error.
Yang dikembalikan tiap batas
Section titled “Yang dikembalikan tiap batas”| Status | Kode | Retry-After | Yang perlu dilakukan |
|---|---|---|---|
| 429 | rate_limit_exceeded | Tidak, kecuali untuk musik | Tunggu beberapa detik lalu coba lagi. Beri jarak antar request. |
| 429 | free_quota_rpm | Ya | Tunggu selama jumlah detik yang tercantum di Retry-After, lalu coba lagi. |
| 429 | free_quota_daily | Ya, sampai 00:00 UTC | Jangan coba lagi hari ini. Pakai model berbayar, top up, atau tunggu reset. |
| 429 | plan_limit_reached | Tidak | Jangan coba ulang dalam loop. Aktifkan PAYG atau fallback gratis, atau tunggu jendela kuota direset. |
| 429 | upstream_error | Tidak | Provider sedang membatasi laju. Tunggu lalu coba lagi. |
| 503 | all_providers_failed | Ya, saat provider dijeda atau penuh | Tunggu selama jumlah detik yang tercantum di Retry-After, lalu coba lagi. |
Header Retry-After berisi jumlah detik. Kalau response tidak punya Retry-After, pakai exponential backoff.
Kode di tabel ini adalah kode error format OpenAI, yang dikembalikan Chat completions, Responses, dan endpoint lain. Error Messages tidak punya field code. Error itu membawa error.type, dan beberapa batas di atas muncul di sana sebagai rate_limit_error. Di Messages, tentukan penanganan dari status HTTP dan header Retry-After. Lihat Error.
Request per menit per akun
Section titled “Request per menit per akun”Setiap akun punya batas request per menit untuk model berbayar. Batas ini dipakai bersama oleh Chat completions, Messages, dan Responses. Kalau melewati batas, request gagal dengan 429 dan rate_limit_exceeded, tanpa header Retry-After. Batasnya diatur per akun, jadi bisa berbeda antar akun. Request ke model :free dihitung terhadap batas model gratis di bawah, dan endpoint lain tidak dihitung terhadap batas ini.
Pembacaan pemakaian
Section titled “Pembacaan pemakaian”Ketiga endpoint Pemakaian berbagi batas 60 request per menit untuk tiap akun. Kalau melewati batas, request gagal dengan 429 dan rate_limit_exceeded, tanpa header Retry-After. Batas ini dihitung terpisah dari batas akun di atas.
Pembuatan key per tool
Section titled “Pembuatan key per tool”Setiap key login bisa membuat 20 key per tool per menit. Kalau melewati batas, request gagal dengan 429 dan rate_limit_exceeded, tanpa header Retry-After. Melihat dan mencabut key tidak dibatasi.
Batas model gratis
Section titled “Batas model gratis”Setiap akun punya batas per menit dan kuota harian untuk model :free. Nilainya bergantung pada tier akunmu. Model gratis mendaftar tier-tiernya, dan GET /api/public/pricing mengembalikan angka terkini.
- Per menit. Kalau melewati batas, request gagal dengan
429danfree_quota_rpm, danRetry-Aftermenyebut sisa detik sampai jendela batas direset. - Per hari. Kuota harian menghitung request yang berhasil dan direset pukul 00:00 UTC. Kalau kuota habis, request gagal dengan
429danfree_quota_daily, danRetry-Afterberisi jumlah detik sampai reset. Top up atau berlangganan menaikkan kuota. - Lonjakan. Request gratis yang datang berdekatan diberi jarak dan dilayani satu per satu, bukan ditolak. Lonjakan yang terus-menerus ditolak dengan
429danrate_limit_exceeded. - Anggaran token. Model gratis bisa punya anggaran total token. Kalau sudah habis, model itu mengembalikan
429danrate_limit_exceededsampai jendela anggaran direset.
Response model gratis yang berhasil membawa X-RateLimit-Limit, X-RateLimit-Remaining, dan X-RateLimit-Reset kalau model itu punya batas per menit. X-RateLimit-Reset adalah Unix timestamp dalam detik.
Jendela kuota langganan
Section titled “Jendela kuota langganan”Langganan mencakup model-modelnya lewat jendela kuota. Saat sebuah jendela habis dan PAYG maupun fallback gratis tidak aktif, request ke model yang tercakup gagal dengan 429 dan plan_limit_reached, tanpa header Retry-After. message pada error ini ditulis dalam bahasa Indonesia, jadi gunakan code untuk menentukan penanganan error (di Messages, gunakan status dan error.type). Aktifkan PAYG atau fallback gratis di pengaturan langgananmu, atau tunggu jendela direset. Lihat Langganan.
Proses musik bersamaan
Section titled “Proses musik bersamaan”Setiap akun bisa menjalankan dua pembuatan musik sekaligus. Request ketiga gagal dengan 429 dan rate_limit_exceeded, dan Retry-After diatur 60 detik. Coba lagi setelah salah satu proses pembuatan musik selesai. Lihat Musik.
Batas dan gangguan provider
Section titled “Batas dan gangguan provider”Saat provider sebuah model membatasi laju kenari, kamu mendapat 429 dan upstream_error, tanpa header Retry-After. Saat provider timeout atau gagal, kamu mendapat 503 dan upstream_error. Saat semua provider untuk sebuah model sedang dijeda sementara atau penuh, kamu mendapat 503 dan all_providers_failed, dengan header Retry-After. Rute atau fallback BYOK bisa memindahkan request ke provider lain sebelum kamu melihat salah satu dari error ini. Lihat Routing & rute dan BYOK.
Key dibagikan
Section titled “Key dibagikan”API key dibagikan dibatasi lajunya sebagai satu kesatuan, jadi orang-orang yang memakai sebuah share tidak bisa menghabiskan batas akun pemiliknya. Setiap alamat IP klien juga dibatasi 30 request per menit pada satu API key dibagikan, baik di /v1 maupun di server MCP. Kalau melewati batas itu, response-nya 429 dengan body teks biasa too many requests, try again shortly, bukan JSON. Lihat Autentikasi & API key.
Coba ulang dengan aman
Section titled “Coba ulang dengan aman”Di Messages, terapkan aturan yang sama berdasarkan status HTTP, karena tidak ada code. Coba ulang hanya error yang bisa pulih sendiri: 429 dengan rate_limit_exceeded, free_quota_rpm, atau upstream_error, serta 503. Jangan coba ulang free_quota_daily, plan_limit_reached, atau 402 apa pun, karena kondisinya tetap sama sampai kamu mengubah sesuatu.
- Kalau response punya header
Retry-After, tunggu selama jumlah detik itu. - Kalau tidak, tunggu dengan exponential backoff dan jitter, misalnya 1, 2, 4, dan 8 detik, masing-masing ditambah pecahan detik acak.
- Berhenti setelah beberapa percobaan dan tampilkan error-nya.
SDK resmi OpenAI dan Anthropic sudah mencoba ulang response 429 dan 5xx beberapa kali secara bawaan dan mengikuti Retry-After. Naikkan jumlah percobaannya dengan max_retries kalau itu cukup. Contoh ini menunjukkan logikanya kalau kamu ingin mengendalikannya sendiri.
import osimport randomimport time
from openai import APIStatusError, OpenAI
client = OpenAI( base_url="https://kenari.id/v1", api_key=os.environ["KENARI_API_KEY"], max_retries=0,)
RETRYABLE = {"rate_limit_exceeded", "free_quota_rpm", "upstream_error", "all_providers_failed"}
def chat(messages, model="step-3-7-flash:free", attempts=5): for attempt in range(attempts): try: return client.chat.completions.create(model=model, messages=messages) except APIStatusError as error: retryable = error.status_code in (429, 503) and error.code in RETRYABLE if not retryable or attempt == attempts - 1: raise retry_after = error.response.headers.get("retry-after") delay = float(retry_after) if retry_after else min(30, 2**attempt) time.sleep(delay + random.random())
reply = chat([{"role": "user", "content": "Halo!"}])print(reply.choices[0].message.content)Jangan melanjutkan request yang gagal di tengah stream. Kirim ulang sebagai request baru.