> ## Documentation Index
> Fetch the complete documentation index at: https://docs.leuwongrr.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate Limits

> Batas penggunaan LeuwongRR User API dan cara menangani response 429.

# Rate Limits

LeuwongRR User API memakai rate limit untuk menjaga layanan tetap aman, stabil, dan nyaman digunakan oleh semua member.

Rate limit membantu mencegah:

* Spam request
* Penyalahgunaan API token
* Bot yang melakukan request terlalu sering
* Beban server berlebihan
* Akses mencurigakan dari sistem eksternal

<Note>
  Rate limit berlaku untuk request public safe endpoint dan User API Token yang dibuat dari halaman `https://leuwongrr.online/user/api-access`.
</Note>

## Batas request user API

Untuk penggunaan normal, batas berikut aman untuk website, bot, atau dashboard sederhana.

| Jenis limit             |              Batas rekomendasi |
| ----------------------- | -----------------------------: |
| Public read endpoint    |             60 request / menit |
| User read endpoint      |             60 request / menit |
| Create order endpoint   |             10 request / menit |
| Token validate endpoint |             30 request / menit |
| Request paralel         | Maksimal 2–3 request bersamaan |
| Token lewat URL         |                Tidak diizinkan |
| Token lewat header      |                          Wajib |

<Warning>
  Jangan polling setiap 1 detik. Request terlalu agresif dapat terkena `429 Too Many Requests`.
</Warning>

## Endpoint yang dihitung rate limit

```txt theme={null}
GET  /api/v1/health
POST /api/v1/auth/token/validate
GET  /api/v1/catalog/robux-packages
GET  /api/v1/catalog/payment-methods
GET  /api/v1/articles
GET  /api/v1/articles/{slug}
GET  /api/v1/me
GET  /api/v1/me/dashboard-summary
GET  /api/v1/me/balance
GET  /api/v1/me/balance/transactions
GET  /api/v1/me/deposits
GET  /api/v1/me/deposits/{invoice}
POST /api/v1/me/orders
GET  /api/v1/me/orders
GET  /api/v1/me/orders/{invoice}
GET  /api/v1/me/invoices/{invoice}
GET  /api/v1/me/invoices/{invoice}/status
```

## Response jika terkena rate limit

Jika request terlalu sering, API dapat mengembalikan:

```txt theme={null}
429 Too Many Requests
```

Contoh response:

```json theme={null}
{
  "success": false,
  "message": "Terlalu banyak request. Silakan coba lagi beberapa saat."
}
```

## Header rate limit

Jika tersedia, response API dapat menyertakan header berikut:

| Header                  | Keterangan                                    |
| ----------------------- | --------------------------------------------- |
| `Retry-After`           | Waktu tunggu dalam detik sebelum mencoba lagi |
| `X-RateLimit-Limit`     | Batas request periode saat ini                |
| `X-RateLimit-Remaining` | Sisa request yang masih tersedia              |
| `X-RateLimit-Reset`     | Waktu reset limit dalam Unix timestamp        |

Contoh:

```http theme={null}
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1760000000
```

Jika menerima status `429`, tunggu sesuai nilai `Retry-After` sebelum mencoba lagi.

## Rekomendasi interval request

| Kebutuhan              |                                 Rekomendasi |
| ---------------------- | ------------------------------------------: |
| Cek status invoice     |                          Setiap 10–30 detik |
| Cek daftar order       |                          Setiap 30–60 detik |
| Cek saldo              | Saat halaman dibuka atau setiap 30–60 detik |
| Cek profil `/me`       |            Saat login / saat halaman dibuka |
| Bot command manual     |               Saat user menjalankan command |
| Auto refresh dashboard |                         Minimal 15–30 detik |

## Cara retry yang aman

Gunakan exponential backoff sederhana:

```js theme={null}
async function fetchWithRetry(url, options, retries = 3) {
  for (let attempt = 0; attempt <= retries; attempt++) {
    const response = await fetch(url, options);

    if (response.status !== 429) {
      return response;
    }

    const retryAfter = Number(response.headers.get('Retry-After') || 5);
    await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
  }

  throw new Error('Rate limit exceeded. Please try again later.');
}
```

## Praktik terbaik

* Simpan token di backend/server/bot
* Jangan simpan token di frontend JavaScript
* Jangan upload token ke GitHub
* Gunakan HTTPS
* Gunakan cache ringan untuk data yang sering dibaca
* Hindari request berulang terlalu cepat
* Regenerate token jika dicurigai bocor
