DocsRate Limits

Rate Limits

Understand the rate limits for the FreeFileTools API and how to handle them in your application.

Free Tier Limits

LimitValue
Requests per hour50
Max file size per request25 MB
Rate limit windowRolling 1 hour

The rate limit is applied per API key. Each key gets its own independent counter that resets on a rolling hourly basis.

When Rate Limits Are Exceeded

When you exceed the rate limit, the API returns a 429 Too Many Requests response:

json
{
  "error": "Rate limit exceeded",
  "message": "You have exceeded the rate limit of 50 requests per hour. Please try again later.",
  "retryAfter": 1742
}

The retryAfter field indicates the number of seconds to wait before making another request.

Rate Limit Response Headers

Every API response includes headers to help you track your rate limit usage:

HeaderDescription
X-RateLimit-LimitMaximum number of requests allowed per hour (50)
X-RateLimit-RemainingNumber of requests remaining in the current window
Retry-AfterSeconds to wait before retrying (only on 429 responses)

Example response headers

http
HTTP/1.1 200 OK
Content-Type: image/jpeg
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 42

Tips for Staying Within Limits

1.

Check remaining requests

Monitor the X-RateLimit-Remaining header to know how many requests you have left.

2.

Implement exponential backoff

When you receive a 429 response, wait and retry with increasing delays rather than hammering the API.

3.

Cache results

If you are processing the same files repeatedly, cache the results locally to avoid unnecessary API calls.

4.

Batch wisely

For batch processing, space out your requests over time rather than sending them all at once.

Example: Handling rate limits in JavaScript

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

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
      console.log(`Rate limited. Waiting ${retryAfter} seconds...`);
      await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    return response;
  }

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