Skip to content
ZeroCaptcha

Rate limits and concurrency

There is no rate limit on creating paid tasks. What bounds your throughput is your balance, your account’s share of the queue, and budgets on reads. This page says what each one is, how the API tells you where you stand, and how to run many tasks at once without hitting any of them.

Bound Default Over it
Your available balance Your balance, less what running tasks hold insufficient_funds (402), ERROR_ZERO_BALANCE
A key’s daily spend cap None, until you set one spend_cap_reached (402), ERROR_SPEND_CAP_REACHED
Tasks queued or running for your account 50 at once queue_full (429, Retry-After: 2), ERROR_NO_SLOT_AVAILABLE
Tasks queued across the service 5,000 queue_full, as above

Creating a task draws on no request budget: the bounds above are the only ones. A task finishes (and frees its place in your share) as soon as it succeeds, fails or expires. The share is set per account; if you need more than 50 tasks in flight at once, write to us.

Reads (GET /v1/tasks, GET /v1/tasks/{id}, GET /v1/balance, getTaskResult, getBalance, res.php, and opening a live-update stream) draw on two budgets: one for the key, one for its account. Both refill evenly, not all at once when a window ends.

Budget Default
Reads per key 200 every 2 seconds
Reads per account, all its keys together 200 every 2 seconds
Live-update streams open per account 10
Public reads (GET /v1/prices, GET /v1/status) per client address 60 a minute

Over a budget, a read is refused with rate_limited (429) and Retry-After; in the createTask format with ERROR_RATE_LIMIT, and in 2Captcha’s with ERROR: 1005 (and MAX_USER_TURN for in.php, should creation ever have a budget). Nothing is charged for a refused read.

Replies to calls with a key carry two headers (IETF’s RateLimit fields):

RateLimit-Policy: "key-read";q=200;w=2, "account-read";q=200;w=2
RateLimit: "key-read";r=187;t=1, "account-read";r=161;t=1
  • RateLimit-Policy names each budget with its size q and the seconds w it refills over.
  • RateLimit says how many units r are left in each, and t, the seconds until one more is back.

Read them rather than hard-coding the defaults above, which the service may change. When r reaches 0, wait t seconds before the next read.

  • A request body may be at most 64 KiB; a larger one is refused with payload_too_large (413).
  • The API answers every request within 10 seconds, or with request_timeout (504). When it is overloaded it answers service_unavailable (503) with Retry-After. Retry both.

Limits lists every limit in one table, field lengths included.

  • Create in parallel, up to your share. Keep at most 50 tasks queued or running; when one ends, start the next. A worker pool of that size, or a semaphore, does it.
  • Poll each task every 2 seconds, not faster. 50 tasks polled every 2 seconds is 25 reads a second, well within the read budget. Better still, use callbacks or one live-update stream instead of polling each task.
  • Treat queue_full as back-pressure: wait the 2 seconds it asks, then try again, and lower your concurrency if it keeps happening.
  • Keep enough balance for the tasks you run at once: each holds its price until it ends.
  • Spread across keys only for bookkeeping. Every key of an account shares the account’s read budget and queue share, so more keys do not mean more throughput.