Identify visitors

Learn best practices for timing identification requests, caching visitor information or using linked IDs to associate your own identifiers with each visitor ID.

Assuming you have your JavaScript agent installed and initialized, you can start analyzing visitors. This involves calling the agents get() function or its equivalent in your chosen SDK. This triggers an identification request that sends the collected browser signals to the Fingerprint Platform API and receives a response containing the visitor's visitor ID and other metadata.

This guide focuses on when and how to identify visitors on the web. To explore the JavaScript agent API further, see its API reference. If you are looking to identify mobile devices instead, see Android and iOS.

The most common approaches to browser identification are:

Identify on page load

This is the simplest way to get started. Call get() (or your SDK equivalent) as soon as the JavaScript agent loads. Use the result immediately or save it for later.

<script>
  // Initialize the agent on page load and analyze the visitor right away
  const fpPromise = import('https://metrics.yourwebsite.com/v3/<<browserToken>>')
    .then(FingerprintJS => FingerprintJS.load({/**...*/}))

  fpPromise
    .then(fp => fp.get())
    .then(result => console.log(result.requestId, result.visitorId))
</script>

📘

Note: The code snippets in this guide assume you have already set up some kind proxy integration for Fingerprint. Proxying requests through your own domain or subdomain like metrics.yourwebsite.com instead of connecting to Fingerprint servers directly helps avoid ad blockers and increases accuracy.

See Installing the JavaScript agent and Evading ad-blockers (proxy integrations) for more details.

Identify on demand

Your use case might only require identifying the visitor when they perform a specific action. This just-in-time approach avoids using your billable API calls unnecessarily.

For example, to prevent account takeover, you can install the agent only on your login page and get the visitor ID just before logging the user in. We recommend always using a fresh visitor ID for sensitive actions and security use cases to minimize the potential for replay attacks.

<script>
  // Initialize the agent on page load
  const fpPromise = import('https://metrics.yourwebsite.com/v3/<<browserToken>>')
    .then(FingerprintJS => FingerprintJS.load({/**...*/}))

  // Analyze the visitor if they submit a form
  document.querySelector('button[type="submit"]').addEventListener('click', async () => {
    const fp = await fpPromise
    const result = await fp.get()
    console.log(result.requestId, result.visitorId)
  })
</script>

See Optimizing the JavaScript agent to learn more about deploying Fingerprint effectively.

Response

The get() function returns a promise of a response object with the visitor ID and other metadata. You can get an extended result by using get({ extendedResult: true }).

await fp.get()
// response:
{
  "requestId": "8nbmT18x79m54PQ0GvPq",
  "visitorId": "2JGu1Z4d2J4IqiyzO3i4",
  "visitorFound": true,
  "confidence": { "score": 0.995 }
}
await fp.get({ extendedResult: true })
// response:
{
  "requestId": "8nbmT18x79m54PQ0GvPq",
  "visitorId": "2JGu1Z4d2J4IqiyzO3i4",
  "visitorFound": true,
  "confidence": { "score": 0.995 },
  "ip": "185.230.125.20",
  // ipLocation: This field is deprecated and will not return a result for applications created after January 23rd, 2024. 
  // See IP Geolocation (https://dev.fingerprint.com/docs/smart-signals-overview#ip-geolocation) for a replacement 
  // available in our Smart Signals product.
  "ipLocation": { 
    "accuracyRadius": 10,
    "latitude": 47.3925,
    "longitude": 8.4546,
    "postalCode": "8010",
    "timezone": "Europe/Zurich",
    "city": {
      "name": "Zurich"
    },
    "continent": {
      "code": "EU",
      "name": "Europe"
    },
    "country": {
      "code": "CH",
      "name": "Switzerland"
    },
    "subdivisions": [
      {
        "isoCode": "ZH",
        "name": "Zurich"
      }
    ]
  },
  "browserName": "Chrome",
  "browserVersion": "75.0.3770",
  "os": "Mac OS X",
  "osVersion": "10.14.5",
  "device": "Other",
  "incognito": false,
  "firstSeenAt": {
    "global": "2022-03-16T11:26:45.362Z",
    "subscription": "2022-03-16T11:31:01.101Z"
  },
  "lastSeenAt": {
    "global": "2022-03-16T11:28:34.023Z",
    "subscription": null
  }
}

📘

JavaScript agent response limitations

Note that the response received by the JavaScript agent is limited on purpose. Since client-side code can be tampered with, we recommend consuming Fingerprint results securely through one of our server-side integrations. The full identification event including the visitor's Smart signals is available through the Server API, Webhooks, or Sealed results.

See Protecting from client-side tampering to learn about getting Fingerprint results securely to your server.

Linking and tagging information

The visitorId provided by Fingerprint Identification is especially useful when combined with information you already know about your users, for example, account IDs, order IDs, etc. You can follow user actions, track logged-in devices, and recognize malicious behavior.

You can pass a linkedId or tag parameters to the get() function (or its equivalent in your SDK) to associate your own metadata with the visitor ID.

<script>
  const fpPromise = import('https://metrics.yourwebsite.com/v3/<<browserToken>>')
    .then(FingerprintJS => FingerprintJS.load())

  // Pass your own data to get()
  fpPromise
    .then(fp => fp.get({
      linkedId: "accountNum12345",
      tag: {
        orders: ["orderNum6789"],
      	location: { city: "Atlanta", country: "US" }
      } 
    }))
    .then(result => console.log(result.visitorId))
</script>
  • linkedId is a string you can use to filter identification events in the Dashboard or when using the Server API.
  • tag is a JavaScript object of any shape allowing you to store structured metadata. It is not indexed, you cannot use it to search for events.

For more details, see Linking and tagging information.

Caching the visitor ID

For security and fraud prevention use cases, we recommend identifying the visitor on demand and always using a fresh visitor ID without caching.

For less sensitive use cases, for example, content personalization, you might need to know the visitor ID at all times but also not need to re-identify the visitor repeatedly on every page load. To avoid unnecessary API calls, we recommend caching identification results.

Caching using Fingerprint client libraries

The easiest way to cache visitor information is to install the JavaScript agent using one of our open-source client libraries. All of them provide caching out of the box:

By default, our libraries use sessionStorage to cache results, but you can specify a different cache location:

  • sessionStorage (default) — cleared when the page session ends (closing the browser tab or window).
  • localStorage — persists even when the browser is closed and reopened, cleared manually by the user.
  • memory — cleared on page reload.
  • noCache — disable caching completely if needed.

You can also provide your own custom cache implementation to the library. By default, the cache time limit is 1 hour, and the maximum possible cache time is 24 hours. Please refer to the documentation of your chosen library on GitHub for more details.

📘

A note on Incognito mode

Values stored in sessionStorage, localStorage, and cookies are not available from Incognito mode, so these caching attempts will not work if a visitor switches from normal to private browsing (or vice versa).

Custom cache

If you are not using one of our libraries, you can implement your own caching using sessionStorage, localStorage, or client-side cookies. The general principle is always the same:

  1. Check if your cache storage contains a visitorId and its timestamp is within your cache time limit. If yes, use the visitor ID.
  2. If not, use the JavaScript agent to make an identification request to the Fingerprint API.
  3. Save the returned visitorId to your cache storage along with a timestamp.

Caching time limit

For most use cases, caching visitor IDs for 1 hour is sufficient to avoid over-utilization without affecting identification accuracy. Generally, we recommend always keeping the cache time limit shorter than 24 hours:

  • Maintains high identification accuracy.
  • Keeps the information from Smart signals up to date.
  • Reduces the risk of replay attacks — malicious actors reusing a cached ID and abusing it for the duration of the cache.

📘

Explanation: Why does over-caching lead to lower accuracy?

Browsers naturally go through incremental changes as users install updates, add extensions, plug in external monitors, or change internet connections. Fingerprint continually captures these incremental changes a few at a time and recognizes moderately updated browser configurations as the same browser using the other stable signals.

However, long delays between identification events can increase the risk that the two browser configurations are too different to safely assign them the same visitor ID. Do not cache visitor IDs for longer than 24 hours to avoid unnecessary false negatives.

What's next