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.
Quick reference
Section titled “Quick reference”| 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 |
reCAPTCHA versions
Section titled “reCAPTCHA versions”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 → v2https://www.google.com/recaptcha/api.js?render=6LdyC2cUAAAAACGuDKpXeDorzUDWXmdqeg-xy696 → v3https://www.google.com/recaptcha/enterprise.js?render=explicit → v2 EnterpriseInvisible 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:
// 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.
Turnstile vs the challenge page
Section titled “Turnstile vs the challenge page”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_tkorcdn-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.