Product

Smart Signals: VPN, proxy, bot, tampering and velocity on every event

Every identify is stored as an event, and each event carries signals: what the server learned about the network, the browser and the device behind the visit. You read them with your secret key, see them in the console and receive them in webhooks. They are evidence for your own rules. They do not change the allow, human check or deny answer.

What each signal catches

Browser signals apply to web visits. The emulator, attestation and device-integrity lines apply to apps built with the mobile SDKs (version 0.7.0 and later for the device checks); each is true, false or null when the check could not run, for example for lack of a permission. These checks run on the device, so a determined attacker can hide from them. We do not promise to catch every case. The mobile device checks (root or jailbreak, hooking, emulator, debugger, developer mode, traffic interception, device VPN, location spoofing and cloned app) are recorded and returned to you but not scored yet: they do not change the trust score, and they act only through rules you write.

  • IP geolocation: The country and city the visit comes from.
  • ASN: The network number and the name of the company that runs the IP.
  • Datacenter: Visits that come from a hosting or cloud network instead of a home or mobile connection.
  • Tor: Visits that leave the Tor network through an exit node.
  • iCloud Private Relay: Visits that leave through Apple’s privacy relay. A relay on its own does not count as a VPN.
  • Blocklist: IPs known to belong to malicious infrastructure. When that check is not available the answer is unknown, not clean.
  • VPN: Visits that look like they come through a VPN, with the reasons.
  • Proxy: Traffic that reaches you through a hosting network.
  • Bot: Whether the visit is a good bot, a bad bot or not detected. A bot we recognise is named with its operator and category, and one that imitates a confirmed bot is flagged. Automated and headless browsers and common automation frameworks are reported with the kind that was seen.
  • Incognito: Whether the visit comes from a private window, in Chrome and Firefox on desktop. Other browsers and apps return unknown. It does not change the trust score.
  • Tampering: Browsers whose own functions or output were altered to hide the visitor.
  • Anti-detect browser: The pattern that browsers built to mask a visitor’s identity leave behind.
  • Privacy browser: Browsers that hide their fingerprint on purpose, named when known. Not a risk by itself.
  • Virtual machine: Browsers running inside virtualization software.
  • Velocity: How many different IPs, countries and linked IDs one device used in the last 5 minutes, hour and day, and how many events it produced.
  • Emulator: App installs running on an emulator or simulator instead of a real phone (Android, iOS and macOS apps).
  • Attestation: Whether the platform vouched for the app and device, and how strongly (Android, iOS and macOS apps).
  • Root or jailbreak: Apps running on a rooted Android device or a jailbroken iPhone or iPad (Android and iOS apps).
  • Hooking frameworks: Instrumentation and hooking tools attached to the app, the kind used to change how it behaves at run time (Android, iOS and macOS apps).
  • Debugger: A debugger attached to the app (Android, iOS and macOS apps).
  • Developer mode: Developer options or USB debugging switched on (Android apps).
  • Traffic interception: Devices whose network traffic may be intercepted (Android and iOS apps).
  • Device VPN: A VPN running on the phone itself, shown as a VPN signal with the reason os_vpn (Android and iOS apps).
  • Location spoofing: A device location that software is faking, when the app already has location access (Android and iOS apps).
  • Cloned app: An app running in a clone or parallel space instead of the original install (Android apps).

Unknown is not “no”

When a check could not run, for example because there is no data for that IP or the field does not exist on that platform, the signal is null, not false. Only a check that ran and found nothing says false. Treat the two differently, and weigh signals as evidence rather than verdicts.

Where to see them

  • The events API: read one event or search by bot (good, bad or not detected, and by bot name, category or label), VPN, proxy, Tor, tampering, virtual machine, root or jailbreak, hooking, emulator, interception, location spoofing and cloned app.
  • The console: open an event to see its signals in groups, and filter the event list.
  • Webhooks: the same signals arrive with every event.
  • The browser or app never sees them. Only your backend does.

Read the signals reference →

IP data credit

IP address data powered by IPinfo.

Read the signals of an event

Signals are on every event. Events stored before signals existed have signals set to null.

// Backend. Read events with your secret key and weigh the signals yourself.
const r = await (await fetch('https://api.fpchecker.com/v1/events?linkedId=user_123', {
  headers: { 'X-Secret-Key': process.env.FPCHECKER_SECRET_KEY },
})).json();
if (!r.events) throw new Error(r.error ?? r.reason);
for (const event of r.events) {
  const s = event.signals; // null for an event stored before signals existed
  if (s?.bot.result === 'bad' || s?.ip.blocklist.result === true) flagForReview(event); // your code
}

// event.signals looks like this (null means unknown, never "no"):
// {
//   version: 1,
//   ip: { country: 'DE', city: 'Berlin', asn: 64500, datacenter: true, tor: false, ... },
//   vpn: { result: true, ... },
//   proxy: { result: true, ... },
//   bot: { result: 'bad', ... },
//   incognito: false,   // true or false in Chrome and Firefox on desktop, null elsewhere
//   tampering: { result: false, ... },
//   virtualMachine: false,
//   velocity: { distinctIp: { '5m': 1, '1h': 2, '24h': 3 }, ... },
//   mobile: null   // on a native event, for example:
//   mobile: { emulator: false, attested: true, rooted: true, hooked: false, mitm: false,
//             vpn: false, locationSpoofed: null, clonedApp: false }  // null = not checked
// }

Frequently asked questions

Do signals change the allow or deny decision?

No. Signals are shown to you so you can write your own rules. The decision API works as before.

Can a signal be wrong?

Yes. A privacy browser, for example, is not a threat in itself. That is why each signal is a separate field with its reason, not one verdict.

Do old events have signals?

Events stored before signals were introduced have signals set to null. Treat that as unknown.

Try it on your own sign-up flow

Every new account gets 2,000 free checks. No card required.