Skip to main content

Rate Limits

Gale enforces rate limits to ensure consistent performance and prevent abuse.

Current Limits

API Key TypeRequests per Minute
Test keys (glm_test_*)100
Live keys (glm_live_*)1000
Limits are enforced per API key across all endpoints. All requests count toward your limit regardless of HTTP method (GET, POST, etc.).

Rate Limit Headers

Every API response includes rate limit information:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1698345600
  • X-RateLimit-Limit: Total requests allowed per minute
  • X-RateLimit-Remaining: Requests remaining in current window
  • X-RateLimit-Reset: Unix timestamp when the limit resets

Handling Rate Limits

When you exceed the rate limit, you’ll receive a 429 response:
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests. Please try again in 30 seconds."
  }
}
Response includes:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
The Retry-After header indicates seconds to wait before retrying.

Best Practices

1. Implement Exponential Backoff

async function makeRequestWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const retryAfter = response.headers.get('Retry-After') || (2 ** i);
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }

  throw new Error('Max retries exceeded');
}

2. Use Webhooks Instead of Polling

Don’t poll for order status - use webhooks: Bad:
// Polling every second
setInterval(async () => {
  const order = await getOrder(orderId);
}, 1000);
Good:
// Use webhooks
app.post('/webhooks/gale', (req, res) => {
  if (req.body.type === 'order.created') {
    handleOrder(req.body.data);
  }
});

3. Batch Operations

Use batch endpoints when available:
// Instead of multiple requests
for (const product of products) {
  await checkEligibility(product); // 100 requests
}

// Use batch endpoint
await batchCheckEligibility(products); // 1 request

4. Cache Results

Cache eligibility checks and product data:
const cache = new Map();

async function getProductEligibility(productId) {
  if (cache.has(productId)) {
    return cache.get(productId);
  }

  const result = await checkEligibility(productId);
  cache.set(productId, result);
  return result;
}

Request Higher Limits

Need higher limits for your production use case? Contact support@withgale.com with:
  • Your use case description
  • Expected request volume
  • Current API key