Verify 2FA Documentation

About TypingDNA

TypingDNA builds products that analyze user typing behavior to make conclusions. One application of our technology is verification of user identity for authentication purposes.

Our Verify 2FA and Authentication API solutions commonly replace traditional second factor authentication flows, enabling users to confirm their identity by typing -- without the additional UX friction introduced by more traditional methods.

About Verify 2FA

Verify is a complete 2FA service designed to reduce reliance on traditional SMS and Email 2FA methods in the user authentication process. A Verify 2FA integration allows you to offer typing verification as a second factor in flows where traditional 2FA methods would otherwise have been required.

With Verify 2FA, end-users prove their identity by typing generated texts, only deferring to Root of Trust (RoT) channels (SMS & Email) when strictly necessary.

The goal of Verify 2FA is to offer the best experience to end-users while reducing the costs typically associated with sending 2FA codes.

Try a demo

Video tutorial

Integrate Verify 2FA in under 10 minutes inside your web app. Follow along...

Initial Setup

Sign up for an account

To integrate Verify 2FA you will need to obtain credentials (Client ID & Secret) and create your first application. Sign up for a free account to get started, and sign in to the Client Dashboard for access to your Client ID & Secret.

The Sandbox environment allows you to get familiarized with the TypingDNA Verify 2FA technology. The Sandbox environment is limited to a maximum of 100 users per month.

The Production environment is designed for live applications. Production environment also benefits from our federated model, which means that if a user has already enrolled on one website application, they will not need to enroll again on other websites that use TypingDNA Verify technology.

The Production environment is only available to Pro and Enterprise clients. The Pro Production environment has no limit on the number of users and can be activated instantly by introducing a valid credit card.

Configure your account

Below are the steps required within the dashboard to configure a Verify 2FA account before beginning the integration process:

Connect providers

TypingDNA will provide the first 200 one-time passwords (OTP) in the Sandbox environment. After that, a corresponding channel provider account must be linked from within the Verify Dashboard. In both Sandbox and Production environments, these gateways will be used on your behalf to send OTP verification codes to the users via email (Sendgrid) or SMS (Twilio).

Failure to connect a channel account, after the first 200 OTP codes are sent, will result in an error message if an attempt is made to verify or enroll a user through that channel. Any traffic limitations that your gateway provider accounts are subject to, will affect the Verify 2FA flow, if reached.

1. Connect a Twilio account

In order to send SMS verification codes on your behalf, we require you to associate a Twilio account with your TypingDNA account. Click the Connect to Twilio button within the Dashboard to provide us the required credentials and test the connection.

2. Connect a Sendgrid account

To support email verification codes, a Sendgrid account must be associated with your account. Click the Connect to Sendgrid button within the Verify 2FA Dashboard to provide us the required credentials and test the connection.

Create an Application

All user enrollment and verification activity in Verify 2FA occurs within the context of an Application. To create your first application, click on the Add your first integration button from within the Dashboard.

Add Application details

Each Application requires a domain to be associated with it. This field is mandatory, and used to ensure proper and secure communication between the TypingDNA Verify 2FA window and the origin website that initiated the Verify 2FA process. Provide the domain that will be hosting the front-end snippet that renders the Verify 2FA button.

It is important to set the correct domain, as using a different domain than what is configured will result in an error.



TypingDNA Verify 2FA is designed to reduce the number of SMS/email 2FA codes required to be sent to your users, replacing them with in-browser, secure typing biometric verification when possible.

To launch the secure Verify 2FA service from within an application, you have to integrate a TypingDNA backend client, a frontend JavaScript client and an HTML snippet that renders a button or an iframe. The backend client passes the required data attributes to the frontend, linking them via HTML attributes on the button or the iframe element. When an end-user interacts with the button or when the iframe is created, these values are passed to the Verify 2FA service to validate the session.

There are three scenarios in which typing biometrics verification is not possible, and traditional SMS/email verification codes are sent.

First, when a user initially registers their typing behavior with TypingDNA through Verify 2FA, during enrollment, a verification code is sent to the registered channel (SMS or email) to establish a Root of Trust (RoT).

Second, when a user fails typing verification, the service will defer to the RoT registered during enrollment to confirm their identity.

Finally, when an end-user’s device is determined to be mobile, a code is automatically sent, as typing verification is currently not supported on mobile.

How encrypted end-user data and verification results flow between your backend, frontend and the Verify 2FA window service depends on the flow you have chosen when initializing the TypingDNAVerifyClient object in the backend. There are two available flows, which to choose depends on UX preference:

Standard mode

Through Standard mode, the flow is simplified for the end-user, as the OTP is automatically passed from Verify 2FA to your application. To implement the Standard mode, a callback function has to be included in the data attributes of the HTML button or iframe through which the TypingDNA Verify 2FA service is started (see Integrate Backend). After the user has attempted typing verification in the Verify 2FA window, if the user’s pattern is verified successfully, a verification code is returned as a parameter to the callback function. If the user fails verification, the error message is passed in the same parameter.

Show OTP mode (not available for iFrame implementations)

The Show OTP mode requires more end-user interaction, as they must copy and paste the OTP code provided by the Verify 2FA pop-up window or iframe, into an input that you’ll have to provide.

In both modes, in order to finalize the flow, call the typingDNAVerifyClient.validateOTP() method to confirm the authenticity of the verification code using TypingDNA’s validation service. This method requires both the user identifier and code as parameters (see Reference section for details). If the code is valid a success message will be returned. Otherwise, the code validation service will return a failure to validate message.

Integrate Backend & Frontend

Integrate Backend

Once an account is set up in the Dashboard, the next step is to install an official TypingDNA client in the backend and configure it according to your preferences.

