Developer API · Best Practice

AgenWebsite Rate API memberlakukan dua batas: kuota harian per pengguna (Free 150 / Pro 30.000 / Max 60.000, reset 00:00 WIB) dan burst per menit (Free 20 / Pro 300 / Max 600). Setiap response menyertakan header X-RateLimit-Limit, X-RateLimit-Remaining, dan X-RateLimit-Reset; saat batas terlampaui API mengembalikan 429 dengan Retry-After. Best practice-nya: pantau header, caching agresif, dan backoff yang sopan.

Dua jenis batas: harian & burst

Kuota harian membatasi total request per hari; burst membatasi request per menit. Keduanya dihitung per request (bukan per baris kurir) dan berlaku per pengguna — dibagi bersama untuk semua API key milik akun.

Tier Kuota/hari Burst/menit Maks key aktif
Free 150 20 2
Pro 30.000 300 5
Max 60.000 600 20

Kuota harian direset otomatis pukul 00:00 WIB (Asia/Jakarta). Karena kuota bersifat per pengguna, menambah key tidak menambah jatah — semua key berbagi kuota yang sama. Detail ada di dokumentasi.

Header rate limit & status 429

Setiap response (sukses maupun gagal) menyertakan header berikut — gunakan untuk memantau sisa jatah tanpa panggilan ekstra:

Header Arti
X-RateLimit-Limit Kuota harian tier Anda
X-RateLimit-Remaining Sisa kuota hari ini
X-RateLimit-Reset Waktu reset kuota (00:00 WIB berikutnya)
Retry-After Hanya pada 429: detik sebelum boleh mencoba lagi

Ketika kuota harian habis atau burst per menit terlampaui, API mengembalikan 429 dengan amplop error konsisten:

JSON · Error 429
{
  "success": false,
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Kuota harian habis. Coba lagi setelah reset.",
    "request_id": "req_..."
  }
}

Caching: cara paling hemat kuota

Cara termurah menaikkan kapasitas efektif adalah caching, bukan menaikkan tier. Tarif untuk pasangan (asal, tujuan, berat, kurir) yang sama jarang berubah dalam hitungan menit. Cache hasil di sisi aplikasi Anda ~30 menit dapat memangkas panggilan hingga 60-80%.

Node.js · Redis cache
import { createClient } from "redis";
const redis = createClient();
await redis.connect();

async function cekOngkirCached({ originPc, destPc, weight, couriers }) {
  const key = `ongkir:${originPc}:${destPc}:${weight}:${couriers.sort().join(",")}`;

  const cached = await redis.get(key);
  if (cached) return JSON.parse(cached);

  const res = await fetch("https://api.agenwebsite.com/v1/rates", {
    method: "POST",
    headers: {
      "x-api-key": process.env.AGENWEBSITE_RATE_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      shipper: { postal_code: originPc },
      destination: { postal_code: destPc },
      weight,
      couriers,
    }),
  });

  const body = await res.json();
  if (!res.ok || !body.success) {
    throw new Error(body?.error?.message ?? "Gagal mengambil tarif.");
  }

  // Cache 30 menit; hemat kuota harian sekaligus percepat checkout.
  await redis.set(key, JSON.stringify(body.data.rates), { EX: 1800 });
  return body.data.rates;
}

Tambahan: debounce input kode pos di front-end agar API tidak dipanggil setiap ketikan, dan normalkan berat (mis. bulatkan ke 100 gram terdekat) agar cache key lebih sering hit.

Menangani 429 dengan backoff

Saat menerima 429, jangan langsung retry berulang — hormati Retry-After dan pakai exponential backoff. Untuk burst (per menit), Retry-After biasanya kecil; untuk kuota harian, sebaiknya tampilkan tarif dari cache dan tunda panggilan baru.

