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

  1. Check headers proactively — monitor X-Monthly-Usage and X-RateLimit-Remaining to slow down before hitting limits
  2. Implement exponential backoff — on 429 errors, wait and retry with increasing delays
  3. 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