---
title: "Rate Limits"
description: "Per-route API limits, and the gateway global limit."
canonical: "https://developers.fnlb.net/docs/rate-limits"
markdown: "/docs/rate-limits.md"
---

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

# Rate Limits

The API and the gateway limit requests per IP address. They do not share a counter. Hitting a limit on one does not block the other.

A limited call returns `429` and this body:

```json
{
  "type": "error",
  "errors": [
    {
      "type": "general",
      "errorCode": "net.fnlb.errors.common.rate_limit_exceeded",
      "message": "You are being rate limited."
    }
  ]
}
```

Wait for the window to pass, then retry. Spread calls out instead of sending a burst and backing off every time.

## API

`https://api.fnlb.net/v1` has **no global limit**. Each route has its own window.

Most routes allow about **100 requests per 10 minutes** from one IP. A few are different on purpose:

| Route | API token or session | OAuth2 access token | Window |
| :--- | :--- | :--- | :--- |
| `GET /bots`, `POST /bots` | 100 | 100 | 10 minutes |
| Categories and presets | 100 | 1000 | 10 minutes |
| `POST /bots/{botId}/commands/run` | 250 | 1000 | 10 minutes |
| Friends, blocked users, user search | 250 | 1000 | 10 minutes |
| `GET /user` | 500 | 1000 | 5 minutes |
| `POST /oauth2/token` | 1000 | 1000 | 5 minutes |
| `POST /bots/bulk-export` | 2 | 5 | 10 minutes |
| `POST /bots/bulk-import` | 10 | 50 | 10 minutes |

Where the OAuth2 column is higher, a token that starts with `FNLBOA2AT_` gets that higher cap. An API token that starts with `FNLB_` gets the lower one.

Public routes, such as [GET /bots/public](/api?method=GET&path=/bots/public), are not rate limited.

The numbers above match the routes as they are enforced today. If you are building a client, treat `429` as the source of truth and keep the rest of your calls going. One busy route does not lock the account out of the others.

## Gateway

`https://gateway.fnlb.net/v1` has both a global limit and a per-route limit.

- **Global:** 100 requests per 10 seconds per IP, across every gateway route.
- **Bots:** [GET /bots](/gateway?method=GET&path=/bots) and [GET /bots/{botId}](/gateway?method=GET&path=/bots/{botId}) share 100 requests per minute.
- **Shards:** [GET /shards](/gateway?method=GET&path=/shards) allows 100 requests per minute.

A poller that asks for bots and shards together should stay under both. Once every 10 to 30 seconds is enough for a dashboard. The lists only include bots that are connected, so polling faster does not reveal offline bots.

## Retry

```javascript
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;
    await new Promise((resolve) => setTimeout(resolve, 10_000));
  }
  throw new Error('Rate limit exceeded after multiple retries.');
}
```

Queue work in your process so a loop cannot fire hundreds of command calls at once. For a higher cap on a specific integration, write to [support@fnlb.net](mailto:support@fnlb.net) and describe the routes and the volume.

<Card title="Join Discord" icon="discord" href="https://fnlb.net/discord">
  Ask about a limit you are hitting, or about an integration that needs more room.
</Card>
