# API Rate Limits https://api-docs.lumar.io/docs/graphql/rate-limits Our API employs rate limiting to ensure fair usage and protect against abuse. Exceeding the defined limits will result in your requests being temporarily blocked. ### Limit Details Rate limiting is applied based on the requester's IP address. The current limit is **6000 requests per 5-minute period**. This averages to 20 requests per second. If you exceed this limit, you will receive an HTTP `429 Too Many Requests` response code. If your application requires a higher request rate, please contact us to discuss your requirements. ### Exponential backoff When you receive a 429 response, wait before retrying. Use exponential backoff to progressively increase the delay between retries: ```typescript async function fetchWithBackoff(url: string, options: RequestInit, maxRetries = 5): Promise { for (let attempt = 0; attempt < maxRetries; attempt++) { const response = await fetch(url, options); if (response.status !== 429) { return response; } const delay = Math.min(1000 * Math.pow(2, attempt), 30000); const jitter = Math.random() * 500; console.warn(`Rate limited. Retrying in ${Math.round(delay + jitter)}ms...`); await new Promise(resolve => setTimeout(resolve, delay + jitter)); } throw new Error("Max retries exceeded due to rate limiting"); } ``` Adding random jitter prevents multiple clients from retrying in lockstep. ### Request budgeting To stay within limits proactively: - **Batch related data** into fewer, larger queries. GraphQL lets you request multiple fields and connections in a single request. - **Cache stable data** such as report templates, account metadata, and finished crawl results. - **Use report downloads** for bulk data export instead of paginating through thousands of API pages. - **Track your usage** by counting requests in your client code and throttling when approaching the limit. A simple in-memory rate tracker: ```typescript class RateTracker { private timestamps: number[] = []; private readonly limit = 6000; private readonly windowMs = 5 * 60 * 1000; canMakeRequest(): boolean { const now = Date.now(); this.timestamps = this.timestamps.filter(t => now - t < this.windowMs); return this.timestamps.length < this.limit; } recordRequest(): void { this.timestamps.push(Date.now()); } } ```