Rate Limits and Throttling

Every FourA API request passes through rate limiting. You'll encounter two types of limits: concurrency (simultaneous requests) and RPM (requests per minute). Both are enforced per service.

How Rate Limits Work

The API enforces limits at two levels:

  1. Overall API limit: applies to all requests regardless of endpoint.
  2. Per-service limit: applies separately to each endpoint (single, proxy, browser).

Each level tracks two metrics:

  • Concurrency: how many requests are running at the same time.
  • RPM: how many requests you've sent in the last 60 seconds.

A request must pass both the overall API check and the service-specific check before it reaches the backend.

Rate Limit Responses

When you hit a limit, the API returns a JSON response with your current usage and the limits in effect.

429: RPM Exceeded

{
  "error": "Rate limit exceeded",
  "status": 429,
  "service": "single",
  "retryAfter": 5,
  "current": {
    "concurrency": 12,
    "rpm": 3000
  },
  "limits": {
    "maxConcurrency": 500,
    "maxRpm": 3000
  }
}

You've sent too many requests in the last minute. Wait for the retryAfter period before sending more.

503: Concurrency Exceeded

{
  "error": "Service at capacity",
  "status": 503,
  "service": "proxy",
  "retryAfter": 2,
  "current": {
    "concurrency": 500,
    "rpm": 1200
  },
  "limits": {
    "maxConcurrency": 500,
    "maxRpm": 3000
  }
}

Too many requests are running at the same time. Some of your earlier requests haven't finished yet.

Response Fields

Field Type Description
error string Human-readable error message
status number HTTP status code (429 or 503)
service string Which service hit the limit: single, proxy, browser, or api
retryAfter number Recommended wait time in seconds before retrying
current.concurrency number Your current number of active requests
current.rpm number Your requests in the last 60 seconds
limits.maxConcurrency number Maximum simultaneous requests allowed
limits.maxRpm number Maximum requests per minute allowed

Handling Rate Limits

Use the retryAfter field to implement backoff:

import requests
import time

def fetch(url, max_retries=5):
    for attempt in range(max_retries):
        resp = requests.post(
            "https://eu.api.foura.ai/api/single/",
            headers={
                "X-API-Key": "YOUR_API_KEY",
                "Content-Type": "application/json"
            },
            json={"method": "GET", "url": url}
        )

        if resp.status_code in (429, 503):
            data = resp.json()
            wait = data.get("retryAfter", 5)
            time.sleep(wait)
            continue

        return resp

    raise Exception("Max retries exceeded")

Tips

  • Check the current fields in rate limit responses to understand your usage patterns.
  • If you're consistently hitting concurrency limits, reduce the number of parallel requests.
  • If you're hitting RPM limits, add a small delay between requests or batch them over a longer window.
  • The retryAfter value varies by limit type: 2 seconds for concurrency, 5 seconds for RPM.
Last updated: April 9, 2026