Skip to main content

Rate Limits & Concurrency

OmniScrape limits how many requests you can have in flight at the same time (concurrency), based on your plan. There is no fixed requests-per-second cap — you can send as many requests as you like as long as you stay under your concurrency limit.

Concurrency by plan

PlanMax concurrent requests
Free trial1
Pay-As-You-Go5
Startup10
Growth25

A "concurrent request" is any scrape (sync or async) that is currently being processed. When a request finishes, its slot frees up immediately.

What happens at the limit

If you exceed your concurrency limit, the request returns 429 with a structured code and a Retry-After header:

{
"success": false,
"error": "Concurrent request limit reached for your plan. Retry shortly.",
"code": "CONCURRENCY_LIMIT"
}

Wait the suggested time (or a couple of seconds) and retry.

Monthly quotas

Subscription plans include a monthly allowance of successful requests. Pay-As-You-Go has no monthly cap — you simply pay per request from your balance.

PlanIncluded successful requests / month
Pay-As-You-GoUnlimited (balance-based)
Startup10,000
Growth40,000

Exceeding the monthly quota returns 402:

{
"success": false,
"error": "monthly quota exceeded: 10000/10000 requests used this month",
"code": "MONTHLY_QUOTA_EXCEEDED"
}

Upgrade your plan or wait for the monthly reset. See Pricing.

Staying within limits

The simplest pattern is a bounded worker pool sized to your plan's concurrency:

import os, requests
from concurrent.futures import ThreadPoolExecutor

KEY = os.environ["OMNISCRAPE_KEY"]
MAX_CONCURRENCY = 5 # match your plan

def scrape(url):
return requests.post(
"https://api.omniscrape.io/v1/scrape",
headers={"X-API-Key": KEY},
json={"url": url, "mode": "auto"},
timeout=120,
).json()

urls = [f"https://example.com/page/{i}" for i in range(1, 101)]
with ThreadPoolExecutor(max_workers=MAX_CONCURRENCY) as pool:
results = list(pool.map(scrape, urls))

For very large batches, prefer the async jobs API so you submit work without holding connections open, and still cap how many jobs are unresolved at once.

Retry guidance

Retry 429, 500, 502, and 503 with exponential backoff. Do not retry 400, 401, or 402. See Errors for the full strategy.