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

# Rate limits

> Per-minute request limits by plan, and how to handle 429s

Rate limits apply to every endpoint across the WhatsApp, Platform, and Workflows APIs. They are counted per API key, or per IP when no key is present.

## Requests per minute

| Plan       | Requests / minute |
| ---------- | ----------------- |
| Free       | 100               |
| Legacy     | 100               |
| Pro        | 500               |
| Platform   | 1000              |
| Enterprise | 2000              |

The window is a fixed minute, not a rolling one. A project with no active plan gets the free limit.

## Response headers

Every response carries your current state:

```
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
```

When you exceed the limit, Kapso returns `429` with:

```
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 0
Retry-After: 60
```

```json theme={null}
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded the rate limit. Please try again later."
}
```

Read `X-RateLimit-Remaining` and back off before you hit zero, rather than waiting for the 429.

## Workflow execution burst limit

Starting workflow executions has a second, tighter limit measured **per second and per workflow**. It stops a single runaway workflow from consuming your whole per-minute budget.

| Plan       | Executions / second / workflow |
| ---------- | ------------------------------ |
| Free       | 5                              |
| Legacy     | 5                              |
| Pro        | 15                             |
| Platform   | 30                             |
| Enterprise | 30                             |

Exceeding it returns `429` with its own headers:

```
X-Burst-RateLimit-Limit: 15
X-Burst-RateLimit-Remaining: 0
Retry-After: 1
```

## Meta's limits are separate

The WhatsApp API proxies Meta. Meta enforces its own throughput and messaging limits on top of Kapso's, so a request can pass Kapso's limit and still be rejected upstream:

```json theme={null}
{
  "error": "Meta API rate limit exceeded. Retry after 60 seconds"
}
```

Your WABA messaging tier controls how many business-initiated conversations you can start per day. See [Meta's messaging limits](https://developers.facebook.com/docs/whatsapp/messaging-limits/).

Broadcasts are not affected by this. Kapso paces them internally to stay within throughput limits, so you do not need to throttle a broadcast yourself.

## Handling 429

Retry with exponential backoff, honoring `Retry-After`:

```typescript theme={null}
async function callWithRetry(url: string, options: RequestInit, attempt = 0) {
  const res = await fetch(url, options);

  if (res.status !== 429 || attempt >= 5) return res;

  const wait = Number(res.headers.get('Retry-After') ?? 60) * 1000;
  await new Promise((r) => setTimeout(r, wait * 2 ** attempt));

  return callWithRetry(url, options, attempt + 1);
}
```
