Rate Limiting
SALZ API rate limits by plan tier, rate limit headers, handling 429 responses, and best practices for staying within limits.
SALZ enforces rate limits to ensure fair usage and protect the service. Rate limits are applied per API key and vary by plan tier.
Rate Limits by Plan
| Plan | Requests per Minute | Monthly Quota |
|---|---|---|
| Free | 5 | 50 |
| Pro | 20 | 5,000 |
| Enterprise | Custom | Custom |
Rate limits are measured in a sliding window. If you send 5 requests in the first 10 seconds on the free plan, you will need to wait until the oldest request falls out of the 60-second window.
Rate Limit Headers
Every API response includes headers that tell you your current rate limit status:
X-RateLimit-Limit: 20 X-RateLimit-Remaining: 17
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per minute |
X-RateLimit-Remaining | Requests remaining in the current window |
Use these headers to monitor your usage in real time and throttle requests before hitting the limit.
Handling 429 Responses
When you exceed the rate limit, SALZ returns a 429 Too Many Requests response:
{
"error": "Rate limit exceeded. Try again in 45 seconds.",
"success": false
}
The error message includes the approximate number of seconds until you can retry.
Retry Strategy
The recommended approach is exponential backoff:
async function optimizeWithRetry(text, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch('https://add-salz.io/api/v1/optimize', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.SALZ_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ text }),
});
if (response.status === 429) {
const waitMs = Math.pow(2, attempt) * 1000; // 1s, 2s, 4s
await new Promise(resolve => setTimeout(resolve, waitMs));
continue;
}
return await response.json();
}
throw new Error('Rate limit exceeded after max retries');
}
In Python:
import time
import requests
def optimize_with_retry(text, max_retries=3):
for attempt in range(max_retries):
response = requests.post(
"https://add-salz.io/api/v1/optimize",
headers={"Authorization": f"Bearer {api_key}"},
json={"text": text},
)
if response.status_code == 429:
wait = 2 ** attempt
time.sleep(wait)
continue
response.raise_for_status()
return response.json()
raise Exception("Rate limit exceeded after max retries")
Monthly Quota vs. Rate Limit
These are two separate limits:
- Rate limit -- How many requests you can send per minute. Prevents burst traffic.
- Monthly quota -- How many total requests you can make in a billing period. Controls overall usage.
You can hit the rate limit without exhausting your monthly quota, and vice versa. Both return 429 responses, but with different error messages.
Best Practices
- Check rate limit headers. Read
X-RateLimit-Remainingfrom each response and slow down when it gets low. - Use exponential backoff. When you get a
429, wait before retrying. Double the wait time with each retry. - Queue requests. If you need to process many texts, use a queue that sends requests at a steady pace below your rate limit.
- Batch wisely. Instead of many small requests, combine shorter texts into fewer, longer requests (up to the character limit).
- Cache results. If you might optimize the same text twice, cache the result to avoid unnecessary API calls.
- Upgrade if needed. If you consistently hit rate limits, upgrading to a higher plan is more reliable than complex retry logic.
Monitoring
Track your rate limit usage over time by logging the X-RateLimit-Remaining header. A dashboard chart of this value helps you identify peak usage periods and decide if you need a higher plan.