← 목록

reCAPTCHA v2 vs v3 vs Enterprise — how to tell which one you're fighting (and how to solve each)

devto 2026-07-01 원문 보기 ↗


reCAPTCHA v2 vs v3 vs Enterprise — how to tell which one you're fighting

"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

, and the page loads https://www.google.com/recaptcha/api.js. The sitekey starts with 6L. There's a visible checkbox; clicking it sometimes triggers an image grid ("select all bicycles").

v2 invisible — same api.js, same 6L... sitekey shape, but no visible checkbox. The widget is bound to a button or fired via grecaptcha.execute(), often with data-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= — the ?render= parameter is the dead giveaway. The page calls grecaptcha.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=... (note enterprise.js, not api.js), and the JS calls live under grecaptcha.enterprise.*. Enterprise can run in a v2-style or v3-style mode, so identify it by the enterprise.js include first, then check widget vs. ?render=.

Quick reference for the script tell:

What each means for automation

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 solving 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.

Here's the v3 case end to end; v2 is the same minus versionaction, 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", "actison": "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

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).