Anti-Captcha uses a custom JSON task-based API. CaptchaAI uses the simpler, widely-adopted 2Captcha-compatible format. This guide provides exact code replacements for every CAPTCHA type.
API Format Differences
Anti-Captcha:
Submit: POST /createTask (JSON body)
Poll: POST /getTaskResult (JSON body)
Format: Task objects with "type" field
CaptchaAI:
Submit: POST /in.php (form data or JSON)
Poll: GET /res.php (query parameters)
Format: Flat key-value with "method" field
Step 1: Get CaptchaAI Credentials
- Register at captchaai.com
- Add funds
- Copy your API key
Step 2: Migrate reCAPTCHA v2
Anti-Captcha (Before)
import requests
import time
ANTICAPTCHA_KEY = "your_anticaptcha_key"
# Submit
resp = requests.post("https://api.anti-captcha.com/createTask", json={
"clientKey": ANTICAPTCHA_KEY,
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "SITE_KEY",
}
})
task_id = resp.json()["taskId"]
# Poll
while True:
time.sleep(5)
result = requests.post("https://api.anti-captcha.com/getTaskResult", json={
"clientKey": ANTICAPTCHA_KEY,
"taskId": task_id,
})
data = result.json()
if data["status"] == "ready":
token = data["solution"]["gRecaptchaResponse"]
break
CaptchaAI (After)
import requests
import time
CAPTCHAAI_KEY = "your_captchaai_key"
# Submit
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "userrecaptcha",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
task_id = resp.json()["request"]
# Poll
while True:
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": CAPTCHAAI_KEY,
"action": "get",
"id": task_id,
"json": 1,
})
data = result.json()
if data["request"] != "CAPCHA_NOT_READY":
token = data["request"]
break
Step 3: Migrate reCAPTCHA v3
Anti-Captcha (Before)
resp = requests.post("https://api.anti-captcha.com/createTask", json={
"clientKey": ANTICAPTCHA_KEY,
"task": {
"type": "RecaptchaV3TaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "SITE_KEY",
"minScore": 0.7,
"pageAction": "login",
}
})
CaptchaAI (After)
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "userrecaptcha",
"version": "v3",
"googlekey": "SITE_KEY",
"pageurl": "https://example.com",
"action": "login",
"min_score": "0.7",
"json": 1,
})
Step 4: Migrate Cloudflare Turnstile
Anti-Captcha (Before)
resp = requests.post("https://api.anti-captcha.com/createTask", json={
"clientKey": ANTICAPTCHA_KEY,
"task": {
"type": "TurnstileTaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "TURNSTILE_KEY",
}
})
CaptchaAI (After)
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "turnstile",
"sitekey": "TURNSTILE_KEY",
"pageurl": "https://example.com",
"json": 1,
})
Step 5: Migrate Image CAPTCHA
Anti-Captcha (Before)
import base64
with open("captcha.png", "rb") as f:
body = base64.b64encode(f.read()).decode()
resp = requests.post("https://api.anti-captcha.com/createTask", json={
"clientKey": ANTICAPTCHA_KEY,
"task": {
"type": "ImageToTextTask",
"body": body,
}
})
CaptchaAI (After)
import base64
with open("captcha.png", "rb") as f:
body = base64.b64encode(f.read()).decode()
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "base64",
"body": body,
"json": 1,
})
Step 6: Migrate GeeTest
Anti-Captcha (Before)
resp = requests.post("https://api.anti-captcha.com/createTask", json={
"clientKey": ANTICAPTCHA_KEY,
"task": {
"type": "GeeTestTaskProxyless",
"websiteURL": "https://example.com",
"gt": "GT_KEY",
"challenge": "CHALLENGE_VALUE",
}
})
CaptchaAI (After)
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "geetest",
"gt": "GT_KEY",
"challenge": "CHALLENGE_VALUE",
"pageurl": "https://example.com",
"json": 1,
})
Step 7: New Features After Migration
After switching, you gain access to CAPTCHA types Anti-Captcha doesn't support:
Cloudflare Challenge
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "cloudflare_challenge",
"pageurl": "https://cloudflare-protected.example.com",
"sitekey": "CHALLENGE_KEY",
"json": 1,
})
BLS CAPTCHA
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "bls",
"pageurl": "https://bls-portal.example.com",
"sitekey": "BLS_SITE_KEY",
"json": 1,
})
Complete Migration Wrapper
Replace Anti-Captcha calls with this unified wrapper:
import requests
import time
class CaptchaAISolver:
"""Drop-in replacement for Anti-Captcha API calls."""
def __init__(self, api_key):
self.api_key = api_key
self.base = "https://ocr.captchaai.com"
def solve(self, method, **params):
"""Submit and poll for any CAPTCHA type."""
data = {"key": self.api_key, "method": method, "json": 1}
data.update(params)
resp = requests.post(f"{self.base}/in.php", data=data, timeout=30)
resp.raise_for_status()
result = resp.json()
if result.get("status") != 1:
raise RuntimeError(f"Submit failed: {result.get('request')}")
return self._poll(result["request"])
def _poll(self, task_id, timeout=120):
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)
data = resp.json()
if data["request"] != "CAPCHA_NOT_READY":
if data.get("status") == 1:
return data["request"]
raise RuntimeError(f"Solve error: {data['request']}")
raise TimeoutError("Poll timeout")
def recaptcha_v2(self, sitekey, url):
return self.solve("userrecaptcha", googlekey=sitekey, pageurl=url)
def recaptcha_v3(self, sitekey, url, action="verify", min_score=0.7):
return self.solve(
"userrecaptcha", version="v3", googlekey=sitekey,
pageurl=url, action=action, min_score=str(min_score),
)
def turnstile(self, sitekey, url):
return self.solve("turnstile", sitekey=sitekey, pageurl=url)
def geetest(self, gt, challenge, url):
return self.solve("geetest", gt=gt, challenge=challenge, pageurl=url)
def image(self, base64_body):
return self.solve("base64", body=base64_body)
def bls(self, sitekey, url):
return self.solve("bls", sitekey=sitekey, pageurl=url)
def balance(self):
resp = requests.get(f"{self.base}/res.php", params={
"key": self.api_key, "action": "getbalance", "json": 1,
})
return float(resp.json()["request"])
# Usage — replaces all Anti-Captcha calls
solver = CaptchaAISolver("your_captchaai_key")
# reCAPTCHA v2
token = solver.recaptcha_v2("SITE_KEY", "https://example.com")
# Turnstile
token = solver.turnstile("SITE_KEY", "https://example.com")
# Balance
print(f"Balance: ${solver.balance():.2f}")
Parameter Mapping Reference
| Anti-Captcha | CaptchaAI | Notes |
|---|---|---|
clientKey |
key |
API key |
task.type |
method |
CAPTCHA type identifier |
task.websiteURL |
pageurl |
Target page URL |
task.websiteKey |
googlekey or sitekey |
Site key |
task.minScore |
min_score |
v3 minimum score |
task.pageAction |
action |
v3 action string |
task.body |
body |
Base64 image data |
task.gt |
gt |
GeeTest key |
task.challenge |
challenge |
GeeTest challenge |
taskId |
id |
Task ID for polling |
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
ERROR_WRONG_USER_KEY |
Using Anti-Captcha key | Register at CaptchaAI for new key |
| JSON body rejected | Sending JSON task objects | Use form data with flat key-value pairs |
Missing method field |
Using type from Anti-Captcha |
Replace with CaptchaAI method names |
| Wrong poll endpoint | POST to /getTaskResult |
GET to /res.php with query params |
FAQ
Is the migration harder than switching from 2Captcha?
Slightly, because the API formats differ. But the core logic is the same (submit → poll → get result). Use the wrapper class above for a clean migration.
Can I keep Anti-Captcha as a fallback?
Yes. Run both in parallel and route based on CAPTCHA type or priority. CaptchaAI handles Cloudflare Challenge and BLS that Anti-Captcha doesn't support.
Do I need to change my proxy configuration?
The proxy parameter format differs. In CaptchaAI, use proxy=user:pass@host:port and proxytype=HTTP as flat parameters instead of Anti-Captcha's nested proxy object.
Related Guides
Switch to better Cloudflare and BLS support — start with CaptchaAI.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.