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 — the enriched decision, risk, network, and bot signals — reach your server two ways: pushed to you as webhooks (see Webhooks) and readable on demand through the Server API. They are also surfaced in the dashboard. The examples below consume the webhook payload shape; the same fields appear on a session read from the API.
A visit resolves into 35+ smart signals across network, browser, device and behavioral analysis. The reference below names the ones you will reach for most often, including:
| Signal | Description | Response | Platform |
|---|---|---|---|
| VPN Detection | Flags VPN usage from IP intelligence | network.vpn: boolean | Web |
| Proxy Detection | Identifies datacenter and residential proxy usage | network.proxy: boolean | Web |
| Tor Detection | Matches IP against known Tor exit nodes | network.tor: boolean | Web |
| Datacenter | Flags IPs belonging to known cloud/hosting providers | network.datacenter: boolean | Web |
| IP Geolocation | City-level geolocation + ISP and ASN from IP address | geo.{ country, city, timezone }, network.{ isp, asn } | Web |
| Signal | Description | Response | Availability |
|---|---|---|---|
| Browser Tampering | Detects spoofed User-Agent, modified navigator, extension injection | { result: boolean, anomalyScore: number } | Web |
| Antidetect Browsers | Scores fingerprint-spoofing browser builds via CSS and property probes | bot.antidetectScore: number (0–100, Pro+) | Web |
| Privacy Settings | Detects privacy-focused browser configurations (Tor Browser, Brave, Firefox ETP, Safari ITP) | { result: boolean } | Web |
| Developer Tools | Detects when browser DevTools is open | { result: boolean } | Web — Business & Enterprise |
| Incognito | Infers private browsing across Chromium, Firefox and Safari | identification.incognito: boolean | Web |
| Signal | Description | Availability |
|---|---|---|
| Emulator | Detects Android emulators (BlueStacks, Genymotion, Nox, Android SDK) via GPU renderer and UA markers | Web — all plans |
Native-only detections. Root, jailbreak, cloned/dual-app and Frida instrumentation depend on signals only a native mobile SDK can collect. TRACIO ships browser SDKs, so these are not effective in the web agent — rely on the automation, headless, antidetect, emulator and behavioral verdicts instead.
| Signal | Description | Response | Platform |
|---|---|---|---|
| Bot Detection | Identifies automation frameworks and headless browsers | bot.result: "human"|"bot"|"uncertain", bot.type: string, bot.score: number | Web |
| Risk Score | Aggregated risk for the request, on the webhook decision object | decision.riskScore: number, decision.suspectScore: number, decision.action: "real"|"fake"|"suspicious" | Web |
VPN, proxy, Tor, and datacenter flags are resolved server-side from the
visitor's IP using commercial IP intelligence databases (IP2Location /
MaxMind). The public webhook payload surfaces the combined results as booleans
on the network object — network.vpn, network.proxy, network.tor,
network.datacenter — with no per-method breakdown or confidence string. See
IP Intelligence for details.
Private browsing is inferred across Chromium, Firefox and Safari and reaches you as
identification.incognito. There is no browser API that reports it, so the verdict
comes from weighted voting over how storage behaves in a private window — origin
private file system errors, storage durability, and platform-specific quirks each
contribute.
It is a probabilistic signal, not a certainty: treat it as one input among several
rather than a fact to act on alone. Because private windows also suppress the
_vid_t cookie, an incognito visit is identified from signals only, and its
identification.confidence is correspondingly lower.
The tampering detector identifies visitors who have modified their browser to misrepresent their identity:
navigator properties by comparing getter prototypesPluginArray.prototype and MimeType.prototype chainsFunction.prototype.toString, Object.getOwnPropertyDescriptor, and other critical functions have been replaced with ProxiesThe anomalyScore (0.0-1.0) quantifies the degree of inconsistency. Values above 0.5 indicate significant tampering.
The webhook decision object carries the aggregated risk for a request:
decision.riskScore (integer 0-100), decision.suspectScore (number), and
decision.action (the recommended action). The score aggregates the smart
signal outputs; the bands below describe how riskScore maps to risk levels:
| Score Range | Risk Level | Typical Indicators |
|---|---|---|
| 0-10 | Normal | Clean signals, known visitor, residential IP |
| 11-30 | Low | Minor inconsistencies, datacenter IP, or first visit |
| 31-60 | Medium | VPN detected, browser tampering, or unusual velocity |
| 61-80 | High | Multiple risk signals, proxy + tampering, high activity |
| 81-100 | Critical | Bot detected, Tor exit node, or severe anomalies |
The score aggregates the active smart-signal outputs — primarily IP intelligence (VPN/proxy/Tor/datacenter), the bot verdict, and browser tampering. Confirmed human interaction (mouse/keyboard) lowers the score.
Four privacy-focused browser configurations are detected:
| 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 or canvas resisted (Firefox UA required) | 1+ marker |
| Safari ITP | Cookies blocked or IndexedDB restricted (Safari UA required) | 1+ marker |
Smart Signals reach your server through the webhook payload (see Webhooks for the full shape and signature verification) and on a session read from the Server API. The examples below read fields directly off the webhook payload; the field names are the same either way.
// `payload` is the webhook delivery body (/docs/webhooks)const score = payload.decision.riskScoreconst isVPN = payload.network.vpnconst isBot = payload.bot.result === "bot"
if (isBot) { return block("Automated access")}
if (score > 60) { return requireMFA()}
if (isVPN && score > 30) { return requireCaptcha()}
return allow()// `payload` is the webhook delivery body (/docs/webhooks)function computeFraudRisk(payload: WebhookPayload): string { let risk = "low"
if (payload.decision.riskScore > 60) risk = "high" else if (payload.decision.riskScore > 30) risk = "medium"
// Escalate when multiple network signals agree if (payload.network.vpn && payload.network.proxy) risk = "high" if (payload.network.tor) risk = "high" if (payload.bot.result === "bot") risk = "high"
return risk}