Guides

Bot, VPN and Tor detection

Detect bots, VPNs, proxies and Tor with one identification: which fields on the event, signal groups and webhooks tell you, and how to act on them.

Every Fingerly identification doubles as a bot detection API and a VPN detection API. The same call that returns the visitor ID also reports whether the visitor looks automated and whether the connection comes through Tor, a VPN, a proxy or a hosting provider. You read the answer from your backend, on the stored event or in a webhook.

These are signals for your own policy, not verdicts. Fingerly never blocks anyone on its own, and a VPN is not evidence of fraud by itself, which is why you set what each one is worth.

Where the answer is

What you want to knowWhere to read itValues
Is the visitor a person, an automation or a crawler?visitor_kind on the eventhuman, ai_bot, automation or search_crawler
Does the connection come through an anonymising network?anonymity_network on the eventtor, vpn, proxy or hosting. Omitted for an ordinary connection.
Whose network is it?asn, asn_name and country_code on the eventThe autonomous system number, its name and the ISO country
Which signals raised the score?triggers on the eventThe signal groups that fired, heaviest first, each with weight and confidence
How suspicious is the session overall?suspect_score and suspect_levelA score, and low, medium or high

Signal groups for bots and anonymised networks

GroupKey in `triggers`Meaning
BotbotThe client is automated, or says it is a bot.
Tor exit nodetorThe connection arrives from the Tor network.
VPNvpnThe connection arrives over a VPN.
Datacenter proxydatacenter_proxyThe address belongs to a proxy or a hosting provider rather than a consumer connection.
Residential proxyresidential_proxyTraffic is relayed through someone else's home connection.
IP reputationip_reputationThe address has a recent history of abuse.

Each group has a default weight per platform, listed in the signals reference, and you can change them with risk weights. VPN and residential proxy findings can be weighed by how they were recognised or by confidence. The bot group applies to the web. Whether the visitor is a crawler or an AI agent is told by visitor_kind, not by a signal group.

Read it on your server

Node.js
const event = await fingerly.events.get(requestId)

if (event.visitor_kind === 'automation') return refuse()
if (event.anonymity_network === 'tor') return challenge()
if (event.anonymity_network === 'vpn' && event.suspect_level !== 'low') return challenge()

An event that is not recorded yet comes back as pending, and an identification that could not be scored has no score, which is not a score of 0. See server-side verification before you act on a result.

Get it pushed to you

identification.completed is sent for every identification. visitor.suspect is sent when one reaches the high level, with every signal that fired in triggers, each carrying its signal, its group, its weight and its confidence. Subscribe to it to react to automation or Tor traffic without polling. See webhooks.

What a browser or an app is told

A page or an app can read suspect_score and suspect_level by default, never the signals, and not at all if you hide them on the key. The groups and fields above are told only to your backend and the dashboard, because knowing which check tripped teaches a fraudster what to hide.

Recipes