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

# Rate Limits

> Understanding API rate limits and best practices

The Chirp API enforces rate limits to ensure fair usage and maintain service quality for all users.

## Rate Limit Tiers

Rate limits vary by endpoint and API key type:

**App Keys**

* **SMS Sending**: 100 requests per minute
* **Webhook Management**: 60 requests per minute
* **General API**: 120 requests per minute

**Admin Keys**

* **Application Management**: 60 requests per minute
* **Organization Settings**: 60 requests per minute
* **General API**: 120 requests per minute

## Rate Limit Headers

Each API response includes headers indicating your current rate limit status:

```http theme={null}
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
```

**X-RateLimit-Limit**

The maximum number of requests allowed in the current window.

**X-RateLimit-Remaining**

The number of requests remaining in the current window.

**X-RateLimit-Reset**

Unix timestamp when the rate limit window resets.

## Rate Limit Exceeded

When you exceed the rate limit, the API returns:

**HTTP Status:** `429 Too Many Requests`

**Response:**

```json theme={null}
{
  "error": "Rate limit exceeded. Try again in 30 seconds."
}
```

**Headers:**

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

## Best Practices

**1. Implement Exponential Backoff**

When you receive a 429 response, wait before retrying:

```javascript theme={null}
async function sendWithRetry(payload, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(`$https://api.buildwithchirp.com/v1/sms`, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${apiKey}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify(payload),
      });

      if (response.status === 429) {
        const retryAfter = response.headers.get("Retry-After");
        await new Promise((r) => setTimeout(r, retryAfter * 1000));
        continue;
      }

      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await new Promise((r) => setTimeout(r, Math.pow(2, i) * 1000));
    }
  }
}
```

**2. Monitor Rate Limit Headers**

Track your usage by checking rate limit headers:

```javascript theme={null}
const response = await fetch(`$https://api.buildwithchirp.com/v1/sms`, options);

const limit = response.headers.get("X-RateLimit-Limit");
const remaining = response.headers.get("X-RateLimit-Remaining");
const reset = response.headers.get("X-RateLimit-Reset");

console.log(`${remaining}/${limit} requests remaining`);
console.log(`Resets at ${new Date(reset * 1000)}`);
```

**3. Batch Requests When Possible**

Send messages to multiple recipients in a single request:

```json theme={null}
{
  "from": "+15551234567",
  "to": ["+15559876543", "+15551112222", "+15553334444"],
  "text": "Bulk message"
}
```

**4. Implement Request Queuing**

Use a queue to manage high-volume sending:

```javascript theme={null}
class RateLimitedQueue {
  constructor(requestsPerMinute) {
    this.queue = [];
    this.interval = 60000 / requestsPerMinute;
  }

  async add(fn) {
    return new Promise((resolve, reject) => {
      this.queue.push({ fn, resolve, reject });
      if (this.queue.length === 1) {
        this.process();
      }
    });
  }

  async process() {
    while (this.queue.length > 0) {
      const { fn, resolve, reject } = this.queue[0];
      try {
        const result = await fn();
        resolve(result);
      } catch (error) {
        reject(error);
      }
      this.queue.shift();
      if (this.queue.length > 0) {
        await new Promise((r) => setTimeout(r, this.interval));
      }
    }
  }
}
```

**5. Cache When Appropriate**

Cache responses that don't change frequently:

* Webhook configurations
* Application settings
* Phone number assignments

## Higher Rate Limits

If you need higher rate limits for your use case, contact our sales team to discuss custom limits for your account.

## Test Mode

Rate limits also apply to test API keys, but test mode has more generous limits to facilitate development and testing.
