Migrating reCAPTCHA solving off 2Captcha: the one-line swap
Most teams who solve reCAPTCHA at volume started on 2Captcha. What people don't realize is that the 2Captcha API has effectively become a shared interface — several providers implement the same in.php / res.php contract. So switching usually isn't a rewrite; it's a base-URL change.
This matters because the main reason to switch is cost at volume (per-1,000 scales linearly; thread-based flattens it). If migrating were a big refactor the savings wouldn't be worth it. It isn't, so they are.
The actual diff
Typical 2Captcha reCAPTCHA code:
import requests, time
API_KEY = "YOUR_KEY"
BASE = "https://2captcha.com" # the only provider-specific line
submit = requests.get(f"{BASE}/in.php", params={
"key": API_KEY, "method": "userrecaptcha",
"googlekey": SITE_KEY, "pageurl": PAGE_URL})
task_id = submit.text.split("|")[1]
while True:
r = requests.get(f"{BASE}/res.php", params={"key": API_KEY, "action": "get", "id": task_id})
if r.text == "CAPCHA_NOT_READY": time.sleep(5); continue
token = r.text.split("|")[1]; break
Migrating to a 2Captcha-compatible provider:
BASE = "https://ocr.captchaai.com" # changed
API_KEY = "YOUR_NEW_KEY" # changed
# everything else is byte-for-byte identical
method=userrecaptcha, googlekey, pageurl, the OK| response, CAPCHA_NOT_READY polling, the token — all the same. Wrapped it in a client class? Change one constant. Used an SDK? Point it at the new base URL.
What stays identical
The reCAPTCHA flow: v2 checkbox, v2 invisible, v3 version=v3 + min_score) — same call shape.
Token handling, your retry/timeout/polling logic — untouched.
What changes
The pricing model (the point): per-1,000 → per-thread with unlimited solves. Size for peak concurrency, not monthly total.
Latency / success-rate are provider-specific — so measure, don't assume.
How to migrate without betting the pipeline on it
Keep 2Captcha wired in; add the new provider behind the same interface (same calls — trivial).
Route ~10% of traffic to the new one.
Compare on your targets: success rate, median latency, cost per 1,000.
Holds up? Ramp. Doesn't? You've lost nothing.
Because the API is identical, that A/B harness is a few lines and a flag.
The honest version
A compatible provider is a drop-in at the API level — that part is a one-line swap. Whether it's the right swap depends on your numbers: run the A/B on real traffic and let the data decide. Compatibility just makes that test cheap.
Top comments (0)