Rate limits
To keep recognition fast for everyone, YesCaptcha has three protections: a limit on how many tasks an account has in progress at once (concurrency limit); a short pause for a clientKey that produces too many errors (automatic pause); and a cache of parameters already found invalid, which returns the original error for a while. None of these are charged.
Concurrency limit
Section titled “Concurrency limit”We limit the number of tasks each account has in progress at the same time, per task type. It is a limit on concurrency, not on requests per minute.
- A task is in progress from the moment you call
createTaskuntil that call returns. Image recognition types return the result fromcreateTask, so concurrency ≈ tasks sent per second × seconds per task. For example, 40 tasks per second at 0.5 seconds each is a concurrency of about 20. - Requests from the same account are counted together; each task type is counted separately.
- Requests over the limit return
ERROR_THREADS_MAXIMUMright away, with your current limit inlimit. They are not charged and do not count toward the automatic pause. - When the solvers are overloaded, the account using the most solving time has its limit for that task type temporarily halved, restored automatically after 10 minutes. This only slows you down; it never pauses the account.
- If you need a higher limit, contact support. The default limits for each type will be published on this page and in the Service changelog once finalized.
{ "errorId": 1, "errorCode": "ERROR_THREADS_MAXIMUM", "errorDescription": "This account already has 30 tasks of this type in progress, which is the limit. Lower the concurrency and wait for pending requests to return before sending more; rejected requests are not charged and do not lead to a block.", "limit": 30}(The number in the example is only an illustration.)
Recommended practice
Section titled “Recommended practice”- Limit the number of requests waiting for a result at the same time, for example with a semaphore or a fixed-size thread pool, rather than only limiting requests per second.
- After
ERROR_THREADS_MAXIMUM, wait for in-flight requests to return before sending new ones, or wait 1 to 2 seconds and retry. Don’t retry in a tight loop. - Spread batches out instead of sending thousands of tasks at once.
A Python (asyncio) example:
import asyncioimport os
import aiohttp
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]LIMIT = 15 # below your concurrency limitsem = asyncio.Semaphore(LIMIT)
async def solve(session, task): async with sem: # at most LIMIT requests in progress at a time result = {} for attempt in range(5): async with session.post( "https://api.yescaptcha.com/createTask", json={"clientKey": CLIENT_KEY, "task": task}, ) as resp: result = await resp.json() if result.get("errorCode") != "ERROR_THREADS_MAXIMUM": return result await asyncio.sleep(1 + attempt) # over the limit: wait and retry return resultAutomatic pause
Section titled “Automatic pause”A clientKey that sends many failing requests in a short time is paused from creating tasks:
| Trigger | Pause |
|---|---|
| 100 of the errors listed below within one calendar minute | 5 minutes |
A single ERROR_IMAGE_TYPE_NOT_SUPPORTED |
30 minutes |
| 1,000 hits on the invalid-parameter cache within one calendar minute | 5 minutes |
Errors that count toward the pause:
ERROR_REQUEST_FORMATSERROR_TASK_ABSENTERROR_TASK_NOT_SUPPORTEDERROR_KEY_DOES_NOT_EXISTERROR_TASKID_INVALIDERROR_SETTLEMENT_FAILEDERROR_HIGH_DEMAND_DOMAINERROR_ZERO_CAPTCHA_FILESIZEERROR_TOO_BIG_CAPTCHA_FILESIZEERROR_IMAGE_TYPE_NOT_SUPPORTEDERROR_ILLEGAL_IMAGE
ERROR_THREADS_MAXIMUM returned by the account concurrency limit (with a limit field) does not count; the same code returned when the solvers are overloaded (without limit) does. Solving failures (ERROR_CAPTCHA_UNSOLVABLE), insufficient balance (ERROR_ZERO_BALANCE), missing fields (ERROR_REQUIRED_FIELDS), unsupported questions (ERROR_UNKNOWN_QUESTION) and others do not count.
During a pause:
- Only
createTaskandgetBalanceare affected; they returnERROR_IP_BLOCKED_5MIN.getTaskResultstill works, so tasks created before the pause can be queried. - The response includes
retryAfter(seconds left),blockReason(the error that caused the pause) andblockDetail(type, URL and sitekey of those requests) so you can fix your program. - Sending more requests does not extend the pause. It ends automatically; there is no need to contact support.
- The dashboard at yescaptcha.com shows pauses from the last 24 hours.
{ "errorId": 1, "errorCode": "ERROR_IP_BLOCKED_5MIN", "errorDescription": "...", "retryAfter": 182, "blockReason": "ERROR_TASK_NOT_SUPPORTED"}Invalid-parameter cache
Section titled “Invalid-parameter cache”Some errors are determined by the request parameters, so resending gives the same answer:
ERROR_RECAPTCHA_INVALID_SITEKEYERROR_RECAPTCHA_INVALID_DOMAINERROR_INVALID_KEY_TYPEERROR_DOMAIN_NOT_ALLOWED
These don’t count toward the pause; instead they are cached site-wide: for 2 minutes after the first decision, and for 10 minutes if confirmed again within an hour. While cached, identical requests (same task type and websiteKey, or same site domain) return the original error immediately, are not charged, and carry "cached": true, retryAfter (seconds left in the cache) and badRequest (the matching parameters). Fixing the websiteKey or switching task type takes effect immediately.
Concurrency limit vs automatic pause
Section titled “Concurrency limit vs automatic pause”| Concurrency limit | Automatic pause | |
|---|---|---|
| Cause | Too many tasks in progress at once | Too many failing requests in a short time |
| Effect | Only the excess requests are rejected with ERROR_THREADS_MAXIMUM |
The clientKey cannot create tasks; ERROR_IP_BLOCKED_5MIN |
| Recovery | Send more as soon as requests finish; a halved limit returns after 10 minutes | Ends automatically |
| Charged | No | No |