429 errors.
The two limits
| Limit | What it caps | Enforced by | Error code |
|---|---|---|---|
| Rate limit (RPM) | Total API requests per minute to /v1/* | Sliding 60-second window | rate_limited |
| Concurrency | Active (queued or processing) async jobs at the same time | Point-in-time count | concurrency_limited |
Limits by tier
| Tier | Rate (req/min) | Concurrency (active jobs) |
|---|---|---|
| Free | 10 | 2 |
| Pro | 60 | 10 |
| Business | 200 | 50 |
| Enterprise | 1,000 | 200 |
Rate limit errors
When you exceed your RPM quota, Reader returns429 with:
Retry-After response header to the same retryAfterSeconds value. Honor it. The SDKs do this automatically: they back off and retry once the window reopens.
Concurrency errors
When you already have N active async jobs (where N is your tier limit) and try to create another, you get429 with a different code:
concurrency_limited doesn’t include a Retry-After because Reader can’t predict when your existing jobs will finish. Poll them, cancel stale ones, or wait for your webhook.
What counts as an active job
A job is “active” as long as its status isqueued or processing. Once a job reaches completed, failed, or cancelled, it no longer counts against your concurrency limit, even though it stays in your history.
Sync scrapes (single-URL POST /v1/read) are not jobs. They don’t count toward concurrency.
Per-key rate limits
On Pro and above, you can set a custom RPM override on individual API keys, useful when you want different keys to share a workspace quota but cap each one. This is managed in the dashboard.Strategies for hitting limits
- Use batch instead of a loop. One
POST /v1/readwith 1,000 URLs counts as one request toward your RPM and one job toward your concurrency, instead of 1,000 sync scrapes firing at your rate limit. - Wait on webhooks, not polling. Polling
GET /v1/jobs/{id}every second is 60 RPM per job. Subscribe a webhook instead. - Stagger job creation. If you need to run 100 crawls, don’t kick them off in parallel. Queue them yourself and start new ones as old ones finish.
Next
- Async jobs: how concurrency works in practice
- Errors: full error code list

