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

# Rate Limiting

> Understand API rate limits and how to handle rate limit responses.

## Overview

thePurplebox API implements rate limiting to ensure fair usage and system stability. Rate limits vary based on your subscription plan and apply to both API calls and email sending.

## Rate Limits by Plan

### Free Plan

The Free plan has the following rate limits:

* **3 requests per minute** - Combined limit for both API calls and emails sent
* Applies to all endpoints including email sending and API operations

### Paid Plans

All paid plans (Starter, Growth, Business, Enterprise) have separate limits:

* **50 emails per minute** - For transactional email sending
* **50 API calls per minute** - For all other API operations (domains, retrieving emails, logs, etc.)

## How Rate Limiting Works

Rate limits are calculated on a **per-minute rolling window** basis. The counter resets every minute from your first request.

### Example Scenarios

#### Free Plan

```
Time: 10:00:00 - Send email #1 ✓
Time: 10:00:20 - Send email #2 ✓
Time: 10:00:40 - Send email #3 ✓
Time: 10:00:50 - Send email #4 ✗ (Rate limit exceeded)
Time: 10:01:01 - Counter resets, send email #5 ✓
```

#### Paid Plan - Emails

```
Send 50 emails within one minute ✓
51st email ✗ (Rate limit exceeded)
Wait for counter to reset
Continue sending ✓
```

#### Paid Plan - API Calls

```
Make 50 API calls (GET emails, verify domain, etc.) within one minute ✓
51st API call ✗ (Rate limit exceeded)
Wait for counter to reset
Continue API operations ✓
```

## Rate Limit Headers

Every API response includes headers that help you track your rate limit status:

```http theme={null}
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1700654400
```

### Header Descriptions

<ParamField header="X-RateLimit-Limit" type="number">
  The maximum number of requests allowed in the current time window.
</ParamField>

<ParamField header="X-RateLimit-Remaining" type="number">
  The number of requests remaining in the current time window.
</ParamField>

<ParamField header="X-RateLimit-Reset" type="number">
  Unix timestamp indicating when the rate limit counter resets.
</ParamField>

## Rate Limit Exceeded Response

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

```json theme={null}
{
  "status": 429,
  "message": "Rate limit exceeded. Please try again later.",
  "data": {
    "retry_after": 45,
    "limit": 3,
    "window": "1 minute"
  }
}
```

### Response Fields

<ResponseField name="status" type="number">
  HTTP status code. Always `429` for rate limit errors.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable error message.
</ResponseField>

<ResponseField name="data" type="object">
  Additional information about the rate limit.

  <Expandable title="properties">
    <ResponseField name="retry_after" type="number">
      Number of seconds to wait before making another request.
    </ResponseField>

    <ResponseField name="limit" type="number">
      Your current rate limit threshold.
    </ResponseField>

    <ResponseField name="window" type="string">
      The time window for the rate limit (e.g., "1 minute").
    </ResponseField>
  </Expandable>
</ResponseField>

## Best Practices

### 1. Monitor Rate Limit Headers

Always check the `X-RateLimit-Remaining` header before making bulk operations:

```javascript theme={null}
const response = await fetch('https://api.thepurplebox.io/v1/send', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(emailData)
});

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

console.log(`Requests remaining: ${remaining}`);
console.log(`Resets at: ${new Date(reset * 1000)}`);
```

### 2. Implement Exponential Backoff

When you receive a `429` response, implement exponential backoff:

```javascript theme={null}
async function sendWithRetry(emailData, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch('https://api.thepurplebox.io/v1/send', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(emailData)
      });

      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After') || Math.pow(2, i);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }

      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}
```

### 3. Batch Operations When Possible

For paid plans, spread out your requests to stay within limits:

```javascript theme={null}
// Instead of sending 150 emails immediately
// Batch them in groups of 50 per minute

async function batchSendEmails(emails) {
  const batchSize = 50;
  
  for (let i = 0; i < emails.length; i += batchSize) {
    const batch = emails.slice(i, i + batchSize);
    
    // Send batch
    await Promise.all(batch.map(email => sendEmail(email)));
    
    // Wait 1 minute before next batch
    if (i + batchSize < emails.length) {
      await new Promise(resolve => setTimeout(resolve, 60000));
    }
  }
}
```

## Upgrading Your Plan

If you consistently hit rate limits, consider upgrading your plan:

* **Free Plan**: 3 requests/min
* **Paid Plans**: 50 emails/min + 50 API calls/min

[Upgrade your plan](https://app.thepurplebox.io/settings/billing) to increase your rate limits.

## Need Higher Limits?

If you have a good sending reputation and need higher rate limits, we can increase your limits on a case-by-case basis. Contact us at [hello@thepurplebox.io](mailto:hello@thepurplebox.io) to discuss your sending needs and reputation metrics.
