← all guides

Handling reCAPTCHA v3 in scrapers without dropping IP reputation

reCAPTCHA v2 gave you something to fight. A checkbox, a grid of traffic lights, a distorted string of letters. You could pay a solving service a fraction of a cent and move on. reCAPTCHA v3 doesn’t give you anything to fight. It sits on the page silently, watches everything your browser does from load to submit, and hands the site owner a number between 0.0 and 1.0. There’s no challenge to beat because there’s nothing to click. You either look human enough or you don’t, and you usually only find out which one you were after your conversion rate on that target quietly falls off a cliff.

The part that catches most scraping teams off guard is that the score isn’t purely a per-request judgment. It’s tied to a running history of your IP and your browser fingerprint against Google’s own network reputation data, plus whatever the site owner has fed back through their own risk signals. That means a bad session doesn’t just fail once, it taxes every session after it on the same identity. If you’re running a residential proxy pool across a dozen recaptcha-protected properties, a sloppy scraping pattern on one target can quietly poison your standing on all of them, because the underlying signals (IP reputation, TLS fingerprint, timing entropy) aren’t scoped to a single site.

This piece is for people who already know what a proxy pool is and have burned through a solving service subscription or two. I’m going to skip the “what is a CAPTCHA” preamble and go straight into how v3 actually scores you, three worked examples from jobs I’ve run, and the failure modes that keep showing up in production. This is not legal advice, and scraping legality depends on the target’s terms of service and your jurisdiction, so check both before you point anything at a live site.

background and prior art

Google shipped reCAPTCHA v3 in 2018 as a deliberate break from the interactive-challenge model. The official v3 documentation is blunt about the goal: no user interaction, a continuous score instead of a pass/fail gate, and the decision of what to do with that score left entirely to the site owner. Google recommends a 0.5 threshold as a starting point in their own FAQ, but in practice site owners tune this per page, so a comment form might tolerate 0.3 and a checkout or account-creation flow might reject anything under 0.7. You will never see the threshold. You only see the downstream effect: a silent block, a fallback v2 challenge injected mid-flow, or a “please try again later” page that has nothing to do with your rate limit.

The solving-service industry (2Captcha, Anti-Captcha, CapMonster Cloud) grew up around v2’s image grids and audio challenges, and all three still work fine for the v2 fallback challenges that get triggered when a v3 score comes back too low. What they don’t do is fix the underlying score. Buying a solved token gets you past that one gate. It does nothing for the IP and fingerprint history that produced the low score in the first place, so the next page on the same site, or the same recaptcha deployment on a different site under the same Google account cookie, scores you just as badly.

The countermove that emerged on the scraping side was the antidetect browser, a Chrome or Firefox build (or wrapper around one) that manages a stable, internally consistent fake fingerprint per identity rather than trying to look like a real browser through patched JS properties alone. That category gets covered in more depth over at antidetectreview.org’s blog, and it’s worth reading if you haven’t, because a lot of what breaks reCAPTCHA v3 scoring in production traces back to fingerprint management that was fine for older, less continuous defenses and isn’t fine here.

the core mechanism

reCAPTCHA v3’s score is built from three buckets of signal, and understanding which bucket a given mistake falls into tells you whether the fix is a proxy change, a browser change, or a behavior change.

Network and identity reputation. Google maintains its own view of which IP ranges are datacenter, which are residential, which are known VPN or proxy exits, and how those ranges have behaved on other recaptcha-protected sites. This is why a clean, freshly rotated datacenter IP can still score 0.1 on first contact, before your scraper has done anything: the range itself carries history. Google’s reCAPTCHA Enterprise documentation on interpreting the risk analysis score confirms the score folds in signals well beyond the current request, which lines up with what every operator sees empirically: identical browser automation scores wildly differently depending on what IP it’s routed through.

Browser and device fingerprint. Canvas rendering hashes, WebGL renderer and vendor strings, installed font lists, screen resolution and pixel ratio, timezone versus locale versus IP-geolocation consistency, and the presence of automation tells like navigator.webdriver. MDN’s reference on the navigator.webdriver property documents exactly the flag that stock Selenium and older Puppeteer builds leave set to true, which is one of the cheapest tells to fix and one of the most commonly missed. Beyond the obvious flags, the deeper problem is fingerprint entropy: if your antidetect setup clones the same canvas noise seed or the same font subset across hundreds of “unique” profiles, those profiles aren’t actually unique to anyone measuring entropy, they’re a cluster. The EFF’s Cover Your Tracks tool is built to demonstrate exactly this, how few fingerprint bits it takes to make a browser trackable, and it’s a legitimate way to sanity check whether your profile generator is producing real variance or just cosmetic variance.

Behavioral telemetry. Mouse movement curves and velocity, scroll patterns, time-on-page before an action, keystroke timing on any adjacent form fields, and how all of that compares to the millions of real sessions Google’s model has seen on similar pages. This is the bucket that’s hardest to fake cheaply and the one most scraping setups skip entirely, because headless automation typically jumps straight to the target element and fires a click or a synthetic form submission with no lead-up at all.

The mechanism that trips people up is that these three buckets interact multiplicatively, not additively. A residential IP with perfect timing but a cloned fingerprint still scores low. A unique fingerprint with perfect timing on a flagged datacenter IP still scores low. You need all three buckets clean at once, and the score you get back is effectively a floor set by your weakest bucket, not an average.

worked examples

