JavaScript agent

FingerprintJS Pro JavaScript API. Not supported in Node.js, requires web browser to work.

The client-side agent is a high-performance JavaScript agent that collects multiple device and browser signals and sends them to the FingerprintJS Pro API for processing and identification.

Installing the agent

There are various ways to install the agent. No matter what you choose, the API will be the same.

CDN

This is the easiest way to start. It's also known as global variable. Add the following HTML code to your pages:

<script>
  function initFingerprintJS() {
    // Initialize the agent at application startup.
    const fpPromise = FingerprintJS.load({ token: 'your-browser-token' });

    // Get the visitor identifier when you need it.
    fpPromise
      .then(fp => fp.get())
      .then(result => console.log(result.visitorId));
  }
</script>
<script
  async
  src="//cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.min.js"
  onload="initFingerprintJS()"
></script>

You can get a token at dashboard.fingerprintjs.com.

ECMAScript module

We recommend this installation method. First install the agent NPM package:

npm install @fingerprintjs/fingerprintjs-pro
yarn add @fingerprintjs/fingerprintjs-pro

Then import the package into your code:

import FingerprintJS from '@fingerprintjs/fingerprintjs-pro'

// Initialize an agent at application startup.
const fpPromise = FingerprintJS.load({ token: 'your-browser-token' })

// Get the visitor identifier when you need it.
fpPromise
  .then(fp => fp.get())
  .then(result => console.log(result.visitorId))

EcmaScript module comes with a TypeScript declaration for superior development experience. The module can be used with various module bundlers such as Webpack, Rollup.js or Browserify. If you face a TypeScript error that occurs in a FingerprintJS file, see the TypeScript support section.

UMD

It's designed for module loaders like RequireJS. Use the following JS code:

require(
  ['//cdn.jsdelivr.net/npm/@fingerprintjs/[email protected]/dist/fp.umd.min.js'],
  (FingerprintJS) => {
    // Initialize an agent.
    const fpPromise = FingerprintJS.load({ token: 'your-browser-token' })

    // Get the visitor identifier when you need it.
    fpPromise
      .then(fp => fp.get())
      .then(result => console.log(result.visitorId))
  }
)

CommonJS

It's very similar to ECMAScript module, but it's legacy. First install the agent NPM package:

npm install @fingerprintjs/fingerprintjs-pro
yarn add @fingerprintjs/fingerprintjs-pro

Then import the package in your code:

const FingerprintJS = require('@fingerprintjs/fingerprintjs-pro')

// Initialize an agent at application startup.
const fpPromise = FingerprintJS.load({ token: 'your-browser-token' })

// Get the visitor identifier when you need it.
fpPromise
  .then(fp => fp.get())
  .then(result => console.log(result.visitorId))

Agent initialization

You should create an agent when your page or application starts:

const fpPromise = FingerprintJS.load({ /* ... */ })

// fpPromise will resolve with `fp` object that you can use to call `fp.get()`

To configure the agent, pass parameters into the “load” function. The table below summarizes the parameters available. Below the table are detailed descriptions of each parameter

Parameter

Description

token

Your browser token that authenticates the agent with the API.

region

Which region to use.

endpoint

Server API URL. Should be only used with Subdomain integration.

tlsEndpoint

Custom TLS endpoint.

disableTls

Disables the extra TLS request.

storageKey

Name of key to store data in visitor browsers.

Full list of parameters:

token default: no, required: yes

Browser token to authenticate the agent with the server API. You can get one at dashboard.fingerprintjs.com.

Example usage:

const fpPromise = FingerprintJS.load({ token: "dXk12f271339d9ag93d" })

regiondefault: 'us', required: false

Available values: us and eu

The region of the FingerprintJS Pro servers you want to send data to. The default is us, which sends data to our global API endpoint. This parameter is ignored when endpoint and tlsEndpoint parameters are used.

Example:

const fpPromise = FingerprintJS.load({ region: "us" })

endpointdefault: no, required: false

This parameter should only be used with the Subdomain integration. Specify your custom endpoint here.

tlsEndpointdefault: no, required: false, since: v3.1.0

Your custom TLS endpoint URL address.

disableTlsdefault: no, required: false, since: v3.4.0

Set it to true to disable the extra TLS request. This is not recommended as it will negatively affect your identification accuracy.

