Skip to main content
Each anonymity signal answers one question: is this visit masked — relayed, tunneled, spoofed, or coming from infrastructure rather than a genuine, unmasked visitor? When a signal fires, it becomes a stable slug in the webhook’s data.signals array (name + weight) and a matching boolean in data.detection_flags. Branch on name, detection_flags, and the score band in code. ShieldLabs surfaces these signals; your own code owns the decision: allow, challenge, review, or block. Risk Scoring explains how the points roll up.

Network and anonymity

These signals indicate the connection is relayed, tunneled, or coming from infrastructure rather than a genuine, unmasked visitor.

Consistency and mismatch

These signals indicate two readings of the same visit disagree, which is what spoofed or relayed visits leave behind.

Environment

These signals indicate the runtime is spoofed, stripped, or could not be fully verified.

Surfaced, not currently scored

These are detected and returned on the webhook in detection_flags, but they add no points to the Risk Score today:

Signal weights

Each anonymity signal adds to the Risk Score by a fixed weight, listed in the full weight table on Risk Scoring. Signals sum into the score and the total is capped at 100. The strongest anonymity signal (Tor, then Privacy Relay, then VPN) takes priority over the others.

Why the VPN signal catches more

ShieldLabs corroborates VPN across multiple signals, so it catches masking that a simple IP blocklist misses. A blocklist is always behind: commercial VPNs rotate through large IP pools daily, and residential proxies hide on ordinary consumer ISPs. Because the VPN signal does not depend on a list alone, a fresh exit node that no blocklist has yet seen can still surface.

Connection type

Every visit also resolves to a single connection type, the headline label for how the visit reaches you. It is surfaced as connection_type on the webhook and as ConnectionType on each History API snapshot. The per-visit connection_type on the webhook and API is one of: Direct, Mobile, VPN, Proxy, Tor, Privacy Relay, Browser VPN/Proxy, or Unknown (when the type could not be resolved). The dashboard Connection Types breakdown uses the same buckets and rolls Browser VPN/Proxy into Proxy for the chart.
The connection type is a summary. The signals array on the Risk Score is the full breakdown: one visit can carry a proxy connection type along with a datacenter and abuser flag underneath it.

A masked visit is not always abuse

A legitimate visitor can carry these signals. A corporate VPN, iCloud Private Relay, or a privacy-focused browser all raise the score without any wrongdoing.
The connection type alone is not a verdict. Take the Risk Score, the anonymity signals, and the sensitivity of the action into account together — the same masked visit can warrant no friction on a low-stakes page and a challenge at a withdrawal, so match the response to the stakes.
Because every signal is explainable, your code can treat a Privacy Relay differently from a Tor exit or a datacenter IP. All are masking, but they carry different intent, and you decide which action each one warrants.

Example

A visit on an anti-detect browser running through a proxy returns both reasons in signals:
The two signals add 60 and 10, landing at 70 in the High band.
The signal strings are display labels and can change — never branch on them. Use detection_flags to see which signals fired. The same numeric weight from two different signals is not interchangeable; read the band, the flags, and the action context together.
Because both reasons are visible, your code can require verification before a withdrawal while letting a low-stakes action through with no friction.

Next steps

Risk Scoring

How signal weights roll up into the 0-100 score and the Clean, Low, Medium, and High bands.

Patterns

The dashboard patterns that grade an identity over time, distinct from these per-request signals.