Explainer

What Are API Rate Limits and 429 Errors?

A 429 is the API telling you to slow down, not that something broke. Here is how limits work and how to handle the error.

Get your free API key →Free to start. No credit card. 1,000 records to spend whenever you like.

An API rate limit caps how many requests you can send in a window of time, and a 429 error is the response you get when you go over it. Nothing is broken. The server is asking you to wait.

Key takeaways

  • A 429 means "too many requests". Your request was valid and was refused only because of speed.
  • Read the Retry-After header first. It tells you how long to wait before the next try.
  • Retry with backoff and a little random jitter. Immediate retries make the problem worse.
  • LeadOcean allows 100 requests per second per key on every plan, and sends its limits in headers on every response.

What it is

A rate limit is a cap on requests per unit of time that an API enforces per key, account or IP address, and HTTP status 429 Too Many Requests is how the server says you passed it.

The status code comes from RFC 6585. It says the user has sent too many requests in a given amount of time, and the response may include a Retry-After header (RFC 6585, September 2026).

Providers set limits to protect shared capacity and to keep one noisy client from slowing everyone else. Limits are a normal part of any RESTful API. The number differs by provider, and so does the window. See rate limits compared across 15 B2B data APIs for the spread.

How it works

Most APIs count requests per key in a moving or fixed window. When the count passes the cap, the next request gets a 429 until the window frees up.

  1. Your client sends a request with its API key.
  2. The server counts it against that key's allowance for the current window.
  3. Under the cap, the request runs and returns data.
  4. Over the cap, the server returns 429 with a JSON error and usually a Retry-After header.
  5. Your client waits that long, then sends the request again.

Worked example, with placeholder numbers. A key is limited to 10 requests per second and your script fires 25 calls in the same second.

The first 10 return 200. The other 15 return 429 with Retry-After: 1. A well-behaved client queues those 15, waits one second, and sends 10 of them. The last 5 go in the next second. All 25 succeed in 3 seconds and nothing is lost.

Providers count in different ways. A fixed window resets at a set time, such as every minute. A sliding window looks back over the last N seconds. A token bucket refills at a steady rate and lets short bursts through. The docs should say which one applies, because it changes how a burst behaves.

Retry-After can be a number of seconds or an HTTP date, per RFC 9110 (RFC 9110, September 2026). Handle both.

429 vs the errors people confuse it with

A 429 is a client-speed problem. Other 4xx and 5xx codes look similar in logs but need a different fix.

StatusWhat it meansWhose sideWhat to do
429 Too Many RequestsYou sent too fastYoursWait for Retry-After, then retry
503 Service UnavailableThe server is overloaded or downTheirsRetry with backoff, check the status page
402 Payment RequiredYour record allowance is spentYoursUpgrade, or wait for the reset if your plan has one
401 / 403Bad key or no permissionYoursFix the key or scope. Retrying will not help

Only 429 and 503 are worth retrying automatically. Retrying a 401 just burns requests.

When it matters

Rate limits are invisible until a job scales. These are the situations where they bite.

Bulk enrichment loops

A loop that enriches 50,000 rows as fast as the CPU allows will hit any limit within seconds. Add a client-side throttle that stays under the cap, and treat 429 as a signal to slow down, not as a failure. Log how often it fires. A rising count tells you the throttle is set too high.

Size the job first. A call that returns only a total is cheaper than a full pull that gets throttled halfway, and it tells you how many requests the run needs.

Parallel workers

Ten workers each sending 20 requests per second is 200 per second against one key. The limit is per key, so workers need a shared limiter or a shared queue. Per-worker throttles do not add up correctly.

Retry storms

When a server returns 429 to many clients at once, they all retry at the same moment and trip the limit again. Exponential backoff with random jitter spreads the retries out. Cap the number of attempts so a stuck job fails loudly.

Agents calling tools

An AI agent that loops over a tool can send hundreds of calls before anyone notices. Put a request budget on the agent, and make the tool return the wait time it was given. Otherwise the model may retry in a tight loop and spend its whole run on refusals.

How LeadOcean handles it

LeadOcean allows 100 requests per second per key, on every plan. Free and Pro share the same limit, and Pro includes 5 API keys, so you can split workloads across keys.

A 429 from LeadOcean means you went faster than the per-second rate. Wait for Retry-After and retry (LeadOcean OpenAPI spec, September 2026). Every response also carries X-RateLimit-Limit, X-Quota-State, X-Quota-Reset and X-Quota-Contact, so you can read your state without a separate call.

Running out of records works differently on each plan. On Free, the 1,000 records are a one-off allowance, so a spent account stops. On Pro, a very large month is paced down to one request a minute until the reset rather than cut off (LeadOcean pricing, September 2026). If that pace hurts, email support for more headroom.

Here is a retry wrapper in Python. It uses the free sizing call (count=true with limit 1), so it spends no records.

python
import os, time, random, requests

URL = "https://api.leadocean.io/v1/people/search?count=true"
HEADERS = {"x-api-key": os.environ["LEADOCEAN_API_KEY"]}
BODY = {"title": ["VP Sales"], "country": ["US"], "limit": 1}

def call_with_backoff(max_tries=6):
    for attempt in range(max_tries):
        r = requests.post(URL, headers=HEADERS, json=BODY, timeout=30)
        if r.status_code != 429:
            return r
        wait = float(r.headers.get("Retry-After", 2 ** attempt))
        time.sleep(wait + random.uniform(0, 0.5))
    raise RuntimeError("still throttled after retries")

print(call_with_backoff().json()["meta"]["total"])

The wrapper trusts Retry-After when it exists and falls back to exponential backoff when it does not. For sustained volume, cap your own rate below 100 requests per second so you rarely see a 429 at all. Plan details are on the pricing page, and the API glossary entry covers the basics.

FAQ

Is a 429 error my fault or the server's?

It is a client-side signal: you sent requests faster than your allowance. The server is healthy, and it is telling you to slow down. A 503 is the code that points at the server.

How long should I wait after a 429?

Wait the number of seconds in Retry-After when the header is present. If it is missing, start at one second and double on each retry, with a little random jitter, up to a fixed cap on attempts.

Should I retry every failed request?

No. Retry 429 and 503, and stop after a few tries. A 400, 401 or 403 will fail the same way every time, so retrying only wastes requests.

How do I avoid 429 errors in the first place?

Throttle on your side to a rate under the published limit, and share one limiter across all workers on a key. Read the limit headers on each response and adjust. Queue work instead of firing it all at once.

Does LeadOcean throttle the free plan differently?

The per-second limit is the same: 100 requests per second per key on every plan. The difference is records. Free has 1,000 one-off records and Pro is $499 a month with a fair-use pace instead of a hard stop.

Build against an API that tells you its limits

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →