Rate Limits
Understand the rate limits and quotas that apply to your API usage
Overview
Rate limits protect the API from abuse and ensure fair usage for all developers. Limits are applied per API key and reset on a rolling window basis.
Maximum requests per minute based on your tier
Maximum simultaneous processing jobs
Maximum image size and batch limits
Limits by Package Tier
Your rate limit tier is determined by your lifetime API credits purchased, not your current balance. As you purchase more credits, you automatically unlock higher rate limits.
| Package Tier | Credits Purchased | Requests/min | Max Concurrent |
|---|---|---|---|
| Trial | < 500 (free trial) | 10 | 1 |
| Standard | 500 - 24,999 | 60 | 5 |
| High Volume | 25,000+ | 120 | 10 |
| Enterprise | Custom contract | 300 | 25 |
- Cumulative: All purchases add to your lifetime total
- Automatic: Tier upgrades happen immediately after purchase
- Permanent: Your tier never decreases, even if credits are used
- Balance-independent: Current credit balance doesn't affect your tier
Example:
Buy API 500 (500 credits) → Standard tier
Buy API 25K (25,000 more) → High Volume tier (25,500 total)
Other Limits
| Limit Type | Value | Notes |
|---|---|---|
| Max image size | 30 MB | Per image, all tiers |
| Max resolution | 4096×4096 | Larger images will be downscaled |
| Batch size | 50 images | Per batch request |
| Output URL TTL | 1 hour | Download URLs expire after 1 hour |
Rate Limit Headers
Every API response includes headers to help you track your rate limit status:
X-RateLimit-LimitMaximum requests allowed in the current window
X-RateLimit-RemainingNumber of requests remaining in the current window
X-RateLimit-ResetUnix timestamp when the rate limit window resets
Retry-AfterSeconds to wait before retrying (only present on 429 responses)
Handling Rate Limits
When you exceed the rate limit, you'll receive a 429 response:
{
"error": {
"type": "rate_limit_error",
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Please retry after 30 seconds."
},
"request_id": "req_abc123"
}Best Practices
- 1.Implement exponential backoff: Start with a 1-second delay, then double it on each retry (1s, 2s, 4s, 8s...)
- 2.Respect Retry-After: Always wait at least the time specified in the Retry-After header
- 3.Monitor rate limit headers: Proactively slow down when approaching limits
- 4.Use batch endpoints: Process multiple images in a single request when possible
- 5.Cache results: Store processed images to avoid redundant API calls
Example: Retry with Backoff
async function callApiWithRetry(url, options, maxRetries = 3) {
let delay = 1000; // Start with 1 second
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
const waitTime = retryAfter
? parseInt(retryAfter) * 1000
: delay;
console.log(`Rate limited. Waiting ${waitTime}ms...`);
await new Promise(r => setTimeout(r, waitTime));
delay *= 2; // Exponential backoff
continue;
}
return response;
}
throw new Error('Max retries exceeded');
}