# Rate Limits

> **Understanding API usage limits**

***

## Overview

The API implements rate limiting to ensure system stability. The current limit is:

**100 requests per minute** (per API key)

***

## Batch Sizes

Recommended batch sizes per entity:

| Entity        | Recommended | Maximum |
| ------------- | ----------- | ------- |
| **Customers** | 100-500     | 1,000   |
| **Orders**    | 50-200      | 500     |
| **Products**  | 50-100      | 200     |

**Why batch?**

* Fewer API calls = faster sync
* Lower network overhead
* Better error isolation

***

## Rate Limit Headers

Every response includes:

```http
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000
```

* `X-RateLimit-Limit`: Max requests per minute
* `X-RateLimit-Remaining`: Requests remaining
* `X-RateLimit-Reset`: Unix timestamp when limit resets

***

## Handling 429 Responses

When you exceed the limit:

```json
{
  "success": false,
  "message": "Rate limit exceeded. Retry after 60 seconds.",
  "data": {
    "retryAfter": 60
  }
}
```

Response includes `Retry-After` header (seconds to wait).

***

## Retry Strategy

Use exponential backoff when you get a 429:

```python
import time
import requests

def api_call_with_retry(url, data, max_retries=3):
    for attempt in range(max_retries):
        response = requests.post(url, json=data)
        
        if response.status_code == 200:
            return response.json()
        
        if response.status_code == 429:
            retry_after = int(response.headers.get('Retry-After', 60))
            print(f"Rate limited. Waiting {retry_after}s...")
            time.sleep(retry_after)
            continue
        
        response.raise_for_status()
    
    raise Exception(f"Failed after {max_retries} retries")
```

**Node.js Example:**

```javascript
const axios = require('axios');

async function apiCallWithRetry(url, data, maxRetries = 3) {
    for (let attempt = 0; attempt < maxRetries; attempt++) {
        try {
            const response = await axios.post(url, data);
            return response.data;
        } catch (error) {
            if (error.response?.status === 429) {
                const retryAfter = error.response.headers['retry-after'] || 60;
                console.log(`Rate limited. Waiting ${retryAfter}s...`);
                await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
                continue;
            }
            throw error;
        }
    }
    throw new Error(`Failed after ${maxRetries} retries`);
}
```

***

## Tips

### 1. Batch Your Requests

```python
# ❌ Bad: 1000 API calls
for customer in customers:
    api.post(url, [customer])

# ✅ Good: 2 API calls
for batch in chunks(customers, 500):
    api.post(url, batch)
```

### 2. Monitor Usage

```python
response = requests.post(url, json=data)
remaining = response.headers.get('X-RateLimit-Remaining')
print(f"Requests remaining: {remaining}")
```

### 3. Stay Below Limit

Target 80-90 requests/minute to leave buffer for spikes.

***

## FAQ

**Q: What happens if I exceed the limit?**\
A: You get a 429 response with `Retry-After` header. Wait and retry.

**Q: Are limits per API key?**\
A: Yes. Each API key has its own 100 req/min limit.

**Q: Do failed requests count?**\
A: Yes. All requests count toward the limit.

**Q: Can I request a limit increase?**\
A: Contact <support@replen.it> with your use case.

***

## Need Help?

Contact <support@replen.it> for assistance.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://replenit.gitbook.io/replenit-docs/rate-limits.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
