Getting Started

Migrate from Manual CAPTCHA Solving to CaptchaAI API

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

  1. Sign up at captchaai.com
  2. Add balance to your account
  3. 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)

No comments yet.