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 to filter visitor history 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

If your use case demands highly accurate identification, we recommend identifying the visitor on demand and always using a fresh visitor ID without caching.

Depending on your use case, you can choose to cache (store) the visitor ID in the browser to:

  • Improve the responsiveness of your application.
  • Stay within the limits of your monthly allowance of API calls.

Caching visitor IDs for extended periods can significantly reduce identification accuracy. Make sure to understand caching best practices and implications before caching visitor IDs.

Cache expiration time

We strongly recommend a maximum cache expiration time of 1 hour.

The properties (e.g. browser version, extensions, screen resolution, IP address, etc) that Fingerprint collects from a browser often change over time. When these incremental changes are captured as soon as they occur, Fingerprint can identify a returning browser with industry-leading accuracy.

Using a longer expiration time leads to:

  • Lower identification accuracy. Fingerprint can miss out on the incremental changes thus increasing the risk of incorrectly identifying a returning browser as new.
  • Outdated Smart Signals information returned from the Server API.
  • Increased risk of replay attacks.

Cache location

We strongly recommend recommend using sessionStorage to cache the visitor ID.

Our data indicates sessionStorage is the best option to minimize the impact on identification accuracy compared to both localStorage and cookies.

Note: A cached visitor ID stored in sessionStorage, localStorage, and cookies will not be available if the user switches to or from Incognito mode.

Caching using Fingerprint client libraries

The easiest way to cache visitor IDs is to install the JavaScript agent using one of our open-source client libraries like React, Angular, Svelte, or Vue. All of them provide caching out of the box.

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

// Example using the generic Fingerprint SPA library
// https://dev.fingerprint.com/docs/generic-js-agent-wrapper-for-spas

const fpjsClient = new FpjsClient({
  loadOptions: {
    apiKey: 'your-public-api-key',
  },
  // Available options are:
  // SessionStorage: Recommended default option. Persists until the browser tab is closed.                 
  // LocalStorage:   Persists until the user manually clears the storage
  //                 (survives browser closing and reopening).
  // Memory:         Persists until the page reloads.
  // NoCache:        Use to disable caching completely.
  cacheLocation: CacheLocation.SessionStorage,
  // The default and recommended value is 3600s (1hr).
  // The maximum possible value is 86400s (1 day).
  cacheTimeInSeconds: 3600
})

You can also provide your own custom cache implementation to your library. Please see the documentation of your chosen library on GitHub for more details.

Custom cache

If you are using the JavaScript agent directly without one of our client libraries, you can implement your own caching. We recommend using sessionStorage, but the general principle is the same for any cache storage:

  1. Check if your cache storage contains a visitorId and its timestamp is within your cache expiration time. 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.

What's next