Troubleshooting

CaptchaAI API Error Handling: Complete Decision Tree

Every CaptchaAI API error has a specific cause and a correct response. This guide maps every error code to the right action — retry, fix parameters, or escalate.


Error Classification

All errors fall into three categories:

Category Action Retry?
Permanent Fix parameters and resubmit No
Transient Wait and retry automatically Yes
Account Fix account issue, then retry No (fix first)

Submit Errors (in.php)

These errors occur when submitting a task:

Permanent Errors — Fix Before Retrying

Error Code Meaning Fix
ERROR_WRONG_USER_KEY Invalid API key format Check key format (32 hex characters)
ERROR_KEY_DOES_NOT_EXIST API key not found Verify key in dashboard
ERROR_WRONG_ID_FORMAT Malformed task ID Use numeric task ID from submit response
ERROR_WRONG_CAPTCHA_ID Task ID doesn't exist Submit a new task
ERROR_BAD_DUPLICATES Duplicate limit reached Change parameters or wait
ERROR_IMAGE_TYPE_NOT_SUPPORTED Invalid image format Use PNG, JPG, or GIF
ERROR_PAGEURL Invalid pageurl parameter Provide full URL with https://
ERROR_BAD_PARAMETERS Missing required parameters Check method-specific required fields
ERROR_GOOGLEKEY Invalid sitekey Extract correct sitekey from target page
ERROR_CAPTCHAIMAGE_BLOCKED Image blocked by moderation Use a different CAPTCHA image
ERROR_BAD_TOKEN_OR_PAGEURL URL/token mismatch Reload page, get fresh parameters

Transient Errors — Retry After Delay

Error Code Meaning Retry Delay
ERROR_NO_SLOT_AVAILABLE All workers busy 5 seconds
ERROR_TOO_MUCH_REQUESTS Rate limit hit 3-10 seconds (exponential backoff)
MAX_USER_TURN Queue full for your account 10 seconds

Account Errors — Fix Account First

Error Code Meaning Fix
ERROR_ZERO_BALANCE No funds Top up account balance
ERROR_IP_NOT_ALLOWED IP not whitelisted Add IP in dashboard settings
ERROR_IP_BANNED IP banned for abuse Contact support

Poll Errors (res.php)

These errors occur when checking task results:

Error Code Meaning Action
CAPCHA_NOT_READY Still solving Poll again in 5 seconds
ERROR_CAPTCHA_UNSOLVABLE Cannot solve this CAPTCHA Submit a new task
ERROR_TOKEN_EXPIRED Token expired before retrieval Submit faster; reduce poll interval
ERROR_EMPTY_ACTION Missing action parameter Add action=get to poll request

Decision Tree Implementation

import requests
import time


# Error classifications
PERMANENT_ERRORS = {
    "ERROR_WRONG_USER_KEY",
    "ERROR_KEY_DOES_NOT_EXIST",
    "ERROR_WRONG_ID_FORMAT",
    "ERROR_WRONG_CAPTCHA_ID",
    "ERROR_BAD_DUPLICATES",
    "ERROR_IMAGE_TYPE_NOT_SUPPORTED",
    "ERROR_PAGEURL",
    "ERROR_BAD_PARAMETERS",
    "ERROR_GOOGLEKEY",
    "ERROR_CAPTCHAIMAGE_BLOCKED",
    "ERROR_BAD_TOKEN_OR_PAGEURL",
}

TRANSIENT_ERRORS = {
    "ERROR_NO_SLOT_AVAILABLE",
    "ERROR_TOO_MUCH_REQUESTS",
    "MAX_USER_TURN",
}

ACCOUNT_ERRORS = {
    "ERROR_ZERO_BALANCE",
    "ERROR_IP_NOT_ALLOWED",
    "ERROR_IP_BANNED",
}

POLL_RETRY_ERRORS = {
    "CAPCHA_NOT_READY",
}

POLL_RESUBMIT_ERRORS = {
    "ERROR_CAPTCHA_UNSOLVABLE",
    "ERROR_TOKEN_EXPIRED",
}


class ErrorAction:
    FAIL = "fail"
    RETRY = "retry"
    RESUBMIT = "resubmit"
    WAIT_POLL = "wait_poll"
    FIX_ACCOUNT = "fix_account"


def classify_error(error_code):
    """Determine the correct action for an error code."""
    if error_code in PERMANENT_ERRORS:
        return ErrorAction.FAIL
    if error_code in TRANSIENT_ERRORS:
        return ErrorAction.RETRY
    if error_code in ACCOUNT_ERRORS:
        return ErrorAction.FIX_ACCOUNT
    if error_code in POLL_RETRY_ERRORS:
        return ErrorAction.WAIT_POLL
    if error_code in POLL_RESUBMIT_ERRORS:
        return ErrorAction.RESUBMIT
    # Unknown errors default to fail
    return ErrorAction.FAIL


