Rate Limits
The API enforces rate limits to ensure fair usage and system stability.
Default Limits
| Limit | Value |
|---|---|
| Requests per minute | 60 |
| Max bulk items per request | 50 |
Rate Limit Headers
Every response includes rate limit information:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests per window |
X-RateLimit-Remaining | Requests remaining in current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
When You're Rate Limited
If you exceed the limit, you'll receive a 429 response:
json
{
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded. Please slow down."
},
"request_id": "..."
}The response includes a Retry-After header indicating how many seconds to wait.
Best Practices
- Check headers — Monitor
X-RateLimit-Remainingto avoid hitting limits - Use bulk endpoints — Create up to 50 QR codes in one request instead of 50 separate calls
- Cache images — The image endpoint returns
Cache-Control: public, max-age=3600. Respect it. - Implement exponential backoff — When rate limited, wait and retry with increasing delays
Example: Handling Rate Limits
javascript
async function apiRequest(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(url, options)
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get('Retry-After') || '5')
console.log(`Rate limited. Retrying in ${retryAfter}s...`)
await new Promise(r => setTimeout(r, retryAfter * 1000))
continue
}
return res
}
throw new Error('Max retries exceeded')
}