Rate Limits
The GenerateInvoice API implements rate limiting to ensure fair usage and maintain service quality for all users. Rate limits vary based on your subscription plan.
Rate Limits by Plan
Each plan has different rate limits to accommodate various usage needs:
| Plan | Requests/Hour | Documents/Month | Bulk Jobs/Month |
|---|---|---|---|
| Free | 50 | 50 | 1 |
| Starter | 500 | 500 | 10 |
| Pro | 2,000 | 2,000 | 50 |
| Scale | 10,000 | 10,000 | 200 |
| Enterprise | Custom | Unlimited | Unlimited |
How Rate Limits Work
Rate limits are applied using a sliding window algorithm:
- Per-hour limits use a 1-hour sliding window
- Per-month limits reset at the start of your billing cycle
- Each API key has its own rate limit counter
- Rate limits are applied per API key, not per IP address
Rate Limit Headers
Every API response includes headers to help you track your rate limit status:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per hour |
X-RateLimit-Remaining | Remaining requests in current window |
X-RateLimit-Reset | Unix timestamp when the rate limit resets |
Retry-After | Seconds to wait before retrying (only on 429 responses) |
Example response headers:
HTTP/1.1 200 OK
X-RateLimit-Limit: 2000
X-RateLimit-Remaining: 1847
X-RateLimit-Reset: 1705324800
Content-Type: application/jsonWhat Happens When Rate Limited
When you exceed your rate limit, the API returns a 429 Too Many Requests response:
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please retry after 847 seconds.",
"details": {
"limit": 2000,
"remaining": 0,
"reset_at": "2024-01-15T12:00:00Z",
"retry_after": 847
}
},
"meta": {
"request_id": "req_abc123",
"timestamp": "2024-01-15T11:45:53Z"
}
}Handling Rate Limits
Here's how to properly handle rate limits in your application:
async function makeApiRequest(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
// Check remaining rate limit
const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
const resetTime = parseInt(response.headers.get('X-RateLimit-Reset'));
if (response.status === 429) {
// Rate limited - wait and retry
const retryAfter = parseInt(response.headers.get('Retry-After')) || 60;
console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
await sleep(retryAfter * 1000);
continue;
}
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
// Log warning if approaching limit
if (remaining < 100) {
console.warn(`Approaching rate limit: ${remaining} requests remaining`);
}
return response.json();
}
throw new Error('Max retries exceeded');
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}Python Example
import time
import requests
def make_api_request(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
# Check rate limit headers
remaining = int(response.headers.get('X-RateLimit-Remaining', 0))
reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
if response.status_code == 429:
# Rate limited - wait and retry
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after} seconds...")
time.sleep(retry_after)
continue
response.raise_for_status()
# Log warning if approaching limit
if remaining < 100:
print(f"Warning: Approaching rate limit ({remaining} requests remaining)")
return response.json()
raise Exception("Max retries exceeded")Best Practices
Monitor Rate Limit Headers
Always check and log the rate limit headers in your responses to anticipate limits.
Implement Exponential Backoff
When retrying after a rate limit error, use exponential backoff to avoid hammering the API.
Use Bulk Operations
For creating multiple documents, use the bulk generation endpoint instead of individual calls.
Cache Responses When Possible
Cache document data locally to reduce API calls for frequently accessed information.
Use Webhooks for Updates
Instead of polling for status changes, set up webhooks to receive real-time notifications.
Usage Limits vs Rate Limits
It's important to understand the difference between rate limits and usage limits:
| Type | Rate Limits | Usage Limits |
|---|---|---|
| What it limits | API requests per hour | Documents created per month |
| Reset frequency | Rolling 1-hour window | Monthly billing cycle |
| Error code | RATE_LIMIT_EXCEEDED | USAGE_LIMIT_EXCEEDED |
| HTTP status | 429 | 402 (Payment Required) |
When you hit a usage limit, you'll need to upgrade your plan or wait for the next billing cycle. The API will return:
{
"success": false,
"error": {
"code": "USAGE_LIMIT_EXCEEDED",
"message": "Monthly document limit exceeded. Please upgrade your plan.",
"details": {
"limit": 500,
"used": 500,
"resets_at": "2024-02-01T00:00:00Z"
}
}
}Need Higher Limits?
If you need higher rate limits or usage limits, consider upgrading your plan or contact us for a custom Enterprise plan.