Reasons
The Details array in the webhook payload contains every signal that fired for the session. Each entry has a Value (points added to the score) and a Description (the signal name).
"Details": [
{ "Value": 10, "Description": "Is datacenter" },
{ "Value": 30, "Description": "Stun is not checked" }
]
Complete signal list
IP Intelligence signals
| Description | Points | Meaning |
|---|
Is tor | +99 | Tor exit node (exclusive — blocks other IP signals) |
Is privacy relay | +15 | iCloud Private Relay (exclusive) |
Is VPN | +15 | VPN detected by 2-of-3 rule (IP API + TCP hint + STUN fail) |
Browser VPN/Proxy | +30 | Browser extension VPN/proxy (replaces datacenter/proxy/abuser/OS mismatch) |
Is proxy | +10 | IP is a proxy server |
Is datacenter | +10 | IP is from a cloud or datacenter ASN |
Is abuser | +10 | IP is in abuse blacklists |
Connectivity signals
| Description | Points | Meaning |
|---|
Stun is not checked | +30 | STUN/ICE did not complete — UDP blocked or WebRTC disabled |
Browser timezone ≠ IP-timezone | +10 | Intl timezone doesn’t match IP geolocation timezone |
OS / Device signals
| Description | Points | Meaning |
|---|
UA OS is not detected | +30 | Cannot determine OS from User-Agent |
Network OS is not detected | +30 | TCP fingerprint did not identify OS |
Fail by windows os detect | +60 | UA = Windows, TCP fingerprint = not Windows |
Fail by linux os detect | +60 | UA = Linux, TCP fingerprint = not Linux |
Fail by android os detect | +60 | UA = Android, TCP fingerprint = not Android |
Fail by IOS detect | +60 | UA = iOS, TCP fingerprint = not iOS/macOS |
Fail by Mac OS detect | +60 | UA = macOS, TCP fingerprint = not macOS/iOS |
Antidetect & automation
| Description | Points | Meaning |
|---|
Antidetect browser (...) | +60 | Localhost port scan detected antidetect/automation ports |
JavaScript disabled (...) | +90 | WebRTC API absent — headless, noscript beacon, or antidetect without WebRTC |
Special signals
| Description | Points | Meaning |
|---|
User has been banned 1H, to many requests | 999 | IP exceeded 10 req/min on REST gateway — auto-ban for 1 hour |
Debug-only lines (prefixed with [VPN debug]) may appear in Details with Value: 0 — they do not affect the score.
Using signals in your logic
You can use specific signal descriptions to customize your response:
app.post('/shieldlabs/webhook', (req, res) => {
const { Data } = req.body;
const signals = Data.Details.map(d => d.Description);
if (signals.includes('Is tor')) {
requireEmailVerification(Data.UserHID);
}
if (signals.some(s => s.startsWith('Fail by'))) {
blockUser(Data.UserHID);
}
if (signals.some(s => s.startsWith('Antidetect browser'))) {
flagForReview(Data.DeviceID);
}
res.status(200).end();
});