storageKeydefault: '_vid', required: false

Name of key to store data in visitor browsers. The data is stored in cookies and local storage. You shouldn't change this parameter once your code runs in production because a change will cause the data in visitor browsers to be purged which will decrease identification accuracy.

Visitor identification

Once an agent instance is initialized, you can start getting visitor identifiers. You are free to identify at any moment of time. You can configure FingerprintJS Pro to receive the identification data in the browser, on the server (via a webhook), or both.

Go to the extendedResult section to see the browser result format. The visitorId field will contain an empty string when the visitor can't be identified, for example when it's a search bot.

Below are a few examples of different approaches for identifying.

Automatic mode

In many cases you will use the automatic mode, because it's the simplest way to get started. The agent will get the data on every page load. You don't need to do anything else. Just add the call fp.get() as soon as the agent is loaded:

const fpPromise = FingerprintJS.load({ /* ... */ })
const fp = await fpPromise
const result = await fp.get()
console.log(result.visitorId)

You can use both async/await and promises to get a visitor identifier. Example of using promises:

const fpPromise = FingerprintJS.load({ /* ... */ })
fpPromise
    .then(fp => fp.get())
    .then(result => console.log(result.visitorId))

When get() is called, a FingerprintJS server will send a webhook request to your server.

Manual mode

Manual mode provides more granular control over how the identification requests are made. When you actually need to get visitor data (on a sign up event for example), call the .get() method to get the data.

const fpPromise = FingerprintJS.load({ /* ... */ })

document.querySelector('#signup-button').addEventListener('click', async () => {
    const fp = await fpPromise
    const result = await fp.get()
    console.log(result.visitorId)
})
const fpPromise = FingerprintJS.load({ /* ... */ })

document.querySelector('#ad').addEventListener('click', () => {
  fpPromise
    .then(fp => fp.get())
    .then(result => console.log(result.visitorId))
})

Search bots

The PRO API recognizes most well-known search bots (Google, Bing, Yahoo, Baidu, DuckDuckGo, and others) and treats them differently. Whenever a page is loaded by a search bot, an identification event is processed server-side, like it would with a normal visitor. The visitorId field will contain an empty string, and the bot.safe value will be true (available when an extended result is requested). Note that the search bot identification requests are not billed by us.
Search bot detection example:

const result = await fp.get({ extendedResult: true })
if (!result.visitorId && result.bot && result.bot.safe) {
  console.log('This is a search bot')
}

Parameters reference

tag

tag is a customer-provided value or an object that will be saved together with the identification event and will be returned back to you in a webhook message or when you search for the visit in the server API. You may want to use the tag value to be able to associate a visit event with information from your current visitor's web request context or add any other information that is convenient for you.

Note that the tag field is optional.

What values can be used as a tag?
Any value that you need when processing a webhook event or that is useful when searching for visits in our server API. Scalar, string or object values can be sent.
For example you can pass a yourCustomId as a tag and then get this yourCustomId back in the webhook, associated with a visitorId.

Examples of using the tag option:

// simple, scalar values
const yourCustomId = 2718281828
fp.get({ tag: yourCustomId })
// or a string value
const requestType = "signup"

// Example of sending and receiving the tag value
fp.get({ tag: yourCustomId })
// Webhook request
{
  "visitorId": "nTxJ28Gt4CegeAwdWELL",
  "tag": { "tag": 2718281828 },
  // ...
}
// Note that tags are always objects, even when you use
// a regular scalar value. 
// If you provide a scalar value, it will be converted to an object
// with `tag` attribute.
// You can also use a JavaScript object as a tag value 
// and it will be returned back to you in a webhook.
// 
// NOTE: nested objects are not supported in tag objects.
const requestMetadata = {
  yourCustomId: 2718281828, 
  requestType: "signup"
}
// Making an API call and receiving a response via a webhook request
fp.get({ tag: requestMetadata })
// Webhook request
{
  "visitorId": "nTxJ28Gt4CegeAwdWELL", 
  "tag": { "yourCustomId": 2718281828, "requestType": "signup" },
  // ...
}
linkedId

linkedId is a way of linking current identification event with a custom identifier. This will allow you to filter visit information when using the Server API

