Skip to content

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.

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 createTask until that call returns. Image recognition types return the result from createTask, 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_MAXIMUM right away, with your current limit in limit. 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.)

  1. 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.
  2. 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.
  3. Spread batches out instead of sending thousands of tasks at once.

A Python (asyncio) example:

import asyncio
import os
import aiohttp
CLIENT_KEY = os.environ["YESCAPTCHA_CLIENT_KEY"]
LIMIT = 15 # below your concurrency limit
sem = 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 result

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_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 createTask and getBalance are affected; they return ERROR_IP_BLOCKED_5MIN. getTaskResult still works, so tasks created before the pause can be queried.
  • The response includes retryAfter (seconds left), blockReason (the error that caused the pause) and blockDetail (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"
}

Some errors are determined by the request parameters, so resending gives the same answer:

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 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