# Rate limits

> YesCaptcha concurrency limits (ERROR_THREADS_MAXIMUM, not charged, no pause), automatic pauses after too many errors (100 in a minute pauses for 5 minutes, ERROR_IP_BLOCKED_5MIN) and the cache of invalid parameters (cached).

Source: https://docs.yescaptcha.com/en/api/rate-limits/ · Last verified: 2026-10-15

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

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](https://docs.yescaptcha.com/en/help/contact/). The default limits for each type will be published on this page and in the [Service changelog](https://docs.yescaptcha.com/en/changelog/) once finalized.

```json
{
  "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

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:

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

## 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_FORMATS`](https://docs.yescaptcha.com/en/api/errors/#ERROR_REQUEST_FORMATS)
-   [`ERROR_TASK_ABSENT`](https://docs.yescaptcha.com/en/api/errors/#ERROR_TASK_ABSENT)
-   [`ERROR_TASK_NOT_SUPPORTED`](https://docs.yescaptcha.com/en/api/errors/#ERROR_TASK_NOT_SUPPORTED)
-   [`ERROR_KEY_DOES_NOT_EXIST`](https://docs.yescaptcha.com/en/api/errors/#ERROR_KEY_DOES_NOT_EXIST)
-   [`ERROR_TASKID_INVALID`](https://docs.yescaptcha.com/en/api/errors/#ERROR_TASKID_INVALID)
-   [`ERROR_SETTLEMENT_FAILED`](https://docs.yescaptcha.com/en/api/errors/#ERROR_SETTLEMENT_FAILED)
-   [`ERROR_HIGH_DEMAND_DOMAIN`](https://docs.yescaptcha.com/en/api/errors/#ERROR_HIGH_DEMAND_DOMAIN)
-   [`ERROR_ZERO_CAPTCHA_FILESIZE`](https://docs.yescaptcha.com/en/api/errors/#ERROR_ZERO_CAPTCHA_FILESIZE)
-   [`ERROR_TOO_BIG_CAPTCHA_FILESIZE`](https://docs.yescaptcha.com/en/api/errors/#ERROR_TOO_BIG_CAPTCHA_FILESIZE)
-   [`ERROR_IMAGE_TYPE_NOT_SUPPORTED`](https://docs.yescaptcha.com/en/api/errors/#ERROR_IMAGE_TYPE_NOT_SUPPORTED)
-   [`ERROR_ILLEGAL_IMAGE`](https://docs.yescaptcha.com/en/api/errors/#ERROR_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 `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](https://yescaptcha.com/) shows pauses from the last 24 hours.

```json
{
  "errorId": 1,
  "errorCode": "ERROR_IP_BLOCKED_5MIN",
  "errorDescription": "...",
  "retryAfter": 182,
  "blockReason": "ERROR_TASK_NOT_SUPPORTED"
}
```

## Invalid-parameter cache

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

-   [`ERROR_RECAPTCHA_INVALID_SITEKEY`](https://docs.yescaptcha.com/en/api/errors/#ERROR_RECAPTCHA_INVALID_SITEKEY)
-   [`ERROR_RECAPTCHA_INVALID_DOMAIN`](https://docs.yescaptcha.com/en/api/errors/#ERROR_RECAPTCHA_INVALID_DOMAIN)
-   [`ERROR_INVALID_KEY_TYPE`](https://docs.yescaptcha.com/en/api/errors/#ERROR_INVALID_KEY_TYPE)
-   [`ERROR_DOMAIN_NOT_ALLOWED`](https://docs.yescaptcha.com/en/api/errors/#ERROR_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

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