Node.js · Retry + backoff
async function requestDenganRetry(payload, maxRetry = 3) {
  for (let attempt = 0; attempt <= maxRetry; attempt++) {
    const res = await fetch("https://api.agenwebsite.com/v1/rates", {
      method: "POST",
      headers: {
        "x-api-key": process.env.AGENWEBSITE_RATE_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify(payload),
    });

    if (res.status !== 429) return res.json();

    // Hormati Retry-After; fallback ke backoff eksponensial + jitter.
    const retryAfter = Number(res.headers.get("Retry-After")) || 2 ** attempt;
    const jitter = Math.random() * 0.3 * retryAfter;
    await new Promise((r) => setTimeout(r, (retryAfter + jitter) * 1000));
  }
  throw new Error("Rate limit: gagal setelah beberapa percobaan.");
}

Untuk kuota harian yang benar-benar habis, backoff tidak membantu sampai reset 00:00 WIB — di titik ini, sajikan hasil cache atau pertimbangkan upgrade tier (berlaku seketika & prorata).

Memantau pemakaian & alert

Pantau kuota secara proaktif lewat GET /v1/usage agar bisa upgrade sebelum mentok di jam sibuk:

cURL · GET /usage
curl https://api.agenwebsite.com/v1/usage \
  -H "x-api-key: awk_live_xxxxxxxx"
JSON · Response
{
  "success": true,
  "data": {
    "plan": "pro",
    "limit": 30000,
    "used": 24180,
    "remaining": 5820,
    "reset_at": "2026-07-02T00:00:00+07:00"
  }
}

Set alert internal saat used/limit melewati 80% dan 95%. AgenWebsite juga mengirim email otomatis pada ambang kuota 80%, 95%, dan saat over-quota, sehingga Anda tidak kaget saat trafik melonjak.

Checklist toko volume tinggi

Praktik Kenapa
Cache 30 menit per (asal, tujuan, berat, kurir) Memangkas 60-80% panggilan; hemat kuota & percepat checkout
Normalkan berat & kode pos sebelum cache key Menaikkan rasio cache hit
Debounce input di front-end Mencegah pemborosan saat user mengetik
Baca X-RateLimit-Remaining tiap response Deteksi dini sebelum kena 429
Hormati Retry-After + backoff eksponensial Retry sopan, hindari badai request
Fallback ke cache saat 429/502 Checkout tetap jalan walau upstream bermasalah
Satu request multi-kurir Minta 5 kurir sekaligus tetap 1 kuota — jangan panggil per kurir
Cek meta.partial & meta.couriers_failed Tangani kegagalan sebagian dengan anggun
Alert di 80% & 95% kuota Waktu untuk upgrade sebelum mentok

FAQ

Apa beda kuota harian dan burst per menit?

Kuota harian membatasi total request per hari (Free 150, Pro 30.000, Max 60.000) dan reset 00:00 WIB. Burst membatasi request per menit (Free 20, Pro 300, Max 600) untuk mencegah lonjakan mendadak. Keduanya per pengguna.

Bagaimana cara menangani status 429?

Hormati header Retry-After sebelum mencoba lagi, gunakan exponential backoff dengan jitter, dan sajikan tarif dari cache jika ada. Untuk kuota harian yang habis, tunggu reset atau upgrade tier.

Apakah menambah API key menambah kuota?

Tidak. Kuota bersifat per pengguna dan dibagi bersama semua key milik akun tersebut. Menambah key hanya berguna untuk pemisahan lingkungan, bukan menambah jatah.

Apakah caching mengurangi pemakaian kuota?

Ya, signifikan. Menyimpan hasil per (asal, tujuan, berat, kurir) selama sekitar 30 menit dapat memangkas 60-80% panggilan API, sehingga kuota harian jauh lebih awet.

Kapan sebaiknya upgrade tier?

Saat pemakaian rutin melewati 80-95% kuota harian meski caching sudah optimal. Pantau lewat GET /v1/usage; upgrade berlaku seketika dan dihitung prorata untuk sisa periode.

Skalakan dengan aman. Dapatkan API key gratis dan pelajari detail kuota, header, serta penanganan error di dokumentasi.