class ResilientSolver:
    """Solver with decision-tree-based error handling."""

    def __init__(self, api_key, max_retries=3, max_resubmits=2):
        self.api_key = api_key
        self.base = "https://ocr.captchaai.com"
        self.max_retries = max_retries
        self.max_resubmits = max_resubmits

    def solve(self, method, **params):
        """Solve with full error handling decision tree."""
        resubmit_count = 0

        while resubmit_count <= self.max_resubmits:
            task_id = self._submit_with_retry(method, **params)

            try:
                token = self._poll_with_handling(task_id)
                return token
            except ResubmitNeeded:
                resubmit_count += 1
                print(f"Resubmitting ({resubmit_count}/{self.max_resubmits})...")
                time.sleep(2)

        raise RuntimeError("Max resubmits exceeded")

    def _submit_with_retry(self, method, **params):
        """Submit task with retry logic for transient errors."""
        retry_count = 0
        delay = 3

        while retry_count <= self.max_retries:
            data = {"key": self.api_key, "method": method, "json": 1}
            data.update(params)

            resp = requests.post(
                f"{self.base}/in.php", data=data, timeout=30,
            )
            result = resp.json()

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

            error = result.get("request", "UNKNOWN")
            action = classify_error(error)

            if action == ErrorAction.FAIL:
                raise PermanentError(f"Permanent error: {error}")
            elif action == ErrorAction.FIX_ACCOUNT:
                raise AccountError(f"Account error: {error}")
            elif action == ErrorAction.RETRY:
                retry_count += 1
                print(f"Transient error: {error}. Retry in {delay}s...")
                time.sleep(delay)
                delay = min(delay * 2, 30)
            else:
                raise RuntimeError(f"Unexpected error: {error}")

        raise RuntimeError("Max submit retries exceeded")

    def _poll_with_handling(self, task_id, timeout=120):
        """Poll for result with error decision tree."""
        start = time.time()

        while time.time() - start < timeout:
            time.sleep(5)
            resp = requests.get(f"{self.base}/res.php", params={
                "key": self.api_key,
                "action": "get",
                "id": task_id,
                "json": 1,
            }, timeout=15)
            result = resp.json()
            error = result.get("request", "")

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

            action = classify_error(error)

            if action == ErrorAction.WAIT_POLL:
                continue  # Normal — keep polling
            elif action == ErrorAction.RESUBMIT:
                raise ResubmitNeeded(f"Need resubmit: {error}")
            elif action == ErrorAction.FAIL:
                raise PermanentError(f"Poll error: {error}")
            else:
                raise RuntimeError(f"Unexpected poll error: {error}")

        raise TimeoutError("Poll timeout exceeded")


class PermanentError(Exception):
    """Error that cannot be resolved by retrying."""
    pass


class AccountError(Exception):
    """Error requiring account-level fix."""
    pass


class ResubmitNeeded(Exception):
    """Task needs to be resubmitted."""
    pass


# Usage
solver = ResilientSolver("YOUR_API_KEY")

try:
    token = solver.solve(
        "userrecaptcha",
        googlekey="SITE_KEY",
        pageurl="https://example.com",
    )
    print(f"Solved: {token[:50]}...")

except PermanentError as e:
    print(f"Fix parameters: {e}")

except AccountError as e:
    print(f"Fix account: {e}")

except TimeoutError:
    print("Solve timed out — try again or increase timeout")

Quick Decision Flowchart

Error received
├── Is status == 1?
│   └── YES → Success! Use the token
│
├── Is error in PERMANENT_ERRORS?
│   └── YES → STOP. Fix parameters. Do not retry.
│
├── Is error in TRANSIENT_ERRORS?
│   └── YES → Wait 3-10s → Retry submit (max 3x)
│
├── Is error in ACCOUNT_ERRORS?
│   └── YES → STOP. Fix account (top up / whitelist IP)
│
├── Is error == CAPCHA_NOT_READY?
│   └── YES → Wait 5s → Poll again
│
├── Is error in {UNSOLVABLE, TOKEN_EXPIRED}?
│   └── YES → Resubmit task (max 2x)
│
└── Unknown error
    └── STOP. Log and investigate.

Error Frequency by Type

In typical production usage:

Error Frequency Severity
CAPCHA_NOT_READY Very common Normal (not an error)
ERROR_NO_SLOT_AVAILABLE Occasional Low — auto-resolves
ERROR_CAPTCHA_UNSOLVABLE Rare (~1%) Medium — resubmit
ERROR_ZERO_BALANCE Rare High — stops all work
ERROR_BAD_PARAMETERS Rare (bugs) High — code fix needed

Troubleshooting

Issue Cause Fix
Infinite retry loop Not classifying errors Use the decision tree above
All tasks fail immediately Wrong API key Check ERROR_WRONG_USER_KEY
Slow failure after timeout Not resubmitting unsolvable Handle ERROR_CAPTCHA_UNSOLVABLE
Unexpected charges Retrying permanent errors Stop retrying non-transient errors

FAQ

Should I retry ERROR_CAPTCHA_UNSOLVABLE?

Don't retry — resubmit as a new task. The original task is closed. A fresh attempt with the same parameters usually succeeds.

How many retries are safe for transient errors?

