Manual CAPTCHA solving — where a human solves each CAPTCHA by hand — works until your volume grows beyond what one person can handle. CaptchaAI replaces the human step with an API call, keeping the rest of your workflow intact.
This guide shows how to migrate step by step.
Before and after
| Aspect | Manual | CaptchaAI API |
|---|---|---|
| Speed | 10–30 seconds per solve (human) | 5–30 seconds (automated) |
| Scale | 1 solve at a time | Hundreds in parallel |
| Availability | Working hours | 24/7 |
| Consistency | Human error, fatigue | Consistent accuracy |
| Integration | Copy-paste tokens | Direct API call |
Step 1: Identify where CAPTCHAs appear
Before changing code, map every CAPTCHA in your workflow:
Login page → reCAPTCHA v2 (sitekey: 6Le-wv...)
Search page → No CAPTCHA
Checkout → Cloudflare Turnstile (sitekey: 0x4AAA...)
For each CAPTCHA, note:
- Type (reCAPTCHA v2, Turnstile, image, etc.)
- Sitekey (from the page HTML)
- When it appears (always, or only sometimes)
Step 2: Get your API key
- Sign up at captchaai.com
- Add balance to your account
- Copy your API key from the dashboard
Step 3: Replace manual solving with API calls
Before (manual flow)
# Manual workflow
def solve_captcha_manual():
print("CAPTCHA detected! Please solve it in the browser...")
token = input("Paste the token here: ")
return token
After (CaptchaAI API)
import requests
import time
API_KEY = "YOUR_API_KEY"
def solve_captcha(method, params):
"""Solve any CAPTCHA via CaptchaAI API."""
params["key"] = API_KEY
params["json"] = 1
# Submit
submit = requests.post("https://ocr.captchaai.com/in.php", data=params).json()
if submit.get("status") != 1:
raise RuntimeError(f"Submit error: {submit.get('request')}")
task_id = submit["request"]
time.sleep(10)
# Poll
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"Error: {result['request']}")
time.sleep(5)
raise TimeoutError("Solve timed out")
Step 4: Update each CAPTCHA touchpoint
reCAPTCHA v2
# Before: manual
token = input("Paste reCAPTCHA token: ")
# After: API
token = solve_captcha("userrecaptcha", {
"method": "userrecaptcha",
"googlekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"pageurl": "https://example.com/login"
})
Image CAPTCHA
import base64
# Before: manual
print("Look at captcha.png and type the text")
answer = input("Answer: ")
# After: API
with open("captcha.png", "rb") as f:
body = base64.b64encode(f.read()).decode()
answer = solve_captcha("base64", {
"method": "base64",
"body": body
})
Cloudflare Turnstile
# Before: manual
token = input("Paste Turnstile token: ")
# After: API
token = solve_captcha("turnstile", {
"method": "turnstile",
"sitekey": "0x4AAAAAAADnPIDROz1234",
"pageurl": "https://example.com/form"
})
Step 5: Add error handling
Manual solving has implicit error handling — the human retries. With API solving, add explicit handling:
def solve_with_retry(method, params, max_retries=3):
"""Solve with automatic retry on failure."""
for attempt in range(max_retries):
try:
return solve_captcha(method, params)
except RuntimeError as e:
error_msg = str(e)
if "ERROR_ZERO_BALANCE" in error_msg:
raise # Cannot retry — no balance
if "ERROR_NO_SLOT_AVAILABLE" in error_msg:
time.sleep(2 ** attempt)
continue
raise
except TimeoutError:
if attempt < max_retries - 1:
continue
raise
raise RuntimeError("Max retries exceeded")
Step 6: Update your workflow loop
Before (manual, sequential)
for url in urls:
page = load_page(url)
if has_captcha(page):
print(f"CAPTCHA on {url} — please solve manually")
token = input("Token: ")
submit_with_token(url, token)
process(page)
After (automated, can run unattended)
for url in urls:
page = load_page(url)
if has_captcha(page):
captcha_type = detect_type(page)
token = solve_with_retry(captcha_type["method"], captcha_type["params"])
page = submit_with_token(url, token)
process(page)
Migration checklist
| Step | Action | Done |
|---|---|---|
| 1 | Map all CAPTCHAs in your workflow | ☐ |
| 2 | Get CaptchaAI API key and add balance | ☐ |
| 3 | Create solver function with submit/poll pattern | ☐ |
| 4 | Replace each input() or manual step with API call |
☐ |
| 5 | Add error handling and retry logic | ☐ |
| 6 | Test each CAPTCHA type end-to-end | ☐ |
| 7 | Set up balance monitoring | ☐ |
| 8 | Remove manual solving code | ☐ |
FAQ
Can I keep manual solving as a fallback?
Yes. If the API returns an error, you can fall back to manual solving. But this should be rare — fix root causes instead.
How long does migration take?
For a simple scraper with one CAPTCHA type, under an hour. For complex workflows with multiple CAPTCHA types, a few hours.
Will my existing scraper logic need to change?
Only the CAPTCHA-solving part. The rest of your workflow — page loading, data extraction, storage — stays the same.
What if I am migrating from another CAPTCHA API?
CaptchaAI uses the same submit/poll pattern as most CAPTCHA APIs. Change the endpoint URLs and adjust parameter names. The flow is nearly identical.
Get your CaptchaAI API key
Automate your CAPTCHA solving at captchaai.com.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.