Skip to main content

Rate Limits

Naturalead enforces multiple rate limiting tiers to ensure fair usage and platform stability. All rate limits use a sliding window of 60 seconds.

Rate limit tiers

TierLimitScopeApplied To
Global1,000 req/minPer IP addressAll requests
API Key500 req/minPer API keyRequests authenticated with an API key
Sync50 req/minPer API keyPOST /api/leads/sync and DELETE /api/leads/sync only
Account2,000 req/minPer accountAll authenticated requests for an account

How tiers stack

A single request may count against multiple tiers simultaneously:
  1. Global — always applies (based on IP)
  2. API Key — applies when using API key auth
  3. Sync — applies only to lead sync endpoints (in addition to API key limit)
  4. Account — applies when account is resolved (bounds total across all keys)
The account limit (2,000/min) bounds total traffic regardless of how many API keys exist. Even if you have 10 keys, each at 500/min, the account total cannot exceed 2,000/min.

Response headers

All responses include rate limit headers following the IETF draft-7 standard:
HeaderDescriptionExample
RateLimit-LimitMaximum requests allowed in the window1000
RateLimit-RemainingRequests remaining in the current window742
RateLimit-ResetSeconds until the window resets34
Retry-AfterSeconds to wait before retrying (only on 429)12

Rate limit exceeded response

When a rate limit is exceeded, the API returns 429 Too Many Requests:
{
  "error": "Too many requests, please try again later"
}
The specific error message varies by tier:
TierError Message
Global"Too many requests, please try again later"
API Key"API key rate limit exceeded, please try again later"
Sync"Sync API rate limit exceeded. Maximum 50 batch requests per minute."
Account"Account rate limit exceeded, please try again later"

Best practices

Implement exponential backoff

When you receive a 429, wait for the Retry-After header value before retrying:
import time
import requests

def api_call_with_retry(url, headers, max_retries=3):
    for attempt in range(max_retries):
        response = requests.get(url, headers=headers)

        if response.status_code == 429:
            retry_after = int(response.headers.get("Retry-After", 5))
            time.sleep(retry_after)
            continue

        return response

    raise Exception("Max retries exceeded")

Monitor your usage

Check RateLimit-Remaining headers proactively to throttle before hitting limits.

Use bulk endpoints

For lead management, prefer the Lead Sync endpoint over individual creates. One sync request can process multiple leads, using only one count against the rate limit.

Spread requests evenly

Avoid bursting all requests at once. Distribute API calls evenly across the 60-second window for best throughput.