Example 1: a job board login gate. We ran a scraper against a job listing site (similar in structure to the boards we’ve covered scraping guidance for, like Indeed and Glassdoor) using 40 concurrent sessions over a rotating residential pool of roughly 20,000 IPs. The automation used a fixed 1.2 second delay from page load to form submit on every session, an artifact of a hardcoded sleep(1200) left over from an earlier build. Scores opened around 0.7 on fresh IPs and dropped to 0.2 within the first 300-odd requests per IP, well under the site’s apparent action threshold, and we started seeing v2 fallback challenges injected on nearly every session. We replaced the fixed delay with a log-normal distribution centered around 3.5 seconds (roughly a 2 to 6 second spread) and added a synthetic mouse path using the ghost-cursor npm package to generate a curved, human-shaped movement into the submit button instead of a synthetic click at fixed coordinates. Average scores across the same IP pool moved to a 0.6-0.8 range within a day, and the v2 fallback rate dropped by roughly two thirds.

Example 2: proxy class matters more than proxy count. On a price-monitoring job hitting an account-creation-adjacent page, we started on a budget datacenter proxy provider priced around $0.50/GB. Every session scored under 0.15 regardless of how much we tuned behavior, because the ASN ranges were pre-flagged at the network layer before any page interaction happened. Switching the same automation, unchanged, to mobile carrier IPs (we tested with Decodo’s mobile pool, priced closer to $15-20/GB versus $4-8/GB for their residential tier at the time) pushed baseline scores to 0.5-0.6 immediately, because carrier-grade NAT ranges are shared with thousands of legitimate phone users and carry inherently better standing than a data-center block ever will. We’ve written more on how to tell these problems apart in diagnosing IP bans, proxy vs fingerprint, since this exact mismatch (bad proxy class disguised as a fingerprint problem) is one of the most common misdiagnoses we see.

Example 3: cookie hygiene isn’t what people think it is. Common advice says to clear cookies between every request to look “fresh.” We tested this directly, 500 requests split into two configurations against the same target. Configuration A kept a persistent browser profile mapped 1:1 to a sticky residential IP for the length of a session. Configuration B wiped cookies and local storage every request while keeping the same IP. Configuration A scored noticeably higher on average. Clearing everything constantly actually looks anomalous, because real users carry session history, prior recaptcha cookies (NID, 1P_JAR), and browsing state forward. The failure mode we found worse than either was reusing the same VM snapshot as the base image for dozens of “distinct” profiles: the canvas and font fingerprint repeated across supposedly unique identities even though cookies and IPs differed, which is the exact entropy problem the antidetect-browser space exists to solve properly.

edge cases and failure modes

Datacenter IPs get penalized before you’ve done anything. No amount of behavioral tuning fixes an ASN-level penalty. Check the proxy class against the target’s sensitivity before deploying, and treat recaptcha-heavy targets as residential or mobile only.

Cloned fingerprints across a profile fleet. If your antidetect tooling generates canvas noise or font subsets from a shared seed, hundreds of “unique” browser profiles collapse into a handful of actual fingerprints. Audit new profile templates with an entropy tool before rolling them out at scale, not after scores start dropping.

Timing that’s too consistent is as bad as timing that’s too fast. A scraper that waits exactly 2.000 seconds every time is a cleaner signal to a trained model than one that waits 200 milliseconds, because real human variance never looks that clean. Use a distribution, not a constant, for every delay in the flow.

Token replay and server-side reputation. The g-recaptcha-response token is single-use, validated once against Google’s siteverify endpoint and invalidated immediately after. Trying to reuse a token obtained through a solving service across multiple backend calls just fails outright, and repeated failed verify calls from the same backend IP get logged against your own infrastructure’s standing, separate from whatever proxy IP the browser session used.

TLS fingerprint mismatches from protocol-translating proxies. If your traffic claims to be Chrome 126 in the User-Agent header but the TLS ClientHello coming through your proxy gateway doesn’t match (a common artifact of proxies that terminate and re-negotiate TLS rather than passing it through), that mismatch is visible independent of anything JavaScript reports. This is the same class of signal PerimeterX and similar vendors check, and the countermeasures overlap heavily with what we cover in bypassing PerimeterX shields: use tooling that preserves the real browser’s TLS handshake rather than a gateway that swaps it out.

what we learned in production

The single biggest mindset shift on our team was dropping the idea that reCAPTCHA v3 is something you solve. It’s something you avoid triggering, and the difference matters because a solving service can get you past a v2 fallback challenge in the moment while doing nothing for the score that caused the fallback to appear. We stopped treating captcha-solver spend as the primary line item for recaptcha-heavy targets and started treating proxy class selection and fingerprint entropy as the primary spend, with solving services kept around purely as a fallback for the sessions that still get flagged despite everything else being clean. That reordering alone cut our fallback-challenge rate by more than half across the targets we track.

The second lesson took longer to accept because it contradicts a lot of scraping folk wisdom: rotating IPs aggressively, on every request, scores worse than holding a sticky IP for the length of a coherent session and rotating between sessions instead. Real users don’t get a new IP mid-checkout. We also stopped throwing new proxies straight into full load, we warm them up with light, human-paced traffic for the first day before running them hard, which mirrors the behavioral pattern issues we cover in debugging 429 errors and proxy quality and in cookie and session handling across rotating proxies. None of this is exotic. It’s closer to just not looking like a bot, over time, rather than looking like a human for one request.

references and further reading

more deep dives like this live on the proxyscraping.org blog.

Written by Xavier Fok

disclosure: this article may contain affiliate links. if you buy through them we may earn a commission at no extra cost to you. verdicts are independent of payouts. last reviewed by Xavier Fok on 2026-07-22.

proxies
Need proxies that survive the block wall?

Singapore Mobile Proxy runs real 4G/5G mobile IPs on rotating SIMs — the carrier-grade addresses most of these targets still trust.

see plans →
read on
More scraping guides

The rest of the field manual: target-site playbooks, library walkthroughs, provider reviews, and anti-bot troubleshooting.

browse all guides →