Rate limits protect the Terrace platform and ensure fair usage. Limits are applied per API key, not per IP address.
Rate Limit Tiers
| Tier | Requests | Burst Limit | Webhooks | Sandbox |
|---|---|---|---|---|
| Free | 1,000 / hour | 50/sec | 5 endpoints | Included |
| Pro | 10,000 / hour | 200/sec | 25 endpoints | Included |
| Enterprise | 100,000 / hour | 1000/sec | 100 endpoints | Included |
Rate Limit Headers
Every API response includes rate limit headers so you can monitor your usage.
X-RateLimit-LimitMaximum requests allowed in the current window.X-RateLimit-RemainingRequests remaining in the current window.X-RateLimit-ResetUnix timestamp when the window resets.Retry-AfterSeconds to wait before retrying (only on 429 responses).Handling 429 Too Many Requests
When you exceed the rate limit, the API responds with HTTP 429. Use exponential backoff:
async function fetchWithRetry(url: string, options: RequestInit, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const res = await fetch(url, options);
if (res.status === 429) {
const retryAfter = parseInt(res.headers.get('Retry-After') || '1', 10);
const backoff = Math.min(retryAfter * 1000, 2 ** attempt * 1000);
await new Promise(resolve => setTimeout(resolve, backoff));
continue;
}
return res;
}
throw new Error('Max retries exceeded');
}Best Practices
Use webhooks instead of polling
Subscribe to events instead of repeatedly checking for changes. This saves your rate limit budget.
Cache responses
Cache GET responses on your end. Many resources include ETag/Last-Modified headers for conditional requests.
Batch operations
Use bulk endpoints where available instead of making individual requests per item.
Monitor your usage
Track X-RateLimit-Remaining in your application to proactively slow down before hitting limits.
Use the SDK
Our official SDKs include built-in rate limit handling with automatic retries and backoff.
Endpoint-Specific Limits
Some endpoints have additional limits beyond the global rate: