Menangani Error 429 dan 402 di Hostlinku: Rate Limit, Limit Kredit, dan Strategi Retry
Kenali tiga lapisan limit di Hostlinku, baca header RateLimit-*, dan terapkan backoff eksponensial dengan jitter agar aplikasi tetap stabil saat trafik melonjak.

Hostlinku membatasi pemakaian di tiga lapisan yang saling melengkapi: rate limit (jumlah request per waktu), limit kredit per API key (biaya per jendela reset), dan saldo akun. Ketiganya dicek di server sebelum request diteruskan ke provider, jadi request yang ditolak tidak dikenakan biaya.
Berapa batasnya?
| Cakupan | Batas | Penentu |
|---|---|---|
POST /v1/chat/completions | 600 request / menit | Per API key |
Endpoint konsol & publik (/api/*) | 120 request / menit | Per alamat IP |
| Autentikasi (login, daftar, OTP) | 30 percobaan / 15 menit | Per alamat IP |
Setiap respons yang melewati limiter membawa header standar RateLimit-Limit, RateLimit-Remaining, dan RateLimit-Reset. Baca RateLimit-Reset untuk tahu kapan jendela berikutnya dimulai.
429 bukan 402
| Kode | Arti | Yang harus dilakukan |
|---|---|---|
429 RATE_LIMITED | Terlalu banyak request dalam jendela waktu | Tunggu RateLimit-Reset, backoff, atau kurangi konkurensi |
402 PAYMENT_REQUIRED | Saldo kurang atau limit kredit API key tercapai | Top-up saldo, atau tunggu reset / naikkan limit key |
Semua error memakai envelope yang sama: status: "error", error.code yang stabil untuk percabangan logika, dan error.message untuk manusia. Jangan retry 401 atau 402 — perbaiki konfigurasi atau saldonya dulu.
Backoff eksponensial dengan jitter
Untuk 429 dan 5xx sementara (UPSTREAM_ERROR, PROVIDER_UNAVAILABLE), tunggu lalu coba lagi dengan jeda yang makin panjang — 1 detik, 2 detik, 4 detik — ditambah sedikit acak agar banyak klien tidak menembak bersamaan.
import random, time
from openai import OpenAI, RateLimitError, APIStatusError
client = OpenAI(base_url="https://api.hostlinku.com/v1", api_key="sk-isi-api-key-kamu")
def chat_with_retry(messages, model="claude-sonnet-4-6", attempts=5):
for i in range(attempts):
try:
return client.chat.completions.create(model=model, messages=messages)
except RateLimitError as e:
reset = e.response.headers.get("RateLimit-Reset")
delay = float(reset) if reset else 2 ** i
except APIStatusError as e:
if e.status_code < 500:
raise # 401/402/422: perbaiki request, jangan retry
delay = 2 ** i
time.sleep(delay + random.uniform(0, 0.5))
raise RuntimeError("Gagal setelah beberapa percobaan")Pantau dari console
Menu Log Permintaan menampilkan status, token, biaya, dan latensi per request, sedangkan menu API Keys menunjukkan pemakaian dan limit tiap key. Saat melapor masalah, sertakan header x-request-id agar tim dukungan bisa menelusuri request tersebut. Baca selengkapnya di Pemakaian & Limit dan Error.