Some examples of how you can use the linkedId:

  1. Link your website userId with a FingerprintJS visitorId to be able to analyze this data.
  2. Link your e-commerce orderId with a FingerprintJS visitorId to be able to see the orders a visitor made.
  3. Link a survey ID with a visitorId to ensure that the same visitor does not participate in a single survey multiple times.
  4. Limit one visitor per item or one visitor per discount coupon.
// Making an API call
// Sending a linkedId value is helpful to filter by this value via server API
var orderId = 3936532456
fp.get({ linkedId: orderId })
// linkedId will be saved with this event and will be available to be queried later.

A linkedId looks similar to tag. When should you use each?
A tag is an object that is "passed-through" and sent back to your webhook endpoint. A tag can contain an arbitrary number of attributes of any type (except for nested objects). You can use tags to store them in your database and use for any purpose. Tag objects are meant to be consumed and processed by you eventually. You can think of a tag object as metadata.
A linkedId is a scalar, string identifier that gets indexed by FingerprintJS platform and can be used to filter visits efficiently. It's a way to create a custom index on your data and use that index to efficiently filter visits when querying them through the Server API. Objects or non-string values are not supported.

ipResolution

ipResolution is an option that controls the geolocation accuracy. This option is only for backwards compatibility and is ignored.

extendedResult

Two types of responses are supported: "default" and "extended". You don't need to pass any parameters to get the "default" response. "Extended" is an extended result format and can be requested using the extendedResult: true parameter.

Response object format is provided below. Every request has a unique requestId that is returned in the response and is also available in API to query later. It is a convenient way to get specific identification events in the Server API.

fp.get()...
// response:
{
  // requestId is different for every request
  // it's a request identifier
  "requestId": "8nbmT18x79m54PQ0GvPq",
  // visitorId is the main browser identifier
  "visitorId": "2JGu1Z4d2J4IqiyzO3i4",
  // if true, this visitor was found and visited before
  // if false, this visitor wasn't found and probably didn't visit before
  "visitorFound": true,
  // A number between 0 and 1 that tells how much the agent is sure about
  // the visitor identifier. The higher the number, the higher the chance
  // of the visitor identifier to be true.
  "confidence": { "score": 0.995 }
}
fp.get({ extendedResult: true })...
// response:
{
  "requestId": "8nbmT18x79m54PQ0GvPq",
  "visitorId": "2JGu1Z4d2J4IqiyzO3i4",
  "visitorFound": true,
  "confidence": { "score": 0.995 },
  "ip": "185.230.125.20",
  "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",
  "bot": { probability: 1, safe: true },
  "incognito": false
}
timeout

Controls client-side timeout. Client timeout controls total time (both client-side and server-side) that any identification event is allowed to run. It doesn't include time when the page is in background (not visible) because browser may suspend identification process in background. By default it's 10 seconds. You can control the client-side timeout using timeout configuration key. The timeout option is in milliseconds. Example usage:

// A timeout of 20 seconds
// An example of the client-side timeout handling
try {
  const result = await fp.get({ timeout: 20000 })
  // ...
} catch (error) {
  if (error.message === FingerprintJS.ERROR_CLIENT_TIMEOUT) {
    console.log("A timeout of 20 seconds exceeded")
  }
}

Error handling

JavaScript agent get method returns a promise which will be rejected in case of an error. Below table summarizes possible types of errors that can lead to result promise rejections. See detailed information about the errors below the table.

Error

Short description

FingerprintJS.ERROR_NETWORK_CONNECTION

FingerprintJS server connection error

FingerprintJS.ERROR_NETWORK_ABORT

FingerprintJS server request is aborted

FingerprintJS.ERROR_TOKEN_MISSING

Token is missing

FingerprintJS.ERROR_TOKEN_INVALID

Token is invalid

FingerprintJS.ERROR_TOKEN_EXPIRED

Token expired

FingerprintJS.ERROR_BAD_REQUEST_FORMAT

Bad FingerprintJS server request data. Can be caused by wrong TLS endpoint.

FingerprintJS.ERROR_BAD_RESPONSE_FORMAT

Bad FingerprintJS server response data. Can be caused by wrong endpoint.

FingerprintJS.ERROR_GENERAL_SERVER_FAILURE

General request server side failure

FingerprintJS.ERROR_CLIENT_TIMEOUT

Client side timeout

FingerprintJS.ERROR_SERVER_TIMEOUT

Server request times out

FingerprintJS.ERROR_RATE_LIMIT

Identification rate limit is exceeded

FingerprintJS.ERROR_FORBIDDEN_ORIGIN

Identification request is blocked due to forbidden origin (see request filtering)

FingerprintJS.ERROR_FORBIDDEN_HEADER

Identification request is blocked due to forbidden HTTP header (see request filtering)

FingerprintJS.ERROR_WRONG_REGION

The region set in the agent options doesn't match the region that was used to create your subscription

FingerprintJS.ERROR_SUBSCRIPTION_NOT_ACTIVE

Your subscription hasn't been activated in the dashboard or you've reached your free plan limit

With the exception of ERROR_CLIENT_TIMEOUT, ERROR_NETWORK_CONNECTION and ERROR_NETWORK_ABORT, all the errors described above will include the requestId field. The get method can also throw other unexpected errors, they should be treated as agent bugs.

Error handling example:

const fpPromise = FingerprintJS.load({ /* ... */ })

try {
  const fp = await fpPromise
  const result = await fp.get()
} catch (error) {
  switch (error.message) {
    case FingerprintJS.ERROR_GENERAL_SERVER_FAILURE:
      console.log('Unknown server error. Request id:', error.requestId)
      break
    case FingerprintJS.ERROR_CLIENT_TIMEOUT:
      console.log('Identification time limit of 10 seconds is exceeded')
      break
    default:
      console.log('Other error')
  }
}
const fpPromise = FingerprintJS.load({ /* ... */ })

fpPromise
  .then(fp => fp.get())
  .then(result => console.log(result.visitorId))
  .catch(error => {
    switch (error.message) {
      case FingerprintJS.ERROR_GENERAL_SERVER_FAILURE:
        console.log('Unknown server error. Request id:', error.requestId)
        break
      case FingerprintJS.ERROR_CLIENT_TIMEOUT:
        console.log('Identification time limit of 10 seconds is exceeded')
        break
      default:
        console.log('Other error')
    }
  })

The connection error occurs when the agent fails to connect to the server API. This can happen during a network outage or if a browser plugin blocks networking requests (e.g. AdBlock).

Timeouts

Two types of timeouts are possible: a server timeout and a client timeout.

Server timeout

The server timeout is fixed at 10 seconds of server-side processing time. If server-side processing exceeds 10 seconds for any reason, the promise will be rejected.

Client timeout

Client timeout controls total time (both client-side and server-side) that any identification event is allowed to run. By default it's 10 seconds. Note that even if the client-side timeout is exceeded, the server-side request can still be running, its results will just be discarded.

Rate limiting

Every subscription token has a rate limit. It means that you cannot make more requests per second than your rate limit allows. Free subscription tokens have a limit of 3 requests/second (with 1 request/s being the default). You cannot increase that rate limit, unless you upgrade to a paid plan.
Paid subscriptions have a limit of 5 requests/second, which you can increase by emailing [email protected]. Whenever that rate limit is exceeded, a request is throttled and a special error is returned instead of the visitorId value.

Supported browsers

The JS agent supports all popular browsers. See more details and learn how to run the agent in old browsers in the browser support guide.

TypeScript support

JS agent officially supports TypeScript version 4.0, but may work with newer and older versions of TypeScript. If you face a TypeScript error that occurs in a .d.ts file provided by FingerprintJS (example 1, example 2), consider any of these solutions:

  • Update the TypeScript package in your project to version 4.0 or newer
    npm i [email protected]^4.0
    # or
    yarn add [email protected]^4.0
    
  • Prevent TypeScript from using the library types. To do it, replace
    import ... from '@fingerprintjs/fingerprintjs-pro'
    
    with
    import ... from '@fingerprintjs/fingerprintjs-pro/dist/fp.esm.min'
    
    in your .ts files, and add the following line to a .d.ts file (if there is no such file, create one anywhere with any name):
    declare module '@fingerprintjs/fingerprintjs-pro/dist/fp.esm.min'
    

Updated 7 days ago



JavaScript agent


FingerprintJS Pro JavaScript API. Not supported in Node.js, requires web browser to work.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.