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

# Rate Limits

> Understand API rate limits and how to handle them

The Bizzy API enforces per-minute rate limits to ensure fair usage and maintain
service stability for all users.

## Limits by Plan

Rate limits are applied per account and scale with your plan:

| Plan         | API requests per minute |
| ------------ | ----------------------- |
| Free         | 10                      |
| Starter      | 60                      |
| Professional | 300                     |
| Enterprise   | 1,000                   |

The limit is also the burst capacity: you can spend your full per-minute
allowance at once, and it replenishes continuously over the following minute.
See [Understanding Limits](/admin-guide/billing/limits) for how rate limits fit
into your plan.

## Rate Limit Headers

Every authenticated API response includes headers describing your current
allowance:

| Header                  | Description                                                       |
| ----------------------- | ----------------------------------------------------------------- |
| `X-RateLimit-Limit`     | Your plan's per-minute request limit (burst capacity)             |
| `X-RateLimit-Remaining` | Requests remaining right now                                      |
| `X-RateLimit-Reset`     | Seconds until your allowance is fully replenished                 |
| `Retry-After`           | On `429` responses only — seconds to wait before the next request |

## Handling Rate Limits

When you exceed your rate limit, the API returns a `429 Too Many Requests`
response:

```json theme={null}
{
    "error": {
        "code": "RATE_LIMITED",
        "message": "Rate limit exceeded. Retry after the number of seconds indicated by the Retry-After header."
    }
}
```

Wait the number of seconds given by the `Retry-After` header, then retry.

### Implementing Rate Limit Handling

<CodeGroup>
  ```typescript TypeScript theme={null}
  async function fetchWithRateLimit(
      url: string,
      options: RequestInit,
      attempt = 0,
  ): Promise<Response> {
      const response = await fetch(url, options);

      if (response.status === 429) {
          const retryAfter = response.headers.get('Retry-After');
          const retryAfterS =
              retryAfter === null ? Number.NaN : Number(retryAfter);
          // Fall back to exponential backoff if the header is ever missing.
          const waitMs = Number.isFinite(retryAfterS)
              ? retryAfterS * 1_000
              : Math.min(60_000, 1_000 * 2 ** attempt);
          console.log(`Rate limited. Waiting ${waitMs}ms before retry...`);

          await new Promise(resolve => setTimeout(resolve, waitMs));
          return fetchWithRateLimit(url, options, attempt + 1);
      }

      return response;

  }

  ```

  ```python Python theme={null}
  import time
  import requests

  def fetch_with_rate_limit(url, headers, attempt=0):
      response = requests.get(url, headers=headers)

      if response.status_code == 429:
          retry_after_s = int(response.headers.get('Retry-After', 2 ** attempt))
          print(f'Rate limited. Waiting {retry_after_s}s before retry...')

          time.sleep(retry_after_s)
          return fetch_with_rate_limit(url, headers, attempt + 1)

      return response
  ```
</CodeGroup>

## Best Practices

<AccordionGroup>
  <Accordion title="Implement request queuing">
    Instead of making requests as fast as possible, implement a queue that spreads requests evenly across your rate limit window.

    ```typescript theme={null}
    class RequestQueue {
        private queue: Array<() => Promise<void>> = [];
        private processing = false;
        private requestsPerSecond: number;

        constructor(requestsPerMinute: number) {
            this.requestsPerSecond = requestsPerMinute / 60;
        }

        async add<T>(fn: () => Promise<T>): Promise<T> {
            return new Promise((resolve, reject) => {
                this.queue.push(async () => {
                    try {
                        resolve(await fn());
                    } catch (e) {
                        reject(e);
                    }
                });
                this.process();
            });
        }

        private async process() {
            if (this.processing) return;
            this.processing = true;

            while (this.queue.length > 0) {
                const fn = this.queue.shift()!;
                await fn();
                await new Promise(r =>
                    setTimeout(r, 1000 / this.requestsPerSecond)
                );
            }

            this.processing = false;
        }
    }
    ```
  </Accordion>

  <Accordion title="Honor Retry-After on 429 responses">
    When you receive a 429 response, wait the number of seconds given by the
    `Retry-After` header before retrying. If you retry sooner, the request will
    simply be denied again.
  </Accordion>

  <Accordion title="Watch X-RateLimit-Remaining">
    Slow down proactively as `X-RateLimit-Remaining` approaches zero instead of
    running into 429s — for example, pause your queue until `X-RateLimit-Reset`
    seconds have passed.
  </Accordion>

  <Accordion title="Cache responses when possible">
    Reduce API calls by caching responses that don't change frequently. This is
    especially useful for reference data like contact lists or business details.
  </Accordion>

  <Accordion title="Batch operations">
    Where available, use batch endpoints to perform multiple operations in a single request instead of making separate calls.
  </Accordion>
</AccordionGroup>

## Increasing Your Limits

Rate limits scale with your plan — upgrading raises your per-minute limit. If
your integration genuinely needs a higher request rate than the Enterprise plan
provides, contact [support@bizzyco.ai](mailto:support@bizzyco.ai) to discuss
your use case.

## Next Steps

<CardGroup cols={2}>
  <Card title="Upgrade Your Plan" icon="arrow-up-right" href="https://www.bizzyco.ai/pricing">
    View pricing and upgrade options
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/api-reference/errors">
    Understand error responses and codes
  </Card>
</CardGroup>
