24 smart signals: incognito detection, tampering analysis, VM detection, suspect scoring, and velocity tracking
Smart Signals are server-side enrichment signals computed from browser fingerprints, IP intelligence, and behavioral analysis. They provide deep context about every visitor without collecting any personally identifiable information. Smart signals are included in every identification response when extendedResult: true is set, and are always available via the Server API.
Each smart signal is computed independently on the server after the client SDK submits browser signals. The server combines the browser-collected data with IP intelligence databases, behavioral history, and cross-signal correlation to produce 24 distinct signal outputs. All signals are returned in a single JSON response with sub-50ms latency.
The following table lists all 24 smart signals with their product key, description, response format, and platform support. Each signal is documented in detail in the sections below.
| # | Signal | Product Key | Description | Platform |
|---|---|---|---|---|
| 1 | VPN Detection | vpn | Detects VPN usage via timezone mismatch, ASN matching, relay detection, and TURN probe | Web, Mobile |
| 2 | Proxy Detection | proxy | Identifies datacenter, residential, HTTP, and SOCKS proxies | Web, Mobile |
| 3 | Tor Detection | tor | Matches IP against known Tor exit node list (updated hourly) | Web, Mobile |
| 4 | IP Geolocation | ipLocation | City-level geolocation with coordinates, timezone, and accuracy radius | Web, Mobile |
| 5 | IP Blocklist | ipBlocklist | Checks IP against threat intelligence feeds for known attackers | Web, Mobile |
| 6 | Bot Detection | botd | 14-method detection for automation frameworks and headless browsers | Web, Mobile |
| 7 | Incognito | incognito | Detects private/incognito browsing mode across all major browsers | Web |
| 8 | Browser Tampering | tampering | Detects spoofed UA, modified navigator, extension injection, native function overrides | Web |
| 9 | Virtual Machine | virtualMachine | Detects VMware, VirtualBox, Parallels, QEMU, and Hyper-V | Web |
| 10 | Emulator | emulator | Detects mobile emulators (BlueStacks, Genymotion, Android SDK) | Web (mobile UA) |
| 11 | Cloned App | clonedApp | Detects dual-space and parallel app environments | Web (mobile) |
| 12 | Factory Reset | factoryReset | Identifies devices that have been factory reset recently | Web |
| 13 | Frida Detection | frida | Detects Frida instrumentation toolkit used for reverse engineering | Web (mobile) |
| 14 | Privacy Browser | privacySettings | Detects Tor Browser, Brave shields, Firefox ETP, Safari ITP | Web |
| 15 | Developer Tools | developerTools | Detects when browser DevTools is actively open | Web |
| 16 | Velocity | velocity | Tracks distinct IPs, countries, and events across 5m/1h/24h windows | Web, Mobile |
| 17 | Suspect Score | suspectScore | Aggregated risk score (0-100) from all signals | Web, Mobile |
| 18 | High-Activity | highActivity | Flags devices with abnormally high request volumes | Web, Mobile |
| 19 | Remote Desktop | remoteDesktop | Detects remote control software (TeamViewer, AnyDesk, RDP) | Web |
| 20 | Canvas Farbling | canvasFarbling | Detects Brave-style canvas randomization that alters fingerprint output | Web |
| 21 | Timezone Mismatch | timezoneMismatch | Standalone timezone-vs-IP analysis (also used by VPN detection) | Web, Mobile |
| 22 | Residential Proxy | residentialProxy | Detects residential proxy networks via velocity and P2P signatures | Web, Mobile |
| 23 | Relay Detection | relay | Identifies iCloud Private Relay and Cloudflare WARP specifically | Web, Mobile |
| 24 | IP Reputation | ipReputation | IP risk scoring based on historical abuse patterns | Web, Mobile |
tracio.ai detects VPN usage through four independent methods. Each method operates independently, and the combined result includes a confidence level reflecting how many methods agree.
Intl.DateTimeFormat) against the GeoIP timezone. A mismatch indicates the user's network traffic is routed through a different geographic location.Confidence levels:
{ "vpn": { "data": { "result": true, "confidence": "high", "originTimezone": "America/New_York", "methods": { "timezoneMismatch": true, "publicVPN": true, "osMismatch": false, "relay": false } } }}Identifies various proxy types including datacenter proxies, residential proxies, HTTP proxies, and SOCKS proxies. Datacenter proxies are detected via ASN matching against known hosting providers. Residential proxies are identified through velocity analysis -- when too many distinct visitor IDs appear from a single residential IP address, it indicates the IP is being shared through a proxy network.
{ "proxy": { "data": { "result": true, "confidence": "high" } }}Matches the visitor's IP address against a continuously updated list of known Tor exit nodes. The exit node list is refreshed hourly from the Tor Project's directory authorities. Tor detection is supplemented by browser-side signals: Tor Browser has a distinctive fingerprint profile including blocked canvas, blocked WebGL, UTC timezone, a limited font set, and rounded screen dimensions.
{ "tor": { "data": { "result": true } }}Checks the visitor's IP address against aggregated threat intelligence feeds covering known spam sources, attack origins, malware command-and-control servers, and credential stuffing infrastructure. The blocklist is updated daily and covers millions of known-bad IP addresses.
{ "ipBlocklist": { "data": { "result": true, "details": { "emailSpam": false, "attackSource": true } } }}VM detection uses 6 weighted markers derived from WebGL parameters, screen characteristics, and hardware properties. Detection requires either a GPU match (WebGL renderer/vendor containing known VM strings) plus 2 or more additional markers, or 3 or more markers without a GPU match.
Detects mobile device emulators commonly used for app fraud, automated testing, and click farms. The detection cross-references the mobile User-Agent with hardware signals that are impossible or improbable on real mobile hardware, such as desktop-class GPU renderers, unusual screen dimensions, or missing mobile-specific APIs.
Frida is a dynamic instrumentation toolkit used by security researchers and attackers to hook into running processes, modify function behavior, and bypass security controls. tracio.ai detects Frida by testing for instrumentation artifacts in the JavaScript environment, including hooked native functions, injected globals, and modified prototype chains that are characteristic of Frida's JavaScript bridge.
The tampering detector identifies visitors who have modified their browser environment to misrepresent their identity. It uses four independent detection strategies:
navigator.userAgentData), navigator properties, and JavaScript engine behavior to detect mismatches.navigator properties by comparing getter prototypes against expected native implementations.PluginArray.prototype and MimeType.prototype chains to detect synthetic plugin lists.Function.prototype.toString and other critical functions have been replaced with Proxy objects or modified implementations.The anomalyScore (0.0-1.0) quantifies the degree of inconsistency. Values below 0.2 are common with browser extensions and are usually benign. Values above 0.5 indicate significant, deliberate tampering. Values above 0.8 strongly suggest anti-detection browser software.
| Score | Interpretation | Typical Cause |
|---|---|---|
| 0.0 - 0.1 | Clean | No tampering detected |
| 0.1 - 0.3 | Minor | Browser extensions modifying one or two properties |
| 0.3 - 0.5 | Moderate | Privacy extension or anti-fingerprinting tool active |
| 0.5 - 0.8 | Significant | Deliberate identity spoofing (e.g., User-Agent switcher + property injection) |
| 0.8 - 1.0 | Severe | Anti-detect browser (Multilogin, GoLogin, AdsPower) or full environment spoofing |
Detects private/incognito browsing mode across all major browsers. The detection is based on multi-signal correlation since browsers do not expose a direct API for querying private mode status. Detection strategies vary by browser engine: storage quota differences in Chrome, FileSystem API behavior in Firefox, and Safari-specific storage restrictions.
| Browser | Detection Method | Threshold |
|---|---|---|
| Tor Browser | Canvas blocked + WebGL blocked + UTC timezone + limited fonts + rounded screen size | 3+ markers |
| Brave | Brave UA or navigator.brave or Client Hints "Brave" brand | 1+ marker |
| Firefox ETP (strict) | Storage partitioned + canvas resisted (Firefox UA required) | 2 markers |
| Safari ITP | Cookies blocked + IndexedDB restricted (Safari UA required) | 2 markers |
The suspect score aggregates all smart signal outputs into a single risk integer (0-100), making it easy to implement threshold-based access control without writing complex multi-signal logic. The score is computed by summing weighted contributions from six risk categories.
| Score Range | Risk Level | Typical Indicators | Recommended Action |
|---|---|---|---|
| 0-10 | Normal | Clean signals, known visitor, residential IP | Allow access without friction |
| 11-30 | Low | Minor inconsistencies, datacenter IP, or first visit | Monitor, no action needed |
| 31-60 | Medium | VPN detected, browser tampering, or unusual velocity | Show CAPTCHA or require email verification |
| 61-80 | High | Multiple risk signals, proxy + tampering, high activity | Require MFA or manual review |
| 81-100 | Critical | Bot detected, Tor exit node, or severe anomalies | Block or rate-limit immediately |
The score computation considers 6 categories, each contributing up to its maximum weight:
Velocity tracking monitors visitor and IP activity across three rolling time windows. It provides insight into how frequently a visitor appears, how many IP addresses they use, and whether they are connecting from multiple countries. This data is invaluable for detecting account sharing, credential stuffing, and geographic impossibility.
{ "velocity": { "data": { "distinctIp": { "intervals": { "5m": 1, "1h": 2, "24h": 4 } }, "distinctCountry": { "intervals": { "5m": 1, "1h": 1, "24h": 2 } }, "events": { "intervals": { "5m": 3, "1h": 12, "24h": 47 } } } }}| Metric | Description | Suspicious Threshold |
|---|---|---|
distinctIp | Number of unique IP addresses seen for this visitor in each window | 3+ in 1h, 8+ in 24h |
distinctCountry | Number of unique countries seen for this visitor in each window | 2+ in 1h (impossible travel) |
events | Total identification events for this visitor in each window | 50+ in 1h, 200+ in 24h |
const event = await fetchEvent(requestId);const score = event.products.suspectScore.data.result;const isVPN = event.products.vpn.data.result;const isBot = event.products.botd.data.bot.result === 'bad';const isTor = event.products.tor.data.result;if (isBot) { return block('Automated access detected');}if (isTor || score > 80) { return block('High-risk access pattern');}if (score > 60) { return requireMFA();}if (isVPN && score > 30) { return requireCaptcha();}return allow();function computeFraudRisk(event: FPEvent): string { const { suspectScore, vpn, proxy, velocity, tampering, tor } = event.products; let risk = 'low'; // Start with suspect score if (suspectScore.data.result > 60) risk = 'high'; else if (suspectScore.data.result > 30) risk = 'medium'; // Escalate if multiple signals agree if (vpn.data.result && proxy.data.result) risk = 'high'; if (tampering.data.result && tampering.data.anomalyScore > 0.5) risk = 'high'; if (velocity.data.distinctIp.intervals['24h'] > 10) risk = 'high'; if (tor.data.result) risk = 'high'; // Impossible travel: 2+ countries in 1 hour if (velocity.data.distinctCountry.intervals['1h'] >= 2) risk = 'high'; return risk;}async function checkAccountTakeover(userId: string, requestId: string) { const event = await fetchEvent(requestId); const currentVisitorId = event.products.identification.data.visitorId; const knownDevices = await db.userDevices.findAll({ userId }); // New device accessing this account if (!knownDevices.includes(currentVisitorId)) { const suspectScore = event.products.suspectScore.data.result; const isVPN = event.products.vpn.data.result; const velocity = event.products.velocity.data; // High-risk indicators on a new device if (suspectScore > 40 || isVPN || velocity.distinctCountry.intervals['24h'] > 1) { await sendSecurityAlert(userId, { type: 'new_device_suspicious', visitorId: currentVisitorId, suspectScore, isVPN, country: event.products.identification.data.ipLocation.country.code, }); return { action: 'require_mfa', reason: 'new_device_with_risk_signals' }; } // New device but low risk - just notify await sendNewDeviceNotification(userId, currentVisitorId); return { action: 'allow_with_notification' }; } return { action: 'allow' };}