reCAPTCHA's Advanced Risk Analysis (ARA) engine evaluates dozens of signals to produce a score between 0.0 (definite bot) and 1.0 (definite human). This score determines whether you see no challenge, a checkbox, an image grid, or a hard block. Google does not publish the exact scoring algorithm, but extensive testing and reverse engineering have identified the key factors. This is a comprehensive technical analysis of what moves the score.
Score factor categories
reCAPTCHA evaluates signals in five categories, each contributing to the final score:
Final Score = f(Browser Signals, Behavioral Signals, Network Signals,
History Signals, Environmental Signals)
Category 1: Browser signals (weight: high)
Browser signals determine whether the client is a genuine browser or an automated tool.
JavaScript API presence
reCAPTCHA probes for APIs that headless browsers either lack or implement differently:
| API checked | Expected in real browser | Headless indicator |
|---|---|---|
navigator.webdriver |
undefined or false |
true (Selenium, Puppeteer) |
navigator.plugins |
PluginArray with 1+ items | Empty or missing |
navigator.languages |
Array with locale strings | Empty array or missing |
navigator.hardwareConcurrency |
2-16 (matches CPU) | Sometimes 0 or undefined |
navigator.deviceMemory |
2-16 GB | Missing in some headless |
window.chrome |
Object with runtime, etc. | Missing in headless Chrome |
Notification.permission |
"default", "granted", or "denied" | Throws or missing |
Impact on score: Missing or incorrect values for these APIs can drop the score by 0.3-0.5 points.
Canvas fingerprint
reCAPTCHA renders hidden canvas elements and reads back the pixel data. The result is a fingerprint unique to the browser/OS/GPU combination.
// reCAPTCHA performs something similar to:
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.textBaseline = "top";
ctx.font = "14px 'Arial'";
ctx.fillText("Hello", 2, 2);
const fingerprint = canvas.toDataURL();
Score impact:
- Consistent fingerprint matching browser/OS declaration → Neutral
- Fingerprint matches known headless pattern → -0.3 to -0.5
- Canvas operations blocked or return uniform data → -0.4 to -0.6
WebGL renderer
The WebGL renderer string reveals the GPU:
const gl = document.createElement('canvas').getContext('webgl');
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
// Expected: "ANGLE (NVIDIA GeForce GTX 1060...)"
// Headless: "SwiftShader" or "Google SwiftShader"
Score impact: SwiftShader (Google's software renderer used in headless Chrome) is a strong bot indicator, dropping scores by 0.3-0.5.
Category 2: Behavioral signals (weight: very high)
Behavioral signals have the highest weight in score calculation. They are collected from the moment the page loads.
Mouse movement
reCAPTCHA tracks mouse coordinates and timestamps throughout the page visit:
| Signal | Human pattern | Bot pattern |
|---|---|---|
| Movement count | 50-500+ events per page visit | 0-5 events |
| Trajectory | Curved paths with variable speed | Straight lines, constant speed |
| Acceleration | Natural ease-in/ease-out | Instant start/stop |
| Micro-movements | Small jitter while hovering | Perfectly still between actions |
| Target overshoot | Slight overshoot with correction | Precise targeting |
Score impact: No mouse movement drops the score by 0.4-0.7.
Keyboard activity
Inter-key timing:
Human: Variable (50-300ms between keys, varies by key pair)
Bot: Constant (all keys at same interval, or instant paste)
Key events:
Human: keydown → keypress → keyup for each character
Bot: May skip keypress, or fire all events simultaneously
Corrections:
Human: Occasional backspace, re-typing
Bot: Perfect input without corrections
Score impact: Instant text input (via clipboard or JavaScript value assignment) scores 0.1-0.2 lower.
Scroll behavior
reCAPTCHA monitors scroll events on the page:
- Humans: Gradual scroll with momentum, variable speed, pauses to read
- Bots: No scrolling, or instant jump to form area
Score impact: No scroll events before form interaction → -0.2 to -0.3.
Element interaction sequence
reCAPTCHA tracks which elements the user interacts with and in what order:
- Humans: Click around the page, hover over links, read content before filling form
- Bots: Navigate directly to form fields, fill in order, submit
Score impact: Direct-to-form behavior without page exploration → -0.1 to -0.3.
Category 3: Network signals (weight: medium-high)
IP reputation
Google maintains an IP reputation database based on:
- Previous reCAPTCHA challenge results from this IP
- Known data center IP ranges (AWS, GCP, Azure, DigitalOcean, etc.)
- Known proxy/VPN provider ranges
- Abuse reports and spam databases
- Search and advertising fraud signals
| IP type | Typical score impact |
|---|---|
| Residential, low abuse | Neutral to +0.1 |
| Residential, some abuse | -0.1 to -0.2 |
| Data center | -0.3 to -0.5 |
| Known proxy/VPN | -0.2 to -0.4 |
| Tor exit node | -0.4 to -0.6 |
| Recently flagged for abuse | -0.3 to -0.6 |
TLS fingerprint (JA3/JA4)
The TLS handshake reveals which cipher suites and extensions the client supports. Each browser has a characteristic fingerprint:
- Chrome: Specific cipher order, TLS 1.3, GREASE extensions
- Python requests: Different cipher order, no GREASE, simpler extension list
- curl: Minimal extensions, OpenSSL-specific patterns
Score impact: Non-browser TLS fingerprint → -0.2 to -0.4.
HTTP headers
reCAPTCHA's server checks the requesting client's HTTP headers:
| Header | Human indicator | Bot indicator |
|---|---|---|
User-Agent |
Matches known browser release | Outdated version, automation tool UA |
Accept-Language |
Populated with locale preferences | Missing or generic |
Accept-Encoding |
gzip, deflate, br |
Missing or unusual |
Sec-CH-UA |
Client hints matching browser | Missing (pre-2022 headers) |
Category 4: History signals (weight: medium)
Google account cookies
Users logged into a Google account with browsing history score higher:
SID,HSID,SSIDcookies → User has Google session- No Google cookies → Unknown user, lower starting score
Score impact: Active Google session → +0.1 to +0.3.
reCAPTCHA cookies
reCAPTCHA sets its own cookies after successful challenge completion:
_GRECAPTCHAcookie → Previous successful solverc::a,rc::b,rc::c→ Risk analysis data cookies
Score impact: Fresh session with no reCAPTCHA cookies → -0.1 to -0.2.
Cross-site reputation
Google tracks reCAPTCHA behavior across all sites using the same browser profile. Good behavior on site A improves scores on site B.
Category 5: Environmental signals (weight: low-medium)
Timezone consistency
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
// Should match IP geolocation
// "America/New_York" with a New York IP → consistent
// "America/New_York" with a Tokyo IP → suspicious
Screen and window dimensions
screen.width, screen.height // Physical screen
window.innerWidth, innerHeight // Browser window
window.outerWidth, outerHeight // Including browser chrome
Score impact: Unusual dimensions (0×0, extremely large, or exactly default) → -0.1 to -0.2.
Battery status (if available)
navigator.getBattery().then(battery => {
battery.level; // 0.0 to 1.0
battery.charging; // true/false
});
Battery API provides a minor signal — always-charging at 100% is consistent with a desktop development environment.
Score optimization strategies
For higher scores in automation
| Strategy | Expected impact | Difficulty |
|---|---|---|
| Use real Chrome (not headless) | +0.3 to +0.5 | Low |
Remove navigator.webdriver flag |
+0.2 to +0.3 | Low |
| Add mouse movement simulation | +0.2 to +0.4 | Medium |
| Use residential proxy IPs | +0.2 to +0.3 | Low (cost) |
| Maintain Google cookies across sessions | +0.1 to +0.2 | Medium |
| Match TLS fingerprint to Chrome | +0.1 to +0.3 | High |
| Simulate page exploration before form | +0.1 to +0.2 | Medium |
Or: Use an API solver
Instead of optimizing all these signals, use CaptchaAI to generate valid tokens regardless of score:
import requests
import time
API_KEY = "YOUR_API_KEY"
# Request a high-score token
submit = requests.post("https://ocr.captchaai.com/in.php", data={
"key": API_KEY,
"method": "userrecaptcha",
"googlekey": "6LcR_RsTAAAAAN_r0GEkGBfq3L7KmU5JbPHJtwNp",
"pageurl": "https://example.com/login",
"version": "v3",
"action": "login",
"min_score": "0.9",
"json": 1,
})
task_id = submit.json()["request"]
for _ in range(60):
time.sleep(5)
result = requests.get("https://ocr.captchaai.com/res.php", params={
"key": API_KEY,
"action": "get",
"id": task_id,
"json": 1,
}).json()
if result.get("status") == 1:
token = result["request"]
print(f"High-score token received")
break
The solver environment is optimized for maximum scores — handling all browser, behavioral, and network signals internally.
Frequently asked questions
What is a "good" reCAPTCHA v3 score?
A score of 0.7 or higher is generally considered human-like. Most websites set their threshold between 0.5 and 0.7. A score of 0.9 passes virtually all implementations. With CaptchaAI, you can request tokens with min_score=0.9.
Does VPN usage always lower the score?
VPN IPs from data centers typically lower scores by 0.2-0.4. However, residential VPN services produce better results. The score impact depends on the specific IP's reputation history, not the VPN service itself.
Why does my score differ between pages on the same site?
reCAPTCHA v3 uses the action parameter to contextualize scores. Different actions (homepage, login, checkout) may have different baseline scores. Also, behavioral signals accumulate during the session — later pages may score higher because more behavior data is available.
Can I check my reCAPTCHA score without owning the site?
Not directly. reCAPTCHA v3 scores are returned only to the server via the siteverify API. However, you can estimate your score by observing whether sites show you challenges (low score) or pass you through (high score) on known reCAPTCHA v3 implementations.
Summary
reCAPTCHA scores are determined by browser fingerprint (API presence, canvas, WebGL), behavioral analysis (mouse movement, keyboard timing, scroll patterns), network reputation (IP type, TLS fingerprint), history (Google cookies, previous solves), and environmental consistency (timezone, screen dimensions). For automation that needs consistent high scores, use CaptchaAI to generate tokens with min_score=0.9, bypassing the need to optimize each signal category individually.
Discussions (0)
Join the conversation
Sign in to share your opinion.
Sign InNo comments yet.