reCAPTCHA v2 vs v3 vs Enterprise - how to tell which one you're fighting (and how to solve each)
"reCAPTCHA is blocking me" is the start of a debugging session, not the end of one. There are four practical variants - v2 checkbox, v2 invisible, v3 score, and Enterprise - and they behave completely differently. They fail differently, they're solved differently, and the call you make to a solver isn't the same shape. So before you touch any code, the first job is identifying which one you're up against. The page tells you, if you know where to look.
How to tell which variant it is
Everything you need is in the page source and the script tags. Open devtools, look at the rendered widget and the api.js include.
- v2 checkbox - the classic "I'm not a robot" box. In the DOM you'll see a
<div class="g-recaptcha">, and the page loadshttps://www.google.com/recaptcha/api.js. The sitekey starts with6L. There's a visible checkbox; clicking it sometimes triggers an image grid ("select all bicycles"). - v2 invisible - same
api.js, same6L...sitekey shape, but no visible checkbox. The widget is bound to a button or fired viagrecaptcha.execute(), often withdata-size="invisible". It only shows an image challenge if Google decides the session looks risky. - v3 score - there is no widget and no checkbox at all. The script include is
https://www.google.com/recaptcha/api.js?render=KEY- the?render=parameter is the dead giveaway. The page callsgrecaptcha.execute(sitekey, {action: 'login'})and gets back a token plus a 0.0–1.0 score that the site's backend evaluates. - Enterprise - the script is
https://www.google.com/recaptcha/enterprise.js?render=...(noteenterprise.js, notapi.js), and the JS calls live undergrecaptcha.enterprise.*. Enterprise can run in a v2-style or v3-style mode, so identify it by theenterprise.jsinclude first, then check widget vs.?render=.
Quick reference for the script tell
api.js+ visible checkbox → v2 checkboxapi.js+data-size="invisible"/execute()→ v2 invisibleapi.js?render=KEY→ v3enterprise.js→ Enterprise (then check widget vs. score mode)
What each means for automation
- v2 checkbox is a puzzle problem - you need a token representing a solved challenge.
- v2 invisible is mostly the same under the hood, except the challenge only surfaces when you look risky. Clean up IP/fingerprint and it often passes silently.
- v3 is a reputation problem, not a puzzle. Nothing to click - you're scored on IP, fingerprint, behavior, and the action. A "fail" means you scored below the site's threshold.
- Enterprise is the same two modes wearing a different SDK. The practical difference is the namespace and sometimes a required
actionenterpriseflag. It's the same v2/v3 mechanics with more backend signals on the site's side; your client job barely changes.
The most common mistake: grabbing a token for the wrong variant - a plain v2 token sent to a v3 endpoint, or v3 solved without the matching action. The token comes back fine, the form submits, and the site silently rejects it. Identifying correctly up front saves that whole loop.
The solve flow per variant
If your solver already speaks the 2Captcha-style API (method=userrecaptcha, googlekey, pageurl), every variant is the same endpoint with a couple of parameters flipped. Submit to in.php, poll res.php, drop the token into g-recaptcha-response.
- v2 checkbox / invisible:
method=userrecaptcha,googlekey=,pageurl=. Invisible uses the exact same call. - v3: add
version=v3andaction=(e.g.login). The action must match what the page passes toexecute(). You can't request a score - the site's backend sets the minimum. - Enterprise: add
enterprise=1alongside the v2 or v3 parameters depending on the mode. Samegooglekey/pageurl; if score mode, still sendaction.
Here's the v3 case end to end; v2 is the same minus version/action, Enterprise adds enterprise=1:
import requests, time
API_KEY = "YOUR_API_KEY"
SITEKEY = "6Lc..." # the data-sitekey / render key
PAGEURL = "https://target.example/login"
# submit (v3 shown; drop version+action for v2, add enterprise=1 for Enterprise)
rid = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"version": "v3",
"action": "login",
"googlekey": SITEKEY,
"pageurl": PAGEURL,
"json": 1,
}).json()["request"]
# poll
token = None
for _ in range(40):
time.sleep(3)
res = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": rid,
"json": 1
}).json()
if res["status"] == 1:
token = res["request"]
break
# submit token as g-recaptcha-response (matching the action for v3)
TL;DR
Identify from the script include: api.js (v2), api.js?render= (v3), enterprise.js (Enterprise); then checkbox vs. invisible vs. score by the widget/flow. v2 = puzzle/token, v3 = reputation/score, Enterprise = same two modes, different SDK + an enterprise flag. Solve flow is one endpoint: userrecaptcha + googlekey + pageurl, with version=v3/action for v3 and enterprise=1 for Enterprise. CaptchaAI returns tokens for reCAPTCHA v2 (checkbox + invisible), v3 (with action), and Enterprise, and it's 2Captcha-API-compatible - so an existing client is mostly a base-URL change. The trial is free (3 days, no card).
Comments
No comments yet. Start the discussion.