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

PlanRequests per MinuteMonthly Quota
Free550
Pro205,000
EnterpriseCustomCustom

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
HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRequests 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-Remaining from 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.