This page documents every error code the CaptchaAI API can return, organized by endpoint. Use it to diagnose failed requests, implement proper error handling, and avoid common mistakes.
The CaptchaAI API has two endpoints:
in.php— submit a CAPTCHA task (errors occur at submission time)res.php— poll for the result (errors occur while retrieving results)
When you include json=1 in your request, errors return as JSON:
{"status": 0, "request": "ERROR_CODE_HERE"}
Without json=1, errors return as plain text: ERROR_CODE_HERE
Quick error handling rules
Before the full reference, here are the three rules that handle 90% of cases:
| Error pattern | Action |
|---|---|
CAPCHA_NOT_READY |
Normal — poll again in 5 seconds |
Any ERROR_ starting with parameter/format issues |
Fix your request — do not retry the same request |
Server errors (ERROR_SERVER_ERROR, ERROR_INTERNAL_SERVER_ERROR) |
Retry after 10 seconds with exponential backoff |
Submit errors (in.php)
These errors occur when you submit a new CAPTCHA task.
ERROR_WRONG_USER_KEY
Cause: The key parameter has an incorrect format. CaptchaAI API keys are 32 characters.
Fix:
- Check that your key is exactly 32 characters.
- Verify there are no extra spaces or line breaks.
- Copy the key directly from captchaai.com/api.php.
# Wrong — key has extra space
"key": "abc123... "
# Correct
"key": "abc12345678901234567890123456789a"
ERROR_KEY_DOES_NOT_EXIST
Cause: The API key does not match any account in the system.
Fix:
- Log into captchaai.com and copy the key from your dashboard.
- Make sure you are using the correct account's key.
- If you recently created the account, wait a few minutes for the key to activate.
ERROR_ZERO_BALANCE
Cause: Your account has no available threads to accept the task.
Fix:
- Wait for currently running tasks to complete (threads will free up).
- Upgrade your plan for more concurrent threads.
- Check your account balance at captchaai.com/api.php.
This is not always an out-of-funds error. It can also mean all your threads are currently occupied. If you have a single-thread plan and one task is running, new submissions will return this error until the first task completes.
ERROR_PAGEURL
Cause: The pageurl parameter is missing or empty. This parameter is required for token-based CAPTCHAs (reCAPTCHA, Cloudflare Turnstile, GeeTest, etc.).
Fix: Add the full URL of the page where the CAPTCHA loads, including the protocol:
# Wrong
"pageurl": ""
# Correct
"pageurl": "https://example.com/login"
ERROR_WRONG_GOOGLEKEY / ERROR_GOOGLEKEY
Cause: The googlekey (sitekey) parameter is blank, malformed, or missing.
Fix:
- Re-extract the sitekey from the target page's
data-sitekeyattribute or the reCAPTCHA anchor URLkparameter. - Make sure the value is not empty or truncated.
# Wrong — empty sitekey
"googlekey": ""
# Correct
"googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
ERROR_BAD_TOKEN_OR_PAGEURL
Cause: The combination of googlekey (sitekey) and pageurl is invalid. The sitekey is not registered for the given page URL.
Common causes:
- The reCAPTCHA widget loads inside an iframe on a different subdomain. You are using the parent page URL instead of the iframe URL.
- The sitekey belongs to a different page or domain.
- The sitekey was extracted from a development/staging environment.
Fix:
- If the reCAPTCHA is in an iframe, use the iframe's
srcURL as thepageurl. - Verify the sitekey from the live production page.
- Test both values by loading the reCAPTCHA anchor URL manually:
https://www.google.com/recaptcha/api2/anchor?k=YOUR_SITEKEY
ERROR_TOO_BIG_CAPTCHA_FILESIZE
Cause: The uploaded image exceeds the maximum allowed size.
Fix: Compress or resize the image before submitting. Use JPEG for photos, PNG for screenshots.
ERROR_ZERO_CAPTCHA_FILESIZE
Cause: The image file is too small (less than 100 bytes), indicating an empty or corrupted upload.
Fix: Verify you are sending actual image data, not an empty file or broken base64 string.
ERROR_WRONG_FILE_EXTENSION
Cause: The uploaded file has an unsupported extension. Supported: jpg, jpeg, png, gif.
Fix: Convert the image to a supported format before uploading.
ERROR_IMAGE_TYPE_NOT_SUPPORTED
Cause: The server cannot determine the image type from the file content.
Fix: Convert to a standard format (PNG or JPEG) and ensure the file is not corrupted.
ERROR_UPLOAD
Cause: The server could not read the uploaded file or base64 payload.
Fix:
- For file uploads: verify your multipart form data encoding.
- For base64: verify the base64 string is complete and properly encoded.
- Test with a known-good image to rule out file corruption.
ERROR_BAD_PROXY
Cause: The proxy you provided is unreachable or has been marked as bad by the system.
Fix:
- Test the proxy independently — can it connect to the target site?
- Try a different proxy.
- Verify the format:
login:password@IP:PORTorIP:PORTfor IP-authenticated proxies.
Proxy usage must be enabled on your account. Contact CaptchaAI support if you have not done this.
ERROR_BAD_PARAMETERS
Cause: Required parameters are missing or have wrong data types.
Fix: Check the API documentation for the specific CAPTCHA type you are solving and verify all required parameters are present:
| CAPTCHA Type | Required Parameters |
|---|---|
| reCAPTCHA v2/v3 | key, method=userrecaptcha, googlekey, pageurl |
| Cloudflare Turnstile | key, method=turnstile, sitekey, pageurl |
| Cloudflare Challenge | key, method=cloudflare_challenge, pageurl, proxy, proxytype |
| GeeTest v3 | key, method=geetest, gt, challenge, pageurl |
| BLS | key, method=bls, body, textinstructions |
| Normal/image | key, method=post, file or body |
IP_BANNED
Cause: Your IP has been temporarily banned after repeated failed authentication attempts.
Fix: Wait approximately 5 minutes, then retry with correct credentials. Do not keep sending requests with wrong API keys.
ERROR_SERVER_ERROR / ERROR_INTERNAL_SERVER_ERROR
Cause: A transient server-side error occurred.
Fix: Wait 10 seconds and retry. Use exponential backoff for repeated failures:
import time
retry_delay = 10
for attempt in range(5):
response = submit_captcha()
if response.get("status") == 1:
break
time.sleep(retry_delay)
retry_delay *= 2 # 10s, 20s, 40s, 80s, 160s
Polling errors (res.php)
These errors occur when you check the status of a submitted task.
CAPCHA_NOT_READY
This is not an error. It means the solve is still in progress.
Action: Wait 5 seconds and poll again.
if result.get("request") == "CAPCHA_NOT_READY":
time.sleep(5)
continue # poll again
Timing guide: | CAPTCHA Type | First poll after | Poll interval | |---|---|---| | reCAPTCHA v2/v3/Enterprise | 15 seconds | 5 seconds | | Cloudflare Turnstile | 15 seconds | 5 seconds | | Cloudflare Challenge | 20 seconds | 5 seconds | | GeeTest v3 | 15 seconds | 5 seconds | | Normal/image CAPTCHA | 5 seconds | 5 seconds |
ERROR_CAPTCHA_UNSOLVABLE
Cause: CaptchaAI could not solve the CAPTCHA after multiple attempts.
Common reasons:
- The CAPTCHA type is not supported or parameters are wrong.
- The challenge is corrupted or expired.
- For proxy-based solves: the proxy is too slow or unreachable.
- The site has changed its CAPTCHA implementation.
Fix:
- Verify your parameters (sitekey, pageurl, method) are correct.
- Resubmit with a fresh request.
- If using a proxy, try a different one.
- If the error persists, the site may have changed — re-extract the sitekey and pageurl.
Do not retry the same task ID. Submit a new task with fresh parameters.
ERROR_WRONG_ID_FORMAT
Cause: The captcha ID must be numeric only.
Fix: Verify you are sending the exact ID returned by in.php (digits only, no extra characters).
ERROR_WRONG_CAPTCHA_ID
Cause: The task ID does not exist or has expired.
Fix:
- Verify you are polling with the ID returned by your submission.
- Task IDs may expire after extended periods — resubmit if the task is very old.
ERROR_EMPTY_ACTION
Cause: The action parameter is missing or empty in your polling request.
Fix: Add action=get to your res.php request:
params = {
"key": api_key,
"action": "get", # Required
"id": captcha_id,
"json": 1,
}
ERROR_PROXY_CONNECTION_FAILED
Cause: The solver could not connect to the target site through your proxy.
Fix:
- The proxy may be temporarily down — try a different one.
- The target site may be blocking the proxy IP.
- Verify the proxy can actually reach the target site.
ERROR_WRONG_USER_KEY / ERROR_KEY_DOES_NOT_EXIST
These can also appear on res.php — same cause and fix as the submit errors above.
Error handling template
Copy this pattern for robust error handling in any language:
Python
import time
import requests
API_KEY = "YOUR_API_KEY"
SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"
# Errors that should not be retried (fix the request first)
NO_RETRY_ERRORS = {
"ERROR_WRONG_USER_KEY",
"ERROR_KEY_DOES_NOT_EXIST",
"ERROR_PAGEURL",
"ERROR_WRONG_GOOGLEKEY",
"ERROR_GOOGLEKEY",
"ERROR_BAD_TOKEN_OR_PAGEURL",
"ERROR_BAD_PARAMETERS",
"ERROR_WRONG_FILE_EXTENSION",
"ERROR_IMAGE_TYPE_NOT_SUPPORTED",
"IP_BANNED",
}
# Errors that can be retried
RETRY_ERRORS = {
"ERROR_ZERO_BALANCE",
"ERROR_SERVER_ERROR",
"ERROR_INTERNAL_SERVER_ERROR",
"ERROR_UPLOAD",
}
def solve_captcha(submit_data, max_retries=3, max_polls=60):
"""Submit and solve a CAPTCHA with full error handling."""
# Submit with retry logic
for attempt in range(max_retries):
resp = requests.post(SUBMIT_URL, data={**submit_data, "json": 1}, timeout=30)
resp.raise_for_status()
data = resp.json()
if data.get("status") == 1:
captcha_id = data["request"]
break
error = data.get("request", "UNKNOWN")
if error in NO_RETRY_ERRORS:
raise ValueError(f"Fatal error (fix request): {error}")
if error in RETRY_ERRORS and attempt < max_retries - 1:
time.sleep(10 * (2 ** attempt))
continue
raise RuntimeError(f"Submit failed: {error}")
else:
raise RuntimeError("Submit failed after max retries")
# Poll for result
time.sleep(15)
for _ in range(max_polls):
resp = requests.get(
RESULT_URL,
params={"key": API_KEY, "action": "get", "id": captcha_id, "json": 1},
timeout=30,
)
data = resp.json()
if data.get("request") == "CAPCHA_NOT_READY":
time.sleep(5)
continue
if data.get("status") == 1:
return data["request"]
error = data.get("request", "UNKNOWN")
if error == "ERROR_CAPTCHA_UNSOLVABLE":
raise RuntimeError("CAPTCHA unsolvable — resubmit with fresh parameters")
raise RuntimeError(f"Poll error: {error}")
raise TimeoutError("Solve timed out")
Node.js
const NO_RETRY_ERRORS = new Set([
"ERROR_WRONG_USER_KEY",
"ERROR_KEY_DOES_NOT_EXIST",
"ERROR_PAGEURL",
"ERROR_WRONG_GOOGLEKEY",
"ERROR_BAD_TOKEN_OR_PAGEURL",
"ERROR_BAD_PARAMETERS",
"IP_BANNED",
]);
async function solveCaptcha(submitData, maxRetries = 3, maxPolls = 60) {
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
// Submit with retry
let captchaId;
for (let attempt = 0; attempt < maxRetries; attempt++) {
const resp = await fetch("https://ocr.captchaai.com/in.php", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({ ...submitData, json: "1" }),
});
const data = await resp.json();
if (data.status === 1) {
captchaId = data.request;
break;
}
if (NO_RETRY_ERRORS.has(data.request)) {
throw new Error(`Fatal error: ${data.request}`);
}
if (attempt < maxRetries - 1) {
await sleep(10_000 * 2 ** attempt);
continue;
}
throw new Error(`Submit failed: ${data.request}`);
}
// Poll for result
await sleep(15_000);
for (let i = 0; i < maxPolls; i++) {
const resp = await fetch(
`https://ocr.captchaai.com/res.php?${new URLSearchParams({
key: submitData.key,
action: "get",
id: captchaId,
json: "1",
})}`
);
const data = await resp.json();
if (data.request === "CAPCHA_NOT_READY") {
await sleep(5_000);
continue;
}
if (data.status === 1) return data.request;
throw new Error(`Poll error: ${data.request}`);
}
throw new Error("Solve timed out");
}
FAQ
Is CAPCHA_NOT_READY an error?
No. It means the solve is still in progress. Wait 5 seconds and poll again. This is normal for every CAPTCHA type.
What should I do when I get ERROR_CAPTCHA_UNSOLVABLE?
Submit a new task with fresh parameters. Do not retry the same task ID. If the error happens repeatedly, verify your sitekey and pageurl are correct and that the CAPTCHA type is supported.
How do I know if an error is retryable?
Parameter/format errors (ERROR_WRONG_USER_KEY, ERROR_BAD_TOKEN_OR_PAGEURL, ERROR_PAGEURL, etc.) are not retryable — fix the request first. Server errors (ERROR_SERVER_ERROR, ERROR_INTERNAL_SERVER_ERROR) are retryable with exponential backoff. ERROR_ZERO_BALANCE is retryable after waiting for threads to free up.
Why do I get ERROR_BAD_PROXY for Cloudflare Challenge?
Cloudflare Challenge requires a working proxy. The proxy must be able to reach the target site. Test it independently, then try a different proxy if it fails. Also ensure proxy usage is enabled on your CaptchaAI account.
Where do I find my API key?
Log in to captchaai.com and go to captchaai.com/api.php. Your 32-character API key is displayed on the dashboard.
Related guides
- CaptchaAI Quickstart — get your first solve working
- How to Solve reCAPTCHA v2 Using API — full reCAPTCHA v2 tutorial
- How to Solve Cloudflare Challenge Using API — proxy-required Cloudflare solving
- Common reCAPTCHA v2 Solving Errors — reCAPTCHA-specific troubleshooting
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.