Troubleshooting

CaptchaAI Concurrent Request Limits: Diagnosis and Fixes

When you run too many parallel CAPTCHA tasks, CaptchaAI returns ERROR_NO_SLOT_AVAILABLE. This means you have exceeded your account's concurrent task limit. This guide explains the limits, how to handle them, and how to maximize throughput without hitting the cap.


Symptoms

What you see Cause
ERROR_NO_SLOT_AVAILABLE Too many active tasks at once
HTTP 429 responses Too many requests per second to the API endpoint
Some tasks succeed, others fail Hitting the limit intermittently
Solve times increase Queue congestion on your account

Understanding the limits

CaptchaAI has two types of rate limits:

Limit type What it controls Error
Concurrent tasks Max number of tasks being solved simultaneously ERROR_NO_SLOT_AVAILABLE
Request rate Max API calls per second to submit/poll endpoints HTTP 429

Your concurrent task limit depends on your plan. Check your dashboard at captchaai.com for your current limit.


Fix 1: Add a semaphore to limit concurrency

Control how many tasks run in parallel:

import requests
import time
import threading

API_KEY = "YOUR_API_KEY"
MAX_CONCURRENT = 20  # Stay below your account limit

semaphore = threading.Semaphore(MAX_CONCURRENT)


def solve_captcha(params):
    """Solve a CAPTCHA with concurrency control."""
    with semaphore:
        params["key"] = API_KEY
        params["json"] = 1

        submit = requests.post("https://ocr.captchaai.com/in.php", data=params).json()
        if submit.get("status") != 1:
            raise RuntimeError(f"Submit: {submit.get('request')}")

        task_id = submit["request"]
        time.sleep(10)

        for _ in range(30):
            result = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": API_KEY, "action": "get", "id": task_id, "json": 1
            }).json()
            if result.get("status") == 1:
                return result["request"]
            if result.get("request") != "CAPCHA_NOT_READY":
                raise RuntimeError(f"Solve: {result['request']}")
            time.sleep(5)
        raise TimeoutError("Timed out")

Fix 2: Retry on ERROR_NO_SLOT_AVAILABLE

When you hit the limit, wait and retry instead of failing immediately:

def submit_with_retry(params, max_retries=5):
    """Submit with automatic retry for slot errors."""
    params["key"] = API_KEY
    params["json"] = 1

    for attempt in range(max_retries):
        resp = requests.post("https://ocr.captchaai.com/in.php", data=params).json()

        if resp.get("status") == 1:
            return resp["request"]

        error = resp.get("request", "")
        if error == "ERROR_NO_SLOT_AVAILABLE":
            wait = 2 ** attempt  # Exponential backoff: 1, 2, 4, 8, 16 seconds
            print(f"No slot available, retrying in {wait}s (attempt {attempt + 1})")
            time.sleep(wait)
            continue
        else:
            raise RuntimeError(f"Submit error: {error}")

    raise RuntimeError("Max retries exceeded — no slots available")

Fix 3: Use a task queue

Instead of flooding the API, queue tasks and process them at a controlled rate:

from queue import Queue
from threading import Thread

task_queue = Queue()
results = {}


def worker():
    while True:
        task_id_local, params = task_queue.get()
        try:
            token = solve_captcha(params)
            results[task_id_local] = {"status": "ok", "token": token}
        except Exception as e:
            results[task_id_local] = {"status": "error", "message": str(e)}
        finally:
            task_queue.task_done()


# Start worker threads (limited by semaphore)
for _ in range(MAX_CONCURRENT):
    t = Thread(target=worker, daemon=True)
    t.start()

# Add tasks to queue
captcha_tasks = [
    {"method": "userrecaptcha", "googlekey": "KEY1", "pageurl": "https://site1.com"},
    {"method": "userrecaptcha", "googlekey": "KEY2", "pageurl": "https://site2.com"},
    # ... more tasks
]

for i, params in enumerate(captcha_tasks):
    task_queue.put((i, params))

task_queue.join()
print(f"Completed: {len(results)} tasks")

Fix 4: Reduce polling frequency

Polling too frequently wastes API calls and can trigger rate limits:

# WRONG — polling every 1 second
time.sleep(1)

# CORRECT — poll every 5 seconds
time.sleep(5)

# BETTER — wait longer on initial delay, then poll
time.sleep(15)  # Initial wait
for _ in range(20):
    # ... poll
    time.sleep(5)

Monitoring active tasks

Track how many tasks are currently active:

active_count = 0
lock = threading.Lock()

def track_solve(params):
    global active_count
    with lock:
        active_count += 1
        print(f"Active tasks: {active_count}/{MAX_CONCURRENT}")
    try:
        return solve_captcha(params)
    finally:
        with lock:
            active_count -= 1

FAQ

What is the default concurrent task limit?

It depends on your account plan. Check your CaptchaAI dashboard for your current limit. You can increase it by upgrading your plan.

Does polling count against the rate limit?

Yes. Each res.php request counts. Poll every 5 seconds, not every 1 second.

Can I increase my concurrent limit?

Yes. Contact CaptchaAI support or upgrade your plan to increase the maximum number of simultaneous tasks.

What is the difference between ERROR_NO_SLOT_AVAILABLE and HTTP 429?

ERROR_NO_SLOT_AVAILABLE means too many tasks being solved. HTTP 429 means too many API requests per second (even just polling). Both require backing off.


Scale your solving at CaptchaAI

Maximize throughput at captchaai.com.


Discussions (0)

No comments yet.