This guide will use the Verify 2FA JavaScript npm module within the sample code snippets. Support for additional technologies (JavaScript, Java, PHP/Python/C#/Ruby in progress) exists and is available on Github.

Get the Verify 2FA client

The first step in the backend integration process is to retrieve the TypingDNA Verify 2FA client. The NodeJS Verify 2FA client is installable via npm:

npm install typingdna-verify-client

Initialize the TypingDNAVerifyClient

Once installed, the client is initialized, submitting account credentials generated in previous steps in the Dashboard as parameters (note: credentials differ between the sandbox and production environments):

const typingDNAVerifyClient = new TypingDNAVerifyClient({ 
          clientId: "",
          applicationId: "",
          secret: ""

Pass user data to the frontend

Once initialized, the next step is to retrieve end-user data in the backend, for encryption and linking with the frontend button or iframe created in the next step.

The getDataAttributes method is called to pass credentials and encrypted user data to the frontend snippet. Both the language and flow are optional parameters, defaulting to 'en' and 'standard' respectively. Support for additional languages is in progress.

const typingDNADataAttributes = typingDNAVerifyClient.getDataAttributes({ 
            language :  'en',
            flow : 'standard' // 'show_otp' alternatively

Integrate Frontend

With the backend configured, the next step is to retrieve the frontend script that renders Verify 2FA either in a pop-up window, via a button, or in an iframe.

Get the frontend JavaScript

Retrieve the frontend JavaScript from the following link:

<script src=""></script>

There are two ways to display Verify 2FA on the frontend:

  • In a pop-up window that is accessed via the click of a button,
  • In an iframe that is embedded into the page.


  data-typingdna-callback-fn="callbackFn"> Verify 2FA with TypingDNA


There are two UI alternatives for the iframe integration. One suitable for more spacious user interfaces, with a fixed size of 468px per 598px, and a compact one, with a fixed size of 300px per 188px, suitable for narrow user interfaces.


The class, data-typingdna-client-id, data-typingdna-application-id and data-typingdna-payload are mandatory attributes for the frontend snippet. The values for the data-typingdna-client-id, data-typingdna-application-id and data-typingdna-payload attributes are to be retrieved from the backend. They are generated from the backend through the getDataAttributes function.

To use the compact form of the iframe, add the data-typingdna-compact attribute set to “on” in the iframe tag. If you want to use the standard one, don’t add this attribute at all.

In addition to the required attributes, optional values exist for additional configuration:

typingdna-method: This attribute defines the HTTP method (POST or GET) used to communicate with Verify 2FA. With POST (default), the end-user’s data will not be visible to them from within the window or iframe.

typingdna-callback-fn: If you're using the default flow data attribute, which is 'standard', the JavaScript function will be called and will contain the one-time password (OTP) necessary for validation. In the case of an error, the error details will be returned as a parameter instead. For security reasons this function will not be called if you are accessing an http website. The site needs to be accessed from https.

The callbackFn function will be called with the following parameters:

  • success: 1 or 0, depending on whether the OTP was successfully generated or not.
  • otp: The one-time password (OTP) generated by Verify 2FA, if success is 1.
  • error: The error that occurred if success is 0.
{ payload: { success: 1, otp: '123456'} }
{ payload: { success: 0, error: 'Internal server error'} }

Note: iFrames come with additional security concerns that you should consider. The iFrame display mode should only be used for up-to-date and secure browsers. For older browsers please use the pop-up display mode. Always make sure to take the necessary precaution measures to mitigate all security threats when using iFrames.

Getting and validating the OTP

The OTP is generated during the Verify 2FA process for each enrollment and verification and is sent to the frontend in two ways, either to the JavaScript function typingdna-callback-fn or through the message event fired on the Window object by the Verify 2FA pop-up window or iFrame. If you use the callbackFn, see the description of the incoming information above. If you wish to listen to the message event, the data being sent has the following parameters:

  • action: The action that was performed. Possible values are: sendOtp if the OTP was generated, onError if an error occurred.
  • payload: The payload that was sent. The payload is a JSON object with the following parameters: success, otp, error. (see the description of each parameter above)

Note: no matter which method is used, the data is sent only to the domain associated to the Application, in order to ensure a secure communication. See the section Create an Application for more information.

Once the OTP is generated by Verify 2FA and sent to your frontend, this needs to be verified in the Verify 2FA API and validate the user. In order to do this, you can use the method validateOTP of the TypingDNA Client, as in the following example:

const { success, code, message } = typingDNAVerifyClient.validateOTP({ email }, otp);

See the section API Services - Validate an OTP for more information on the returned values.


Backend public methods

The methods available in the Verify 2FA client and their function are as follows:

getDataAttributes({ email, phoneNumber, countryCode, language }): A helper method that wraps every required data-attribute on the frontend. This is a helper method that returns all the attributes needed to open the Verify 2FA pop-up or load the Verify 2FA iframe.

validateOTP({ email, phoneNumber, countryCode }, code): This method is used in the client’s backend to validate the OTP the user has submitted. The function calls the TypingDNA code validation service and returns either a success or failure. Upon a successful code validation, the end-user is considered verified.

sendOTP({ email, phoneNumber, countryCode }): This method manually triggers the sending of a verification code from the client’s backend to the user’s email or phone. This bypasses the Verify 2FA window’s typing verification flow, and is useful for scenarios in which users cannot type to confirm their identity, such as access via a mobile device.

Language codes

By default, end-users will be served the Verify 2FA window in English. This can be changed via the ‘language’ parameter of the getDataAttributes method of the Verify 2FA backend client. Support for the additional languages below is in progress and the table will be updated as new languages become available.

Language Code
English en
Spanish In progress
Romanian In progress
Portuguese In progress
French In progress
German In progress
Italian In progress
Dutch In progress
Korean In progress
Chinese (Mandarin) In progress
Japanese In progress

Error messages

Code Status Message
104 400 Invalid request body
105 400 Invalid client id
106 400 Invalid application id
107 500 Internal server error
108 400 Request has expired
109 400 Missing user identifier
116 500 Error validating OTP
124 400 Unauthorized request
126 401 Operation not allowed
135 400 Maximum number of active users reached

Public endpoints versions

Version Changes
1.1 Uses Pbkdf2 with SHA512 as the hashing algorithm, 10000 iterations, and a key length of 32 bytes to generate the encryption key for the payload. The client secret is the password and the application id is the salt.
1.0 Uses Scrypt with a CPU cost of 16384, block size of 8, and a key length of 32 bytes to generate the encryption key for the payload. The client secret is the password and the application id is the salt.