ResourcesRate Limits

Rate Limits

Understanding Flameup API rate limits and quotas

Overview

Flameup implements rate limiting to ensure fair usage and platform stability. Rate limits are applied per IP address and vary by endpoint type.

Rate Limit Tiers

Current Rate Limits

Rate limits are applied globally per IP address, not per endpoint:

SurfaceLimitWindow
API requests (with or without API key)75/minPer IP
Dashboard (Firebase) sessions120/minPer user
All API requests share the same per-IP rate limit pool, regardless of endpoint or whether an API key is used. Plan your request patterns accordingly.

Rate Limit Headers

Rate limit headers are returned only on 429 Too Many Requests responses — successful responses do not include them:

X-RateLimit-Limit: 37
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1705320660
HeaderDescription
X-RateLimit-LimitCurrently reports the burst value (roughly half the per-minute limit), not the per-minute maximum
X-RateLimit-RemainingRequests remaining in the current window (0 on a 429)
X-RateLimit-ResetUnix timestamp when the window resets

Handling Rate Limits

When you exceed the rate limit, you'll receive a 429 Too Many Requests response:

{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Please try again later."
}

The response headers will contain timing information for when you can retry.

Implementing Backoff

class FlameupClient {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.rateLimitRemaining = 1000;
    this.rateLimitReset = null;
  }

  async request(endpoint, options = {}) {
    // Check if we should wait
    if (this.rateLimitRemaining <= 0 && this.rateLimitReset) {
      const waitTime = this.rateLimitReset - Date.now();
      if (waitTime > 0) {
        await this.sleep(waitTime);
      }
    }

    const response = await fetch(endpoint, {
      ...options,
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        ...options.headers
      }
    });

    // Update rate limit tracking
    this.rateLimitRemaining = parseInt(
      response.headers.get('X-RateLimit-Remaining') || '1000'
    );
    this.rateLimitReset = parseInt(
      response.headers.get('X-RateLimit-Reset') || '0'
    ) * 1000;

    if (response.status === 429) {
      // Use X-RateLimit-Reset header or default wait time
      const resetTime = parseInt(response.headers.get('X-RateLimit-Reset') || '0') * 1000;
      const waitTime = resetTime > Date.now() ? resetTime - Date.now() : 60000;
      await this.sleep(waitTime);
      return this.request(endpoint, options); // Retry
    }

    return response;
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

Best Practices

Instead of making individual requests, batch when possible:

// Bad: 100 individual requests
for (const user of users) {
  await flare.createPerson(user);
}

// Good: 1 batch request
await flare.batchUpsertPeople(users);

Batch endpoints let you do more work per request, which helps you stay within the per-IP limit.

Requesting Higher Limits

If you need higher rate limits:

  1. Optimize your integration - Use batching, caching, and webhooks
  2. Contact support - Explain your use case for a limit increase