Skip to content

Identify the captcha type

Choosing the right task type starts with recognizing the captcha. The most reliable way is to open the browser’s developer tools (F12) and see in the Network panel which captcha script the page loads; you can also tell by appearance.

What you see What it is Task type
An “I’m not a robot” checkbox reCAPTCHA v2 reCAPTCHA v2
No checkbox; an image challenge appears after you click submit; a small reCAPTCHA badge in the corner Invisible reCAPTCHA v2 (or v3) See “reCAPTCHA versions” below
No interaction at all; only the reCAPTCHA badge reCAPTCHA v3 reCAPTCHA v3
An “I am human” checkbox; image challenges branded hCaptcha hCaptcha hCaptcha
A Cloudflare widget inside a form; the page stays put after the check Cloudflare Turnstile Turnstile
The whole page shows “Just a moment…” / “Checking your connection” and then redirects Cloudflare challenge page Cloudflare challenge page
Arkose Labs puzzles (such as “Pick the image that is the correct way up”) FunCaptcha FunCaptcha
An image of distorted letters and digits Text captcha Image to text

Search the Network panel for api.js or enterprise.js:

Script loaded Version
recaptcha/api.js with no render parameter or render=explicit v2
As above, and the anchor request URL contains size=invisible Invisible v2: add "isInvisible": true
recaptcha/api.js?render=SITE_KEY (render is not explicit) v3
recaptcha/enterprise.js with no render parameter or render=explicit v2 Enterprise
recaptcha/enterprise.js?render=SITE_KEY v3 Enterprise

Examples:

https://www.google.com/recaptcha/api.js?onload=onloadcallback&render=explicit → v2
https://www.google.com/recaptcha/api.js?render=6LdyC2cUAAAAACGuDKpXeDorzUDWXmdqeg-xy696 → v3
https://www.google.com/recaptcha/enterprise.js?render=explicit → v2 Enterprise

Invisible v2 sometimes passes only with a v3 type; try both.

You can also run this in the browser console. It lists every reCAPTCHA on the page with its version, site key, page URL and callback:

find-recaptcha-clients.js
// Paste into the browser DevTools console on a page with reCAPTCHA, then run findRecaptchaClients().
// Lists every reCAPTCHA on the page: version (V2/V3), sitekey, page URL and the callback function.
function findRecaptchaClients() {
if (typeof ___grecaptcha_cfg === 'undefined') return [];
return Object.entries(___grecaptcha_cfg.clients).map(([cid, client]) => {
const data = { id: cid, version: cid >= 10000 ? 'V3' : 'V2' };
const objects = Object.entries(client).filter(([, value]) => value && typeof value === 'object');
objects.forEach(([toplevelKey, toplevel]) => {
const found = Object.entries(toplevel).find(
([, value]) => value && typeof value === 'object' && 'sitekey' in value && 'size' in value,
);
if (toplevel instanceof HTMLElement && toplevel.tagName === 'DIV') data.pageurl = toplevel.baseURI;
if (found) {
const [sublevelKey, sublevel] = found;
data.sitekey = sublevel.sitekey;
const callbackKey = data.version === 'V2' ? 'callback' : 'promise-callback';
const callback = sublevel[callbackKey];
if (!callback) {
data.callback = null;
data.function = null;
} else {
data.function = callback;
const keys = [cid, toplevelKey, sublevelKey, callbackKey].map((key) => `['${key}']`).join('');
data.callback = `___grecaptcha_cfg.clients${keys}`;
}
}
});
return data;
});
}
findRecaptchaClients();

Example output:

[
{
"id": "0",
"version": "V2",
"sitekey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"function": "onSuccess",
"callback": "___grecaptcha_cfg.clients['0']['l']['l']['callback']",
"pageurl": "https://www.google.com/recaptcha/api2/demo"
}
]

Google’s demo pages are useful for comparison: v2 https://www.google.com/recaptcha/api2/demo, invisible v2 https://www.google.com/recaptcha/api2/demo?invisible=true.

Both come from Cloudflare, but they are different:

  • Turnstile is a widget embedded in a page’s form. After verification it shows a check mark and the page stays where it is. The page loads challenges.cloudflare.com/turnstile/v0/api.js. Use Turnstile.
  • The challenge page replaces the whole page with Cloudflare’s “Just a moment…” / “example.com needs to review the security of your connection” screen, which may also contain a widget; after passing, it redirects to the real page. The source contains __cf_chl_rt_tk or cdn-cgi/challenge-platform. Use Cloudflare challenge page.

If your program gets a 403 with “Just a moment…” but a browser opens the page directly, you’re probably only being blocked by TLS fingerprinting. A library that imitates a browser’s TLS fingerprint (such as curl_cffi) usually fixes it without solving anything.