Three retries with exponential backoff (3s → 6s → 12s) covers most transient issues. More than 5 retries indicates a deeper problem.

What's the difference between ERROR_WRONG_USER_KEY and ERROR_KEY_DOES_NOT_EXIST?

WRONG_USER_KEY means invalid format (not 32 hex chars). KEY_DOES_NOT_EXIST means valid format but not found in the system.



Handle every error correctly — start with CaptchaAI.

Discussions (0)

No comments yet.

Related Posts

DevOps & Scaling Ansible Playbooks for CaptchaAI Worker Deployment
Deploy and manage Captcha AI workers with Ansible — playbooks for provisioning, configuration, rolling updates, and health checks across your server fleet.

Deploy and manage Captcha AI workers with Ansible — playbooks for provisioning, configuration, rolling updates...

Automation Python All CAPTCHA Types
Apr 07, 2026
DevOps & Scaling Blue-Green Deployment for CAPTCHA Solving Infrastructure
Implement blue-green deployments for CAPTCHA solving infrastructure — zero-downtime upgrades, traffic switching, and rollback strategies with Captcha AI.

Implement blue-green deployments for CAPTCHA solving infrastructure — zero-downtime upgrades, traffic switchin...

Automation Python All CAPTCHA Types
Apr 07, 2026
Tutorials Using Fiddler to Inspect CaptchaAI API Traffic
How to use Fiddler Everywhere and Fiddler Classic to capture, inspect, and debug Captcha AI API requests and responses — filters, breakpoints, and replay for tr...

How to use Fiddler Everywhere and Fiddler Classic to capture, inspect, and debug Captcha AI API requests and r...

Automation Python All CAPTCHA Types
Mar 05, 2026
Tutorials CAPTCHA Handling in Mobile Apps with Appium
Handle CAPTCHAs in mobile app automation using Appium and Captcha AI — extract Web sitekeys, solve, and inject tokens on Android and i OS.

Handle CAPTCHAs in mobile app automation using Appium and Captcha AI — extract Web View sitekeys, solve, and i...

Automation Python All CAPTCHA Types
Feb 13, 2026
Tutorials Streaming Batch Results: Processing CAPTCHA Solutions as They Arrive
Process CAPTCHA solutions the moment they arrive instead of waiting for tasks to complete — use async generators, event emitters, and callback patterns for stre...

Process CAPTCHA solutions the moment they arrive instead of waiting for all tasks to complete — use async gene...

Automation Python All CAPTCHA Types
Apr 07, 2026
Reference CaptchaAI CLI Tool: Command-Line CAPTCHA Solving and Testing
A reference for building and using a Captcha AI command-line tool — solve CAPTCHAs, check balance, test parameters, and integrate with shell scripts and CI/CD p...

A reference for building and using a Captcha AI command-line tool — solve CAPTCHAs, check balance, test parame...

Automation Python All CAPTCHA Types
Feb 26, 2026
DevOps & Scaling Auto-Scaling CAPTCHA Solving Workers
Build auto-scaling CAPTCHA solving workers that adjust capacity based on queue depth, balance, and solve rates.

Build auto-scaling CAPTCHA solving workers that adjust capacity based on queue depth, balance, and solve rates...

Automation Python All CAPTCHA Types
Mar 23, 2026
DevOps & Scaling CaptchaAI Monitoring with Datadog: Metrics and Alerts
Monitor Captcha AI performance with Datadog — custom metrics, dashboards, anomaly detection alerts, and solve rate tracking for CAPTCHA solving pipelines.

Monitor Captcha AI performance with Datadog — custom metrics, dashboards, anomaly detection alerts, and solve...

Automation Python All CAPTCHA Types
Feb 19, 2026
Tutorials Building a CaptchaAI Debug Logger for Development
Build a debug logging wrapper for the Captcha AI API that captures request details, response data, timing, and errors — with structured output for development t...

Build a debug logging wrapper for the Captcha AI API that captures request details, response data, timing, and...

Automation Python All CAPTCHA Types
Feb 14, 2026
Troubleshooting GeeTest v3 Error Codes: Complete Troubleshooting Reference
Complete reference for Gee Test v 3 error codes — from registration failures to validation errors — with causes, fixes, and Captcha AI-specific troubleshooting.

Complete reference for Gee Test v 3 error codes — from registration failures to validation errors — with cause...

Automation Testing GeeTest v3
Apr 08, 2026
Troubleshooting Turnstile Token Invalid After Solving: Diagnosis and Fixes
Fix Cloudflare Turnstile tokens that come back invalid after solving with Captcha AI.

Fix Cloudflare Turnstile tokens that come back invalid after solving with Captcha AI. Covers token expiry, sit...

Python Cloudflare Turnstile Web Scraping
Apr 08, 2026
Troubleshooting Common GeeTest v3 Errors and Fixes
Diagnose the most common Gee Test v 3 errors — stale challenge, bad parameters, validation failures — and fix them with practical troubleshooting steps.

Diagnose the most common Gee Test v 3 errors — stale challenge, bad parameters, validation failures — and fix...

Automation Testing GeeTest v3
Jan 24, 2026