Rate Limiting
Understanding rate limits, soft caps, and burn protection
Rate Limiting
TessRadar uses a multi-layered rate limiting system to ensure fair usage.
Rate Limits by Plan
| Plan | Credits | Requests/Second | Research/Day |
|---|---|---|---|
| Developer | 25,000 | 10 rps | 100 |
| Business | 50,000 | 20 rps | 300 |
| Professional | 75,000 | 50 rps | 800 |
Rate Limit Headers
Every response includes rate limit information:
| Header | Description |
|---|---|
X-RateLimit-Limit | Requests allowed per second |
X-RateLimit-Remaining | Requests remaining in window |
X-RateLimit-Reset | Unix timestamp when limit resets |
Retry-After | Seconds to wait before retry |
When Limits Are Exceeded
429 Response
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 1 second."
}
}Response Headers
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1736455268
Retry-After: 1Soft Caps
AI endpoints have daily soft caps to prevent abuse. After hitting the cap, requests are throttled (not blocked).
Research Endpoint
| Plan | Daily Limit | After Limit |
|---|---|---|
| Developer | 100 | 1 per 30 seconds |
| Business | 300 | 1 per 30 seconds |
| Professional | 800 | 1 per 30 seconds |
Soft Cap Response
{
"error": {
"code": "SOFT_CAP_EXCEEDED",
"message": "Daily research limit reached. Throttled to 1 request per 30s."
}
}Soft caps reset daily at midnight UTC.
Burn Protection
Prevents runaway credit spending from bugs or automation errors.
| Plan | Max Credits/Minute |
|---|---|
| Developer | 300 |
| Business | 600 |
| Professional | 1,200 |
Burn Protection Response
{
"error": {
"code": "BURN_PROTECTION",
"message": "Credit limit per minute exceeded."
}
}Handling Rate Limits
Basic Retry Logic
async function fetchWithRetry(url: string, options: RequestInit) {
const response = await fetch(url, options);
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After') || '1';
await new Promise(r => setTimeout(r, parseInt(retryAfter) * 1000));
return fetchWithRetry(url, options);
}
return response;
}Exponential Backoff
async function fetchWithBackoff(
url: string,
options: RequestInit,
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') || '1';
const delay = parseInt(retryAfter) * 1000 * Math.pow(2, i);
await new Promise(r => setTimeout(r, delay));
}
throw new Error('Max retries exceeded');
}Best Practices
- Cache responses - Reduce API calls by caching data
- Monitor headers - Track remaining requests in each response
- Use appropriate endpoints - Choose cheaper endpoints when possible
- Implement backoff - Use exponential backoff for retries
Need Higher Limits?
Upgrade your plan or contact support@tessradar.com for enterprise limits.