The suspect score summarises how suspicious a session looks. It is simple on purpose: a sum of weights you can read, explain and change.
How the score is calculated
Each signal that fires adds its weight once. The score is the sum.
tor 14
automation 9
tampering 8
high_activity 6
----------------------
suspect_score 37 → high (threshold 30)
- The score is not a percentage and has no maximum.
- Every signal that fired is listed in
triggerswith its weight and confidence, heaviest first. A signal with weight0still appears. - Weights come from your risk weights: a key's own profile if it has one, otherwise your organization's, otherwise the defaults.
Levels
The level compares the score with your threshold, which is 30 by default.
| Level | When | With the default threshold |
|---|---|---|
low | The score is below half the threshold. | 0 to 14 |
medium | The score is at least half the threshold. | 15 to 29 |
high | The score is at least the threshold. | 30 and above |
An identification that reaches high also sends the visitor.suspect webhook.
When a request is not scored
If the network lookup could not run, the request is answered but not scored: state is unavailable, and suspect_score and suspect_level are absent. Fingerly does not invent a score from half the evidence.
if (event.suspect_score === null) {
// Not scored: fall back to your own rules, or ask for a second factor.
} else if (event.suspect_level === 'high') {
// …
}
Requests whose network lookup could not run are not billed.
Confidence
Each trigger has a confidence of low, medium or high, which says how strong the evidence for that signal was. Confidence is reported, not multiplied into the weight: a high-confidence signal with weight 0 adds nothing. Use confidence when you write rules on individual triggers.
Choosing actions
| Level | A common first policy |
|---|---|
low | Allow. |
medium | Add friction a real customer can pass, such as a second factor or a CAPTCHA. |
high | Hold for review, limit what the session can do, or refuse. |