Rate Limits
To ensure fair usage and API stability, emissions.dev enforces rate limits on all API requests.
Limits by Plan
| Plan | Requests/month | Rate limit | Burst |
|---|---|---|---|
| Free | 500 | 2 req/s | 5 |
| Launch | 5,000 | 5 req/s | 10 |
| Starter | 10,000 | 10 req/s | 25 |
| Growth | 50,000 | 15 req/s | 40 |
| Scale | 200,000 | 25 req/s | 75 |
| Enterprise | Custom | Custom | Custom |
Burst allows short spikes above the per-second rate. Once the burst is exhausted, requests are limited to the per-second rate until the window resets.
Response Headers
Every API response includes headers to help you track your usage:
Rate limit headers
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum burst requests per second |
X-RateLimit-Remaining |
Requests remaining in current window |
Monthly usage headers
| Header | Description |
|---|---|
X-Monthly-Usage |
Requests used this billing month |
X-Monthly-Limit |
Total requests allowed this month |
X-Usage-Warning |
Warning level (only present when approaching or exceeding limit) |
Usage warning levels
| Warning | Meaning |
|---|---|
approaching-limit |
80–90% of monthly quota used |
approaching-limit-critical |
90–100% of monthly quota used |
over-limit-grace |
Over 100% but within 120% grace buffer — requests still allowed |
Requests are hard-blocked at 120% of your monthly quota. When blocked, the response includes a Retry-After header with the seconds until your usage resets on the 1st of next month.
Rate Limit Response
When you exceed the per-second rate limit:
{
"error": {
"message": "Rate limit exceeded. Try again in 1 seconds.",
"status": 429
}
}
When you exceed the monthly quota:
{
"error": {
"message": "Monthly usage limit exceeded (600/500 requests). Please upgrade your plan or wait until your usage resets on the 1st of next month.",
"status": 429
}
}
Handling Rate Limits
Recommended Approach
- Check headers proactively — monitor
X-Monthly-UsageandX-RateLimit-Remainingto slow down before hitting limits - Implement exponential backoff — on 429 errors, wait and retry with increasing delays
- Queue requests — for bulk operations, use a queue to spread requests over time
Example Implementation
class EmissionsClient {
async request(url, options) {
const response = await fetch(url, options);
// Check monthly usage warnings
const warning = response.headers.get('x-usage-warning');
if (warning === 'approaching-limit-critical') {
console.warn('Monthly quota nearly exhausted');
}
// Handle rate limiting with retry
if (response.status === 429) {
const retryAfter = parseInt(response.headers.get('retry-after') || '1');
await new Promise(r => setTimeout(r, retryAfter * 1000));
return this.request(url, options);
}
return response;
}
}
Best Practices
Cache Responses
Emission calculations for the same parameters are deterministic. Cache results to reduce API calls:
const cache = new Map();
async function getEmissions(params) {
const key = JSON.stringify(params);
if (cache.has(key)) {
return cache.get(key);
}
const result = await client.calculate(params);
cache.set(key, result);
setTimeout(() => cache.delete(key), 86400000);
return result;
}
Batch Similar Requests
If calculating emissions for multiple similar routes, consider aggregating where possible.
Increasing Your Limits
Need higher limits? Options:
- Upgrade your plan — visit the pricing page for details
- Request temporary increase — for one-time bulk imports, contact us