Skip to main content

Rate Limits

Understanding and working with Grillo API rate limits.

Overview

Rate limits protect the API from abuse and ensure fair usage for all users.

Limits by tier

TierRequests/minuteRequests/dayConcurrent
Free6010,0005
Standard300100,00020
Premium1,000Unlimited50
EnterpriseCustomCustomCustom

Rate limit headers

Every response includes rate limit information:

HTTP/1.1 200 OK
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1610000000
HeaderDescription
X-RateLimit-LimitRequests allowed per window
X-RateLimit-RemainingRequests remaining
X-RateLimit-ResetUnix timestamp when limit resets

Exceeding limits

When you exceed the rate limit:

HTTP/1.1 429 Too Many Requests
Retry-After: 30
{
"error": {
"code": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 30 seconds.",
"retry_after": 30
}
}

Handling rate limits

Check headers

Monitor your usage via response headers:

const response = await fetch(url, { headers });
const remaining = response.headers.get('X-RateLimit-Remaining');

if (remaining < 10) {
console.warn('Approaching rate limit');
}

Implement backoff

When rate limited, wait before retrying:

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

if (response.status !== 429) {
return response;
}

const retryAfter = response.headers.get('Retry-After') || 30;
await sleep(retryAfter * 1000);
}

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

Exponential backoff

For repeated failures:

async function exponentialBackoff(fn, maxRetries = 5) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.status !== 429 || i === maxRetries - 1) {
throw error;
}
const delay = Math.pow(2, i) * 1000; // 1s, 2s, 4s, 8s, 16s
await sleep(delay);
}
}
}

Best practices

Reduce requests

Cache responses:

  • Cache data that doesn't change frequently
  • Set appropriate cache TTLs

Batch requests:

  • Use batch endpoints where available
  • Fetch multiple items in one request

Request only what you need:

  • Use filters to limit results
  • Select specific fields if supported

Spread requests

Avoid bursts:

  • Distribute requests over time
  • Don't request everything at startup

Implement queuing:

  • Queue requests during high load
  • Process at sustainable rate

Monitor usage

Track consumption:

  • Log rate limit headers
  • Alert when approaching limits

Analyze patterns:

  • Identify usage spikes
  • Optimize high-frequency requests

Code examples

Python with rate limit handling

import time
import requests

class RateLimitedClient:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = "https://api.grillo.io/v1"

def request(self, endpoint, method="GET", **kwargs):
url = f"{self.base_url}{endpoint}"
headers = {"Authorization": f"Bearer {self.api_key}"}

for attempt in range(3):
response = requests.request(
method, url, headers=headers, **kwargs
)

if response.status_code != 429:
return response

retry_after = int(response.headers.get("Retry-After", 30))
print(f"Rate limited, waiting {retry_after}s")
time.sleep(retry_after)

response.raise_for_status()

JavaScript with automatic retry

class GrilloClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.grillo.io/v1';
}

async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const headers = {
'Authorization': `Bearer ${this.apiKey}`,
...options.headers
};

for (let attempt = 0; attempt < 3; attempt++) {
const response = await fetch(url, { ...options, headers });

if (response.status !== 429) {
return response.json();
}

const retryAfter = response.headers.get('Retry-After') || 30;
await new Promise(r => setTimeout(r, retryAfter * 1000));
}

throw new Error('Rate limit exceeded after retries');
}
}

Increasing limits

Upgrade tier

Higher tiers have higher limits:

  • Contact sales for upgrade
  • Enterprise plans have custom limits

Request increase

For specific needs:

  • Contact support
  • Explain use case
  • Temporary increases may be available