CapSolver uses a custom JSON API similar to Anti-Captcha's task-based format. CaptchaAI uses the simpler 2Captcha-compatible format. This guide covers every CAPTCHA type migration with exact code replacements.
Why Migrate
| Factor | CapSolver | CaptchaAI |
|---|---|---|
| Turnstile success rate | 85-95% | 100% |
| Cloudflare Challenge | ❌ | ✅ |
| BLS CAPTCHA | ❌ | ✅ 100% |
| reCAPTCHA v3 score control | Partial | ✅ min_score |
| GeeTest v3 accuracy | 88-95% | 100% |
| API format | Custom JSON | 2Captcha-compatible |
API Format Comparison
CapSolver:
Submit: POST https://api.capsolver.com/createTask
Body: JSON with nested task object
Poll: POST https://api.capsolver.com/getTaskResult
CaptchaAI:
Submit: POST https://ocr.captchaai.com/in.php
Body: Form data (flat key-value)
Poll: GET https://ocr.captchaai.com/res.php
Step 1: Get CaptchaAI API Key
- Register at captchaai.com
- Add funds to your account
- Copy your API key from the dashboard
Step 2: Migrate reCAPTCHA v2
CapSolver (Before)
import requests
import time
CAPSOLVER_KEY = "your_capsolver_key"
resp = requests.post("https://api.capsolver.com/createTask", json={
"clientKey": CAPSOLVER_KEY,
"task": {
"type": "ReCaptchaV2TaskProxyLess",
"websiteURL": "https://example.com",
"websiteKey": "SITE_KEY",
}
})
task_id = resp.json()["taskId"]
while True:
time.sleep(3)
result = requests.post("https://api.capsolver.com/getTaskResult", json={
"clientKey": CAPSOLVER_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"
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"]
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
CapSolver (Before)
resp = requests.post("https://api.capsolver.com/createTask", json={
"clientKey": CAPSOLVER_KEY,
"task": {
"type": "ReCaptchaV3TaskProxyLess",
"websiteURL": "https://example.com",
"websiteKey": "SITE_KEY",
"pageAction": "login",
"minScore": 0.7,
}
})
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 Turnstile
CapSolver (Before)
resp = requests.post("https://api.capsolver.com/createTask", json={
"clientKey": CAPSOLVER_KEY,
"task": {
"type": "AntiTurnstileTaskProxyLess",
"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,
})
CaptchaAI achieves 100% Turnstile success rate vs CapSolver's 85-95%.
Step 5: New Features After Migration
Cloudflare Challenge (Not Available in CapSolver)
resp = requests.post("https://ocr.captchaai.com/in.php", data={
"key": CAPTCHAAI_KEY,
"method": "cloudflare_challenge",
"pageurl": "https://cf-protected.example.com",
"sitekey": "CHALLENGE_KEY",
"json": 1,
})
task_id = resp.json()["request"]
# Standard polling
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
BLS CAPTCHA (Not Available in CapSolver)
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
import requests
import time
class CaptchaAISolver:
"""Drop-in replacement for CapSolver API calls."""
def __init__(self, api_key):
self.api_key = api_key
self.base = "https://ocr.captchaai.com"
def solve(self, method, **params):
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"Error: {data['request']}")
raise TimeoutError("Poll timeout")
# Convenience methods matching common CapSolver use cases
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 cloudflare_challenge(self, sitekey, url):
return self.solve("cloudflare_challenge", sitekey=sitekey, pageurl=url)
def bls(self, sitekey, url):
return self.solve("bls", 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 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
solver = CaptchaAISolver("your_captchaai_key")
# Replace CapSolver calls with equivalent CaptchaAI calls
token = solver.recaptcha_v2("SITE_KEY", "https://example.com")
token = solver.turnstile("SITE_KEY", "https://example.com")
token = solver.cloudflare_challenge("KEY", "https://example.com") # NEW
token = solver.bls("KEY", "https://example.com") # NEW
Parameter Mapping
| CapSolver | CaptchaAI | Notes |
|---|---|---|
clientKey |
key |
API key |
task.type |
method |
CAPTCHA type |
task.websiteURL |
pageurl |
Target URL |
task.websiteKey |
googlekey / sitekey |
Site key |
task.minScore |
min_score |
v3 score minimum |
task.pageAction |
action |
v3 action |
task.gt |
gt |
GeeTest key |
task.challenge |
challenge |
GeeTest challenge |
taskId |
id |
Task ID for polling |
ReCaptchaV2TaskProxyLess |
userrecaptcha |
reCAPTCHA v2 |
ReCaptchaV3TaskProxyLess |
userrecaptcha + version=v3 |
reCAPTCHA v3 |
AntiTurnstileTaskProxyLess |
turnstile |
Turnstile |
ImageToTextTask |
base64 |
Image CAPTCHA |
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| JSON task format rejected | CaptchaAI uses form data | Switch to data={} instead of json={} |
type field not recognized |
CapSolver task types differ | Use CaptchaAI method names |
| Polling with POST | CapSolver uses POST for results | Use GET to /res.php |
Missing json=1 parameter |
CapSolver returns JSON by default | Add json=1 to CaptchaAI requests |
FAQ
How does CapSolver's pricing compare to CaptchaAI?
Per-solve costs are similar. CaptchaAI offers better value through higher Turnstile success rates (fewer wasted solves) and exclusive BLS/Cloudflare Challenge support.
Can I migrate gradually?
Yes. Route new projects to CaptchaAI and migrate existing ones over time. The wrapper class above makes it easy to swap providers.
Does CaptchaAI support CapSolver's recognition API?
CaptchaAI uses a different format but supports all the same CAPTCHA types plus additional ones (Cloudflare Challenge, BLS).
Related Guides
Better Turnstile and BLS support — switch to CaptchaAI today.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.