> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fingerprint.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Smart Signals reference

> Fingerprint is not just an identity platform; it also helps fight fraud by providing actionable device intelligence called Smart Signals. This page contains the reference information for individual Smart Signal components and their applications.

Smart Signals are actionable device intelligence insights you can use to improve your fraud prevention logic. For general information about Smart Signals availability and usage, see [Smart Signals Introduction](/docs/v3/smart-signals-introduction).

Some signals are available on [all platforms](#smart-signals-common-for-browsers-and-mobile-devices), while others are specific only to [browsers](#browser-smart-signals) or [mobile devices](#smart-signals-for-mobile-devices).

## Smart Signals common for browsers and mobile devices

These Smart Signals are available on all platforms.

### Suspect Score

Suspect Score combines all Smart Signals into a weighted integer value based on their global probability. To read more about the weights and the mechanisms, see [Suspect score](/docs/v3/suspect-score).

```json Suspect Score theme={"theme":"github-dark-dimmed"}
"suspectScore": {
  "data": {
    "result": 0
  }
}
```

### Velocity Signals

Velocity Signals are a set of signals that help you detect and prevent fraud by analyzing the velocity of the device.

Velocity Signals sum [key data points](https://fingerprint.com/blog/product-update-velocity-signals/) at three distinct intervals: 5 minutes, 1 hour, and 24 hours as follows:

[`Per visitorID`](https://fingerprint.com/blog/product-update-velocity-signals/#per-visitorid):

* Number of distinct IP addresses linked to the `visitorID`
* Number of distinct countries associated with a `visitorID`
* Number of distinct `linkedIDs` associated with the `visitorID`
* Number of events linked to the `visitorID`

[`Per linkedID`](https://fingerprint.com/blog/product-update-velocity-signals/#per-linkedid):

* Number of distinct IPs associated with the `linkedID`
* Number of distinct `visitorIDs` associated with the `linkedID`

[`Per IP`](https://fingerprint.com/blog/product-update-velocity-signals/#per-ip):

* Number of events linked to an IP address

<CodeGroup>
  ```json Distinct IPs per visitorID theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "distinctIp": {
          "intervals": {
            "5m": 1,
            "1h": 1,
            "24h": 5 // For visitors exceeding 10,000 in 24 hours, we will omit 5m and 1h, returning only 24h as 10,000.
          }
        }
      }
    }
  }
  ```

  ```json Distinct countries per visitorID theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "distinctCountry": {
          "intervals": {
            "5m": 1,
            "1h": 1,
            "24h": 5 // For visitors exceeding 10,000 in 24 hours, we will omit 5m and 1h, returning only 10,000 for 24h.
          }
        }
      }
    }
  }
  ```

  ```json Distinct linkedIDs per visitorID theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "distinctLinkedId": {
          "intervals": {
            "5m": 1,
            "1h": 1,
            "24h": 2 // For visitors exceeding 10,000 in 24 hours, we will omit 5m and 1h, returning only 10,000 for 24h.
          }
        }
      }
    }
  }
  ```

  ```json Events per visitorID theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "events": {
          "intervals": {
            "5m": 3,
            "1h": 5,
            "24h": 23
          }
        }
      }
    }
  }
  ```

  ```json Distinct IPs per linkedID theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "distinctIpByLinkedId": {
          "intervals": {
            "5m": 1,
            "1h": 1,
            "24h": 7 // For visitors exceeding 10,000 in 24 hours, we will omit 5m and 1h, returning only 10,000 for 24h.
          }
        }
      }
    }
  }
  ```

  ```json Distinct visitorIDs per linkedID theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "distinctVisitorIdByLinkedId": {
          "intervals": {
            "5m": 1,
            "1h": 1,
            "24h": 1 // For visitors exceeding 10,000 in 24 hours, we will omit 5m and 1h, returning only 10,000 for 24h.
          }
        }
      }
    }
  }
  ```

  ```json Events per IPv4 theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "ipEvents": {
          "intervals": {
            "5m": 2,
            "1h": 2,
            "24h": 9
          }
        }
      }
    }
  }
  ```

  ```json No Relevant Data - example theme={"theme":"github-dark-dimmed"}
  {
    "velocity": {
      "data": {
        "distinctIpByLinkedId": {
          "intervals": { } // This will be an empty object if there is no data to present
        }
      }
    }
  }
  ```
</CodeGroup>

For high-activity visitors generating over 10,000 unique distinct values to track within a 24-hour window, we will omit the aggregation of 5-minute and 1-hour results, returning an accurate count up to 10,000 for a 24 hour period. This limit does not apply to number of events by visitor ID or events by IP.

### IP Geolocation

The geolocation field shows the estimated physical location of the client\*.

The location is composed of latitude and longitude, along with an accuracy radius ranging from 5 to 1000 km. These coordinates define the center of a circle that can be mapped. The postal code has the weakest level of confidence and this mappable area would rarely fall within a single postal code.

The `asn` and `datacenter` field can be used to group ranges of IP addresses that belong to the same owner to apply protection rules against a whole block of IP addresses. They could also indicate that the visitor connects through an intermediate server instead of connecting through an ISP directly.

\*The latitude and longitude map to the nearest public park or body of water to avoid confusion about whether the coordinates correspond to a person's residence or a business.

```json IP Geolocation theme={"theme":"github-dark-dimmed"}
"ipInfo": {
  "data": {
    "v4": {
      "address": "94.142.239.124",
      "geolocation": {
        "accuracyRadius": 20,
        "latitude": 50.05,
        "longitude": 14.4,
        "postalCode": "150 00",
        "timezone": "Europe/Prague",
        "city": {
          "name": "Prague"
        },
        "country": {
          "code": "CZ",
          "name": "Czechia"
        },
        "continent": {
          "code": "EU",
          "name": "Europe"
        },
        "subdivisions": [
          {
            "isoCode": "10",
            "name": "Prague"
          }
        ]
      },
      "asn": {
        "asn": "7922",
        "name": "COMCAST-7922",
        "network": "73.136.0.0/13"
      },
      "datacenter": {
        "result": true,
        "name": "DediPath"
      }
    },
    "v6": {
      "address": "::ffff:5e8e:ef7c",
      "geolocation": {
        "accuracyRadius": 20,
        "latitude": 50.05,
        "longitude": 14.4,
        "postalCode": "150 00",
        "timezone": "Europe/Prague",
        "city": {
          "name": "Prague"
        },
        "country": {
          "code": "CZ",
          "name": "Czechia"
        },
        "continent": {
          "code": "EU",
          "name": "Europe"
        },
        "subdivisions": [
          {
            "isoCode": "10",
            "name": "Prague"
          }
        ]
      },
      "asn": {
        "asn": "7922",
        "name": "COMCAST-7922",
        "network": "::ffff:5e8e:ef7c/110"
      },
      "datacenter": {
        "result": true,
        "name": "DediPath"
      }
    }
  }
}
```

### Proxy Detection

Detects whether the IP address is used by a **residential** or a **data center** proxy provider using a combination of internal and third-party data sources.

* Data center proxies are typically hosted in data centers and connect with HTTPS or SOCKS5 protocols
* Residential proxies route internet traffic through real user devices with legitimate ISP-issued IP addresses, making requests appear as if they originate from ordinary end-users. They are commonly used for fraudulent activity, such as account takeovers or illegal content scraping
* Proxy confidence is a field that comes with the detection result. If a proxy is **not detected**, `confidence` is `high`. If it's **detected**, can be `low`, `medium`, or `high`. Proxy IPs with high levels of recent activity will get a high confidence
* `mlScore`indicates the likelihood of proxy usage as determined by Fingerprint's ML model, expressed as a decimal between 0 and 1 with up to 3 decimal places (e.g. `0.196`). Values closer to 1 indicate a higher likelihood of proxy usage.
* `details` is an object with additional information about the detected proxy. Always contains a `proxyType` field with one of three values:
  * `residential` - traffic routed through a residential IP
  * `data_center` - traffic routed through a datacenter IP
  * `unknown` - proxy was detected by the ML model but the type could not be determine
* May also contain an optional `lastSeenAt` timestamp indicating when this IP was last observed exhibiting proxy-like behavior. The timestamp is in ISO 8601 format with hourly resolution, always in UTC. This field is not present when the proxy was detected solely by the ML model.

<CodeGroup>
  ```json Proxy not detected theme={"theme":"github-dark-dimmed"}
  "proxy": {
    "data": {
      "result": false,
      // when a proxy is not detected, confidence is high
      "confidence": "high",
      "mlScore": 0.138
    }
  }
  ```

  ```json Residential proxy detected theme={"theme":"github-dark-dimmed"}
  // will return true in case the device IP was recently used by a known residential proxy provider
  "proxy": {
    "data": {
      "result": true,
      // can also be "medium" for moderately active proxy IPs,
      // or "high" for recently active proxy IPs
      "confidence": "low",
      "mlScore": 0.821,
      "details": {
        "proxyType": "residential"
      }
    }
  }
  ```

  ```javascript Data center proxy detected theme={"theme":"github-dark-dimmed"}
  // will return true in case the device IP belongs to a known data center proxy
  "proxy": {
    "data": {
      "result": true,
      // can also be "medium" for moderately active proxy IPs,
      // or "high" for recently active proxy IPs
      "confidence": "low",
      "mlScore": 0.252,
      "details": {
        "proxyType": "data_center",
        // this field is optional and is returned when the time of last proxy activity is known
        "lastSeenAt": "2025-12-31T16:00:00Z"
      }
    }
  }
  ```

  ```javascript Proxy detected (type unknown) theme={"theme":"github-dark-dimmed"}
  "proxy": {
    "data": {
      "result": true,
      "confidence": "low",
      "mlScore": 0.196,
      "details": {
        "proxyType": "unknown"
      }
    }
  }
  ```
</CodeGroup>

### IP Blocklist Matching

The feature uses a combination of internal and 3rd-party IP databases to determine whether:

* `tor` payload : The IP address is a known Tor exit node. Do not utilize active Tor detection mechanisms.
* `ipBlocklist.details`payload : The IP address has been part of a network attack, email spam attack or if 75% or more of events from an IP are flagged as [replayed](/docs/v3/protecting-from-payload-replay-attacks) within the last 7 days.

<CodeGroup>
  ```json Blocklist theme={"theme":"github-dark-dimmed"}
  "ipBlocklist": {
    "data": {
      "result": false,
      "details": {
        "emailSpam": false,
        "attackSource": false
      }
    }
  }
  ```

  ```json Tor theme={"theme":"github-dark-dimmed"}
  "tor": {
    "data": {
      "result": false
    }
  }
  ```
</CodeGroup>

### High-Activity Device

Detects if the device is among the top 2% of devices most frequently identified by your Fingerprint application.**High-Activity Device** searches for spikes in traffic connected to a single `visitorID`. It computes the amount of visits **in the past 24 hours** for each `visitorID` **every five minutes** and reports `data.result` as `true` if the number of visits for the past 24 hours surpasses a threshold.

#### High-Activity Device Threshold

The threshold is calculated for each customer separately and is determined through **a normal traffic distribution**. If the returned `visitorID` does **more requests than 98% of other daily visitors**, the High-Activity Smart Signal returns a positive result. If the traffic doesn't pass the threshold, `data.result` returns `false` and `dailyRequests` field isn't provided.

<CodeGroup>
  ```json High Activity - Detected theme={"theme":"github-dark-dimmed"}
  "highActivity": {
    "data": {
      "result": true,
      "dailyRequests": 42
    }
  }
  ```

  ```json Normal Activity theme={"theme":"github-dark-dimmed"}
  "highActivity": {
    "data": {
      "result": false
    }
  }
  ```
</CodeGroup>

## Browser Smart Signals

The Smart Signals listed below apply only to browsers.

### Browser Bot Detection

[**Javascript agent v3.7.0+**](/docs/changelog-javascript-agent#v3-7-0)

Get information about good and bad bots, allowing you to block or filter them from your regular traffic and stop automated abuse attempts.

The `bot.result` field contains one of `notDetected`, `bad` or `good` values where

* `notDetected` means that we haven't detected a bot and the payload should belong to a regular visitor
* `good` indicates that the bot is a well-known web crawler or other search engine bot
* `bad` is an automated tool that doesn't have legitimate uses and assumes fraudulent activity

<CodeGroup>
  ```json Bad Bot - Detected theme={"theme":"github-dark-dimmed"}
  "botd": {
    "data": {
      "bot": {
        "result": "bad",
        "type": "headless"
      },
      "url": "https://example.com/",
      "ip": "193.165.141.254",
      "time": "2024-04-12T09:29:59.588Z",
      "userAgent": "Headless",
      "requestId": "1712914199539.K1EXmu"
    }
  }
  ```

  ```json Legitimate Visitor theme={"theme":"github-dark-dimmed"}
  "botd": {
    "data": {
      "bot": {
        "result": "notDetected"
      },
      "url": "https://example.com/",
      "ip": "94.142.239.124",
      "time": "2023-08-29T21:48:17.351Z",
      "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
      "requestId": "1693345697334.YKOdT5"
    }
  }
  ```
</CodeGroup>

### Browser Incognito Detection

**Incognito** flag detects whether incognito or private modes are being used by the visitor to access the customer's website.

Most browsers have an option called Incognito mode ([Chrome](https://support.google.com/chrome/answer/95464?hl=en\&co=GENIE.Platform%3DDesktop)) or Private mode ([Safari](https://support.apple.com/en-gb/guide/safari/ibrw1069/mac), [Firefox](https://support.mozilla.org/en-US/kb/private-browsing-use-firefox-without-history)) that disables some functionality and makes the general browser storage more ephemeral. Normal browser tabs save additional information like cookies and local storage content in a way that ensures that the information is available to the website even after the browser window is closed and re-opened. Incognito mode makes sure that there are no such traces once a window gets closed.

Since the most basic fingerprinting technique could be storing a cookie in the visitor's browser, the incognito mode can be used to circumvent this simple mechanism, making sure that the returning visitor is not correctly re-identified through cookies and other information stored in the browser. This might be interpreted as an attempt to pose as a completely new identity. It might also be considered to be the most basic mechanism of browser tampering.

The flag is an interesting data point in fraud scenarios, especially in use cases where applying promotional coupons, redeeming bonuses or voting should be limited to once per user.

<CodeGroup>
  ```json Incognito Mode - Detected theme={"theme":"github-dark-dimmed"}
  "incognito": {
    "data": {
      "result": true
    }
  }
  ```

  ```json Normal Mode theme={"theme":"github-dark-dimmed"}
  "incognito": {
    "data": {
      "result": false
    }
  }
  ```
</CodeGroup>

These browsers are supported:

* Safari (macOS / iOS)
* Chrome (Windows / macOS / iOS / Android / Linux)
* Samsung Browser (Android)
* Firefox (Windows / macOS / iOS / Android / Linux)
* Edge (Windows / macOS / iOS / Android)
* Brave (Windows / macOS / iOS / Android / Linux)

<Warning>
  **HTML iframes limitation**

  Incognito detection can give a false result when JavaScript agent runs in an iframe. Make sure JavaScript agent runs outside iframes to get the accurate result.
</Warning>

### VPN Detection for browsers

Fingerprint's [VPN detection](https://fingerprint.com/blog/vpn-detection-how-it-works/) is capable of detecting whether the user is in a different timezone compared to their originating IP address indicated by the `timezoneMismatch` flag. It can also provide information about whether an IP address is associated with one of the public VPN providers, indicated by the `publicVPN` flag, or anonymizing services, indicated by the `relay` flag . On top of that, we detect whether the OS of the client matches the OS of the network traffic we see, represented in the `osMismatch` flag. Fingerprint also applies a unified ML model to detect VPN usage, represented in the `mlPrediction` flag.

If any of those detection `methods` return a positive result, we return the final `result` as `true`.

<CodeGroup>
  ```json VPN Detected theme={"theme":"github-dark-dimmed"}
  "vpn": {
    "data": {
      "result": true,
      "confidence": "high",
      "mlScore": 0.895,
      "originTimezone": "Europe/Prague",
      "originCountry": "DE",
      "methods": {
        "timezoneMismatch": true,
        "publicVPN": true,
        "auxiliaryMobile": false, // Irrelevant for browsers, mobile SDKs only
        "osMismatch": true,
        "relay": true,
        "mlPrediction": true
      }
    }
  }
  ```

  ```json No VPN Detected theme={"theme":"github-dark-dimmed"}
  "vpn": {
    "data": {
      "result": false,
      "confidence": "high",
      "mlScore": 0.024,
      "originTimezone": "Europe/Prague",
      "originCountry": "DE",
      "methods": {
        "timezoneMismatch": false,
        "publicVPN": false,
        "auxiliaryMobile": false, // Irrelevant for browsers, mobile SDKs only
        "osMismatch": false,
        "relay": false,
        "mlPrediction": false
      }
    }
  }
  ```
</CodeGroup>

#### `result`

* `true` if we detect a VPN through `timezoneMismatch`, `publicVPN`, `relay`, `osMismatch`, or `mlPrediction` methods. The field can be used as a standalone flag for VPN detection. Alternatively, fields in the `methods` section (documented below) can be used in specific use-cases to improve the granularity of the detection
* `false` if none of the `methods` below returned a positive result

#### `confidence`

The confidence level indicates how certain Fingerprint is that the current request is originating from a VPN.  It is conveyed as a string with three possible values: **high**, **medium**, or **low**.

This confidence level is determined by evaluating multiple factors, such as `publicVPN`, `timezoneMismatch`, `osMismatch`, `mlPrediction`, and other relevant `methods`.

In case of `result: true`<br /><br />When `ml_prediction` is the only signal triggering detection, confidence is determined solely by the ML score using fixed thresholds: `0.6 - 0.8` = `low`, `0.8 – 0.9` = `medium`, and above `0.9` = `high`. <br /><br />When multiple signals are active, confidence reflects the strongest available signal across both the ML model and rule-based methods.

* **High confidence**: Clear, strong signals suggest the user is connected via a VPN.
* **Medium confidence**: Some signals point to possible VPN usage, including cases where a significant difference between the device's original timezone and the IP timezone is detected. The evidence is not definitive.
* **Low confidence**: Mainly due to a minor difference between the device's original timezone and the IP timezone. This could suggest scenarios other than VPN usage, such as when the network provider is registered in a different timezone or routes traffic through servers in another location.

In case of `result: false`

* **High confidence**: Strong signals suggest the user is not using a VPN.
* **Medium confidence**: Partial signals have been captured, but the evidence is not definitive.

`mlScore`

Indicates the likelihood of VPN usage as determined by Fingerprint's ML model, expressed as a decimal between 0 and 1 with up to 3 decimal places (e.g. `0.895`). Values closer to 1 indicate a higher likelihood of VPN usage.

#### `originTimezone`

This field exposes the [IANA timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) that is available through the system settings. Since the presence of a VPN does not affect the value of this field, it can be used as a true timezone of origin (physical location) of the user.

* **Example:** `originTimezone: "Europe/Prague"`

#### `originCountry`

This field returns the estimated country of origin of the user based on device location data, expressed as an ISO 3166-1 alpha-2 country code (e.g. `"DE"`). Returns `"unknown"` when the country could not be determined.

#### `methods`

More granular VPN detection methods that contribute to the final VPN detection `result`.

##### `timezoneMismatch`

* `true`
  * When the geolocated IP address of the device does not match the originTimezone from the system settings or
  * When at least 50% of requests from the same IP in the last 7 days show a mismatch between the device’s originTimezone and the IP address location
* `false` when `originTimezone` matches the location of the IP address from which we receive the traffic

The `originTimezone` includes a country-specific reference like `"Europe/Prague"`. The `timezoneMismatch` will be `true` even if a visitor in Prague uses a Berlin VPN server, despite both countries being in the same *GMT+2* UTC offset. For most use cases, `timezoneMismatch` functions well as an indicator of country mismatch between the browser and the IP address.

##### `publicVPN`

Detects whether the IP address of the event matches any publicly known VPN providers like [NordVPN](https://nordvpn.com/), [Surfshark](https://surfshark.com/), [ExpressVPN](https://www.expressvpn.com/), [ProtonVPN](https://protonvpn.com/) and others.

* `true` when our database of public VPN provider IP addresses contains the IP address of the event
* `false` if we did not find a match in our public VPN provider database

##### `osMismatch`

Compares the network signature of the request we have received through our proprietary algorithm and searches our internal database to determine whether the signature matches the OS (operating system) of the client.

* `true`
  * If the network signature of the request we receive **does not match** the signature of the OS of the client or
  * When at least 10% of requests from the same IP in the last 7 days show this mismatch
* `false`
  * if the network signature of the request we receive matches the signature of the OS of the client
  * if we fail to capture the OS information through our detection algorithm (happens in 10-15% cases)

The method is currently very accurate for **Windows** devices but might be less accurate for other OS combinations. We recommend using this flag to lower the false positive rate of the `timezoneMismatch` method.

##### `relay`

Detects whether the IP address of the event matches anonymizing services, such as iCloud Private Relay.

##### `auxiliaryMobile`

* This field is primarily set for requests from our iOS and Android native SDKs.
* For browsers, it is normally `false`, but will be `true` if at least 10% of requests from the same IP in the last 7 days meet the auxiliary mobile detection criteria.
* See the detailed description in [VPN Detection for mobile devices](/docs/v3/smart-signals-reference#vpn-detection-for-mobile-devices)

`mlPrediction`

Set to `true` when Fingerprint's ML model predicts this request is originating from a VPN, `false` otherwise.

### Browser Tamper Detection

There are very simple techniques to confuse less sophisticated fingerprinting algorithms through User Agent [spoofing](https://fingerprint.com/blog/what-is-browser-spoofing/) or by changing the output of selected signals collected from the browser, including the use of antidetect browsers.

While our `visitor_id` remains stable in those cases, tampering detection helps detect this behavior.

We do this using two complementary detection approaches:

* Statistical anomaly detection, which identifies browser signatures that are unusually rare compared to the overall population
* Antidetect browser detection, which combines heuristic (rule-based) methods with a machine learning model to identify known antidetect browsers

<CodeGroup>
  ```json Tampering Detected - Antidetect browser theme={"theme":"github-dark-dimmed"}
  "tampering": {
    "data": {
      "result": true,
      "tampering_confidence": "high",
      "tampering_ml_score": 0.9721,
      "anomalyScore": 0,
      "antiDetectBrowser": true 
    }
  }
  ```

  ```json Tampering Detected - High anomaly score theme={"theme":"github-dark-dimmed"}
  "tampering": {
    "data": {
      "result": true,
      "tampering_confidence": "medium",
      "tampering_ml_score": 0,
      "anomalyScore": 0.97, 
      "antiDetectBrowser": false 
    }
  }
  ```

  ```json Standard Browser theme={"theme":"github-dark-dimmed"}
  "tampering": {
    "data": {
      "result": false,
      "tampering_confidence": "high",
      "tampering_ml_score": 0,
      "anomalyScore": 0,
      "antiDetectBrowser": false
    }
  }
  ```
</CodeGroup>

#### `result`

* `true` if tampering is detected through an anomalous browser signature, antidetect browser detection, or other tampering-related methods
* `false` if none of the tampering checks return a positive result

The field can be used as a standalone flag for tampering detection. Alternatively, the more granular fields documented below can be used for workflows that require more context.

#### `tampering_confidence`

The confidence level indicates how certain Fingerprint is that the current request involves browser tampering. This confidence level is determined by evaluating multiple factors, such as heuristic rules, probabilistic anomaly detection, an anti detect browser ml model, and other relevant methods. It is conveyed as a string with possible values such as high, medium, or low

In case of tampering: `true`

* **High confidence**: heuristic anti detect browser signals and the ml model are triggered, or all of the methods are triggered.
* **Medium confidence**: either the ml model triggers alone, the anomaly score triggers alone with or without the heuristic anti detect browser methods trigger.
* **Low confidence**: only the heuristic anti detect methods are triggered.

In case of tampering: `false`

* **High confidence**: Strong signals suggest the user is not tampering with their request.

#### `tampering_ml_score`

The output of this model is captured as `tampering_ml_score`, a number indicating how likely an event is coming from an anti detect browser. Values close to 1 signify higher confidence and we consider anything above the threshold of 0.8 to be actionable (the result and anti\_detect\_browser fields conveniently captures that fact)

#### `anomaly_score`

The output of this model is captured as `anomaly_score`, a statistical score indicating how rare the visitor’s browser signature is compared to the overall population. Values close to `1` signify highly anomalous browsers and we consider anything above the threshold of `0.5` to be actionable (the `result` field conveniently captures that fact).

#### `anti_detect_browser`

Detects whether the request shows evidence of antidetect browser usage.

This field may be triggered by:

* heuristic detection of known antidetect browser behavior
* machine learning detection of antidetect browser patterns

Examples of antidetect browsers include tools such as AdsPower, DolphinAnty, OctoBrowser, and GoLogin.

### Virtual Machine Detection

Detects if the browser is running inside a [virtualization software](https://fingerprint.com/blog/virtual-machine-fraud-detection/) like VirtualBox by examining the browser configuration.

`mlScore`

Indicates the likelihood of a virtual machine environment as determined by Fingerprint's ML model, expressed as a decimal between 0 and 1 with up to 3 decimal places. Values closer to 1 indicate a higher likelihood that the request originates from a virtual machine environment.

<CodeGroup>
  ```json Browser Launched from a VM theme={"theme":"github-dark-dimmed"}
  "virtualMachine": {
    "data": {
      "result": true,
      "mlScore": 0.812
    }
  }
  ```

  ```json Legitimate Browser theme={"theme":"github-dark-dimmed"}
  "virtualMachine": {
    "data": {
      "result": false,
      "mlScore": 0.043
    }
  }
  ```
</CodeGroup>

### Privacy-Focused Settings

Firefox, Brave, and other privacy-focused browsers actively [fight fingerprinting](https://fingerprint.com/blog/privacy-settings-detection/) and expose user settings that have the ability to randomize and obfuscate signal output. The Privacy-Focused Settings Smart Signal detects if those settings are enabled and reports it.

<CodeGroup>
  ```json Privacy Settings - Detected theme={"theme":"github-dark-dimmed"}
  "privacySettings": {
    "data": {
      "result": true
    }
  }
  ```

  ```json No Privacy Settings theme={"theme":"github-dark-dimmed"}
  "privacySettings": {
    "data": {
      "result": false
    }
  }
  ```
</CodeGroup>

### Developer Tools Detection

Detect whether browser developer tools are manually opened in Chrome or Firefox, or whether a Chrome instance is being controlled via an active Chrome DevTools Protocol session. This enables detection of various automation frameworks and libraries.

> Note: Data required for Developer Tools detection are collected when the JavaScript agent [loads](/reference/v3/js-agent-load-function), not when the user is [identified](/reference/v3/js-agent-get-function). This can result in false negatives if the visitor opens Developer Tools only after loading the page.

<CodeGroup>
  ```json Developer Tool Detected theme={"theme":"github-dark-dimmed"}
  "developerTools": {
    "data": {
      "result": true
    }
  }
  ```

  ```json No Developer Tool Detected theme={"theme":"github-dark-dimmed"}
  "developerTools": {
    "data": {
      "result": false
    }
  }
  ```
</CodeGroup>

### Raw Device Attributes

Raw Device Attributes expose additional data points we normally collect through our JavaScript agent. This Smart Signal is only available for web browsers.

<Warning>
  **Format Stability**

  Raw Device Attributes contents can change at any time in the future (includes complete scoped field removal) and we advise against setting dependencies on concrete field names inside of the `data` field.
</Warning>

```json theme={"theme":"github-dark-dimmed"}
"rawDeviceAttributes": {
  "data": {
    "<field_name>": {
      "value": 127
    }
}
```

## Smart Signals for mobile devices

The Smart Signals listed in this section apply only to mobile devices and provide valuable intelligence about the integrity of the device and the app. Smart Signals for Android devices are now included on our [Free plan](https://fingerprint.com/pricing/), making it easier to get started. Full access to all mobile Smart Signals is included with our [Pro Plus and Enterprise plans](https://fingerprint.com/pricing/). If you are interested in one or more of these signals, then please [contact our support team](https://fingerprint.com/support/) to enable them for you.

When your app is integrated with Fingerprint (using either our native mobile SDKs or our multi-platform SDKs), you will receive these signals as part of our Server API and/or Webhooks responses.

### Android Emulator Detection

[**Android SDK v2.3.0+**](/docs/changelog-android-sdk#v2-3-0)

Prevent spam and protect against nefarious Android emulator farms by ensuring the request is coming from a physical device. To [detect emulators](https://fingerprint.com/blog/android-emulator-tamper-fraud-detection/), several additional device attributes have to be collected and this increases the time to get a `visitorId`. The latency can be anywhere between 300 and 1500ms.

```json theme={"theme":"github-dark-dimmed"}
"emulator": {
  "data": {
    "result": false
  }
}
```

### Cloned App Detection

[**Android SDK v2.3.0+**](/docs/changelog-android-sdk#v2-3-0)

Identify if a request is coming from a cloned application. Making multiple [clones of an app](https://fingerprint.com/blog/navigating-risks-user-initiated-app-cloning/) on the same device can be used to abuse promotions and get around app restrictions. (Android only)

```json theme={"theme":"github-dark-dimmed"}
"clonedApp": {
  "data": {
    "result": false
  }
}
```

### Factory Reset Detection

[**Android SDK v2.3.0+**](/docs/changelog-android-sdk#v2-3-0)<br />[**iOS SDK v2.3.0+**](/docs/changelog-ios-sdk#v2-3-0)

Resetting a **mobile device** to default factory settings has been a common technique that fraudsters use to [evade fraud detection mechanisms](https://fingerprint.com/blog/detecting-suspicious-activity-factory-reset/). When a factory reset is performed, it can

* Disguise the identity of the mobile device
* Be used to abuse promotional offers
* Prevent the mobile device from being blocked for fraudulent activity

The Factory Reset Smart Signal will indicate when the mobile device was most recently factory reset. You can use this information in your fraud detection mechanisms to flag a mobile device as suspicious.

As an example, for a mobile device that was factory reset on July 19, 2023, at 6 AM EST, the response will be:

```json theme={"theme":"github-dark-dimmed"}
"factoryReset": {
  "data": {
    // The time when the mobile device was factory reset in UTC
    "time": "2023-07-19T011:00:00Z",
    // The UTC 'time' represented as Unix epoch time
    "timestamp": 1689445704
  }
}
```

**What is the response for devices that were never factory reset?**

* For Android devices that were never factory reset, the `time` and `timestamp` fields in the response will correspond to when the device was activated.
* For iOS devices that were never factory reset, the `time` and `timestamp` fields will correspond to [epoch](https://en.wikipedia.org/wiki/Epoch_\(computing\)):
  ```json theme={"theme":"github-dark-dimmed"}
   "factoryReset": {
     "data": {
       "time": "1970-01-01T00:00:00Z",
       "timestamp": 0
   }
  }
  ```

**In what other scenarios can a timestamp correspond to epoch?**

* The **iOS device** that initiated the request is not a physical device but an iOS simulator. (Conversely, a factory reset can be detected for Android emulators).
* Your **iOS app** does not use Fingerprint Identification SDK **v2.3.0 or higher**. The ability to detect factory reset was introduced only in v2.3.0.
* Your **Android app** uses an incompatible version of Fingerprint Identification SDK
  * **\v2.3.0:** The ability to detect factory reset was introduced only in v2.3.0.
  * **v2.3.0 ≥ SDK \< 2.3.4:** Due to *lazy* signal collection, more than one request must be initiated from the same device for a factory reset to be detected. If you would like to use one of these versions in your app, you first need to [contact our support team](https://fingerprint.com/support/) to enable factory reset detection for your account. (Since the first request from a fraudulent device is the most critical request to detect fraud, we made improvements in v2.3.4 that allowed us to detect a factory reset during the first request itself.)
  * **≥v2.10.0:** The factory reset detection algorithm has been improved for Android devices to reduce false positives and better distinguish real resets from routine system updates, Google system changes, or vendor-specific behavior.

### Frida Detection

[**Android SDK v2.3.3+**](/docs/changelog-android-sdk#v2-3-3)<br />[**iOS SDK v2.2.0+**](/docs/changelog-ios-sdk#v2-2-0)

In simple terms, [app hooking](https://en.wikipedia.org/wiki/Hooking) is a process where the behavior of a mobile app is changed by intercepting the app at runtime. [Frida](https://frida.re/) is a dynamic instrumentation toolkit that tech-savvy fraudsters can use to spoof an app at runtime and change its behavior. With this Smart Signal, you will know if [Frida](https://fingerprint.com/blog/exploring-frida-dynamic-instrumentation-tool-kit/) is being used to dynamically instrument the app.

```json theme={"theme":"github-dark-dimmed"}
"frida": {
  "data": {
    "result": false
  }
}
```

### Geolocation Spoofing Detection

[**Android SDK v2.3.4+**](/docs/changelog-android-sdk#v2-3-4)<br />[**iOS SDK v2.3.1+**](/docs/changelog-ios-sdk#v2-3-1)

Fraudsters spoof the location of their mobile devices to fool fraud detection systems. With this Smart Signal, you will know if the location of the mobile device has been spoofed or not. For iOS only, this signal requires the host app to be granted [Location Permission](https://developer.apple.com/documentation/corelocation/requesting_authorization_to_use_location_services).

```json theme={"theme":"github-dark-dimmed"}
"locationSpoofing": {
  "data": {
    "result": false
  }
}
```

### Jailbroken Device Detection

[**iOS SDK v2.2.0+**](/docs/changelog-ios-sdk#v2-2-0)

An iPhone or an iPad is labeled *jailbroken* when unauthorized modifications are made to the underlying operating system (iOS). Jailbreaking weakens a device’s built-in security features and makes it easy to steal sensitive information stored on the device. See [Unauthorized modification of iOS](https://support.apple.com/guide/iphone/unauthorized-modification-of-ios-iph9385bb26a/ios) for more information.

Fraudsters employ [phishing](https://en.wikipedia.org/wiki/Phishing) mechanisms to trick users into installing *jailbreak* software on their devices and then take control of their devices. Your app (e.g. banking, e-commerce, etc) will not be able to distinguish the transactions made using [jailbroken devices](https://fingerprint.com/blog/prevent-mobile-fraud-jailbroken-device-detection/) from those made using genuine devices. Honoring these fraudulent transactions will lead to financial losses (caused by chargeback expenses, account takeover, etc) and loss of trust among your customers.

The Jailbroken Smart Signal will help you detect if your app is being used from an iPhone/iPad that has been jailbroken and enable you to proactively act upon it.

```json theme={"theme":"github-dark-dimmed"}
"jailbroken": {
  "data": {
    "result": false
  }
}
```

### MitM Attack Detection

[**Android SDK v2.8.0+**](/docs/changelog-android-sdk#v2-8-0)<br />[**iOS SDK v2.8.2+**](/docs/changelog-ios-sdk#v2-8-2)

Man-in-the-Middle (MitM) attacks occur when a fraudster intercepts the communication between two parties with the intention of

* Gaining access to sensitive information.
* Modifying the information to their advantage.
* Block the requests to/from the intended parties.

These attacks can result in service disruptions for an organization, diminishing customer trust, damaging reputation, and causing financial losses.

The MitM Attacks Smart Signal will help you detect if requests made to Fingerprint servers are intercepted and potentially modified. You can use this information to identify spoofed requests/responses and take additional precautionary steps.

```json theme={"theme":"github-dark-dimmed"}
"mitmAttack": {
  "data": {
    "result": false
  }
}
```

### Rooted Device Detection

[**Android SDK v2.3.0+**](/docs/changelog-android-sdk#v2-3-0)

Ensure a safe Android mobile app environment by detecting [rooted devices](https://fingerprint.com/blog/android-emulator-tamper-fraud-detection/).

```json theme={"theme":"github-dark-dimmed"}
"rootApps": {
  "data": {
    "result": false
  }
}
```

### Tampered Request Detection for mobile apps

[**Android SDK v2.3.0+**](/docs/changelog-android-sdk#v2-3-0)<br />[**iOS SDK v2.2.0+**](/docs/changelog-ios-sdk#v2-2-0)

Promotional offers are often exploited by creating multiple accounts. Device identification enables businesses to determine if the same mobile device was used to create multiple accounts. One technique fraudsters employ to trick device identification is to modify the request sent to our servers.

When your app requests a visitor ID for the device, Fingerprint collects several properties from the device and sends it to our servers. The properties collected from the device are used to generate the visitor ID and deduce other Smart Signals. However, if the properties within the request are modified beyond recognition, then

* A new visitor ID could be generated for an already-seen device
* All the intended Smart Signals may not be flagged.

The Tampered Request Detection Smart Signal detects anomalies in the properties received with the request. Thus, it enables you to identify tampered requests and take corresponding mitigation measures.

```json theme={"theme":"github-dark-dimmed"}
"tampering": {
  "data": {
    "result": true,
    "anomalyScore": 1, 
    "antiDetectBrowser": false
  }
}
```

#### `result`

Indicates if an identification request from an Android SDK has been tampered with.

* `true` - If the request contains anomalous device attributes that could not have been legitimately produced by Fingerprint's Android or iOS SDK (see `anomalyScore`).
* `false` - If the request is considered genuine.

#### `anomalyScore`

When the request contains anomalous device attributes, this value is 1. Otherwise, it is 0.

#### `antiDetectBrowser`

This field does not apply to requests originating from mobile SDKs. It is always false.

### VPN Detection for mobile devices

[**Android SDK v2.3.3+**](/docs/changelog-android-sdk#v2-3-3)<br />[**iOS SDK v2.3.0+**](/docs/changelog-ios-sdk#v2-3-0)

VPN apps for mobile devices are popular with both legit users and fraudsters. These VPN apps

* Protect their users’ privacy by encrypting all their traffic
* Allow their users to remain anonymous by giving them the ability to hide their real location

The VPN Detection Smart Signal for mobile devices will help you [detect](https://fingerprint.com/blog/vpn-detection-location-spoofing-fraud-prevention/) if your app is being used by a mobile device with an active VPN connection.

```json theme={"theme":"github-dark-dimmed"}
"vpn": {
  "data": {
    "result": false,
    "confidence": "high",
    "originTimezone": "Europe/Berlin",
    "originCountry": "DE" // country code string in the ISO 3166 format
    "methods": {
      "timezoneMismatch": false,
      "publicVPN": false,
      "auxiliaryMobile": true,
      "osMismatch": false, // always false, irrelevant for native SDKs
      "relay": false
    }
}
```

#### `result`

For mobile devices, `result` is `true` when any of the following methods is `true`:

* `timezoneMismatch` - `true` when the device is in a different timezone compared to the timezone of the originating IP address.
* `publicVPN` - `true` when the IP address matches one of the known IP addresses that belong to public VPN providers.
* `auxiliaryMobile` - `true` when other proprietary detection methods indicate the presence of a VPN.
* `osMismatch` - always `false` when using mobile SDKs.
* `relay`- `true` then the IP address of the event matches anonymizing services, such as iCloud Private Relay.

#### `confidence`

The confidence level indicates how certain Fingerprint is that the current request is originating from a VPN.  This confidence level is determined by evaluating multiple factors, such as `publicVPN`, `timezoneMismatch`, `auxiliaryMobile`, and other relevant methods.

Possible values: `high`, `medium`, or `low`.

#### `originTimezone`

This field indicates the [IANA timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) that is currently set for the mobile device. In situations where a VPN is enabled, this timezone can be different from the timezone associated with the IP address.

The `originTimezone` usually includes a country-specific reference like `"Europe/Prague"`. The `timezoneMismatch` will be `true` even if a mobile user in Prague uses a Berlin VPN server, despite both countries being in the same *GMT+2* UTC offset. For most use cases, `timezoneMismatch` functions well as an indicator of country mismatch between the mobile device and the IP address.

This field is supported for both Android and iOS devices.

#### `originCountry`

This field indicates the country in which the mobile device is physically located at the time of request. The country is represented in [ISO 3166](https://www.iso.org/iso-3166-country-codes.html) format. It does not require Location Permissions to be enabled for your app.

This field can be very useful in situations where an active VPN can mask the true location of the device.

**Android devices**

* This field is supported only in Android SDK [v2.4.0](https://github.com/fingerprintjs/fingerprintjs-pro-android-demo/releases/tag/v2.4.0) and higher. For lower versions of the SDK, the value is set to `unknown`.
* If the request is from an emulator, irrespective of the SDK version used, the value is set to `unknown`.

**iOS devices**

* The `originCountry`is supported only in iOS SDK [**v2.9.0**](https://docs.fingerprint.com/docs/changelog-ios-sdk#v2-9-0) and higher. For lower versions of the iOS SDK, the value is set to `unknown`.
