Rate Limiting
The Geo-Engine API implements rate limiting to ensure fair usage and platform stability.
Understanding Rate Limits
When you exceed your rate limit, the API responds with:
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1645000000
X-RateLimit-Retry-After: 60
Response Headers
- X-RateLimit-Limit - Maximum requests allowed in this window
- X-RateLimit-Remaining - Requests remaining in current window
- X-RateLimit-Reset - Unix timestamp when the limit resets
- X-RateLimit-Retry-After - Seconds to wait before retrying
Checking Your Limits
Every successful response includes rate limit headers. Monitor these to avoid hitting your limit.
JavaScript Example
async function checkRateLimit() {
const response = await fetch('https://graph.quarticle.ro/graph/api/v1/places/geocode?q=Berlin', {
headers: { 'Authorization': `${apiKey}` }
});
console.log('Limit:', response.headers.get('X-RateLimit-Limit'));
console.log('Remaining:', response.headers.get('X-RateLimit-Remaining'));
console.log('Reset:', response.headers.get('X-RateLimit-Reset'));
return response.json();
}
Python Example
import requests
import time
headers = {'Authorization': f'{api_key}'}
response = requests.get('https://graph.quarticle.ro/graph/api/v1/places/geocode?q=Berlin', headers=headers)
print(f"Limit: {response.headers.get('X-RateLimit-Limit')}")
print(f"Remaining: {response.headers.get('X-RateLimit-Remaining')}")
print(f"Reset: {response.headers.get('X-RateLimit-Reset')}")
Best Practices
1. Implement Backoff
Don't immediately retry when hitting the rate limit. Use exponential backoff:
async function apiRequestWithBackoff(url, options, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
const retryAfter = response.headers.get('X-RateLimit-Retry-After') || 60;
console.log(`Rate limited. Retrying after ${retryAfter}s`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
}
throw new Error('Max retries exceeded');
}
2. Cache Results
Cache API responses to reduce redundant requests:
const cache = new Map();
const CACHE_TTL = 60000; // 60 seconds
async function fetchWithCache(url) {
const now = Date.now();
if (cache.has(url)) {
const { data, timestamp } = cache.get(url);
if (now - timestamp < CACHE_TTL) {
return data;
}
}
const response = await fetch(url, {
headers: { 'Authorization': `${apiKey}` }
});
const data = await response.json();
cache.set(url, { data, timestamp: now });
return data;
}
Rate Limit Window
Rate limits are calculated per minute and reset hourly. For example:
- If your limit is 60 requests/minute
- You can make up to 60 requests in any 60-second window
- The window rolls forward continuously (not calendar-based)
Burst Requests
You can exceed your per-minute limit momentarily if you have unused requests from previous minutes. However, you cannot exceed your daily limit.