Authentication API Documentation


What is TypingDNA?

With TypingDNA you can recognize users by the way they type on their keyboards (we support both desktop & mobile). Our typing biometrics engine, exposed by a RESTful API, analyzes typing patterns and accurately determines if they are a match with a known, enrolled user.

Our solution is deployed in scenarios in which the identity of a user needs confirmation -- such as enforcing password resets, complimenting primary authentication means with an additional layer of security, or in the place of OTP flows. The API is not constrained to specific use-cases or authentication stacks, and can be incorporated anywhere within your architecture that end-users are typing.

Where to start?

Sign up for a free Starter account to obtain an apiKey and apiSecret, and then follow along with this getting started tutorial. Demos and sources are available on GitHub. A machine friendly description of Authentication API is also available as a Swagger file.

Get started - it's FREE

How does it work?

A successful TypingDNA implementation is conceptually a three step process. First, one of our recorders is included in the front-end of an application to collect typing patterns from end-users.

Collected typing patterns are submitted to our API for enrollment or analysis, along with a User ID. Patterns submitted to the /auto endpoint will be intelligently handled as enrollment or verification attempts depending on the context of the request (whether previous enrollments exist, and if there are sufficient), see below for details.

Finally, the Authentication API will return a verification or enrollment JSON response depending on the action performed. In the case of a verification (there were previous saved patterns for comparison), the API will return an actionable result to your application, along with score and additional data for the /verify endpoint.


In order to match typing patterns (step 3), you start by capturing the typing pattern of a user. Implement the TypingDNA JavaScript recorder in your front-end web app.

RESTful Authentication API

Send the recorded typing pattern to our API via RESTful request to store or match against a previously recorded pattern. Then, our API will output a JSON response containing the result of authentication.

All requests to our API should be done from your application backend.

Same text

Uses identical enrollment and verification texts: In this case, user authentication via typing biometrics, only works with a text identical to the enrollment text.

- An average email + password contains 30 chars (for login purpose)
- An average username + password contains 15+ chars (for login purpose)
- An average email contains 15+ chars (for password recovery purpose)
- An average credit card + name contains 30+ chars (for payment purpose)

A good example is "" (for enrollment) and "" (for verification).
A bad example: (enrollment) and (verification).

Please note that for best accuracy we recommend texts that have around 30 characters. Shorter or longer texts will produce more false positives/false negatives. The algorithms work for texts from 4 chars to over 100 chars. Additionally you can use this fixed text algorithm for any length text, including sentences of 50-60 chars or even more. The only requirement is that the typed text/string on which you get the pattern from javascript to be identical (even if errors occur while typing but they are corrected by the user in the process).

Any text

Authenticate a user based on different text than previously used for enrollment.

A good example would be "this is a great experience..." (for enrollment) and "how could we improve..." (for verification).
A bad example: "I agree to do..." (enrollment) and "I agree to do..." (verification).

Capture user's typing

TypingDNA class

Use TypingDNA JavaScript recorder class to capture user's typing patterns. The TypingDNA class is open source, available under Apache Licence (Version 2.0), the source code is public and can be downloaded from the GitHub repository.

Usage and description

First you need to import the typingdna.js file in the page that wants to record a typing pattern. You will need to record typing patterns when a user first creates his account and again whenever you want to authenticate that user on your platform. You can host the .js file yourself.

Alternative locations from where you can include the last class: (or minified) (or minified)

Once you create an instance of the TypingDNA class, the user typing starts being recorded (as a history of key stroke events). Whenever you want to get the user's typing pattern you have to invoke .getTypingPattern method described in detail below.

Returns: Returns the instance of the TypingDNA class (singleton)

var tdna  = new TypingDNA();
Here are the methods of TypingDNA class:

- getTypingPattern(optionsObject) ⇒ string
- addTarget()
- removeTarget()
- start() - called by default
- stop()
- reset()
- getQuality(typingPattern) ⇒ number


TypingDNA.getTypingPattern (optionsObject)

This is the main function that outputs the user's typing pattern as a String

Returns: A typing pattern in String form.

optionsObject: An object of the following form {type:Number, text:String, textId:Number, length: Number, targetId:String}. Detail table below.

Param Type Description
type Number

0 for anytext pattern (when you compare random typed texts of usually 120-180 chars long)
1 for sametext pattern (recommended in most cases, for emails, passwords, phone numbers, credit cards, short texts)
2 for extended pattern (most versatile, can replace both anytext and sametext patterns. Best accuracy, recommended in cases where text is not a secret, as it records the typed characters as well)

text String

(Only for type 1 and type 2) a typed string that you want the typing pattern for

textId Number

(Optional, only for type 1 and type 2) a personalized id for the typed text, or, if it’s against a same text, the id of the text to be typed. textId identifies the text in a unique way. To generate a textId, you can use the method TypingDNA.getTextId(str), which generates a 32-bit FNV-1a hash on the text.

length Number

(Optional) the length of the text in the history for which you want the typing pattern, for type 0 is usually 140 or more

targetId String

(Optional) specifies if pattern is obtain only from text typed in a certain target

caseSensitive String

(Optional, default: false) Used if you pass a text for type 1 or type 2


//anytext pattern
var typingPattern = tdna.getTypingPattern({type:0, length:160});
//sametext pattern
var typingPattern = tdna.getTypingPattern({type:1, text:"Hello5g21?*"});
//extended pattern
var typingPattern = tdna.getTypingPattern({type:2, text:""});


(Optional) Adds a target to the targetIds array. It has to be a text input or text area or any other HTML DOM element that has the .value property. You can add multiple targets (such as username and password fields). If you omit adding targets the typing patterns will be recorded for the entire typing session.




Remove a target from the targetIds array.


Resets the history stack of recorded typing events.


Automatically called at initialization. It starts the recording of typing events. You only have to call .start() to resume recording after a .stop()


Ends the recording of further typing events.


Checks the quality of a general typing pattern (type 0), how well it is revelated, how useful the information will be for matching applications.

Returns: Number - A real number between 0 and 1. Values over 0.3 are acceptable, however a value over 0.7 shows good pattern strength.

Param Type Description
typingPattern String

The type 0 pattern string returned by the getTypingPattern() function.


var patternQuality = tdna.getQuality(typingPattern);

API guidelines


Auto-Enroll allows typing patterns submitted for verification to be saved, improving our understanding of the user’s typing behavior over time.

By enabling Auto-Enroll, typing patterns submitted to the /verify endpoint will be enrolled if they meet minimum criteria determined by the following settings and logic.

Triggered by a Verify call, if the score returned is greater than or equal to the Score Threshold for Auto-Enroll AND the user’s previously enrolled patterns is greater than or equal to the Minimum Initial Enrollments value, the pattern is verified and enrolled. If the score is less than the Score Threshold for Auto-Enroll, it will only be verified.

If the user’s enrolled typing patterns count is below the Minimum Initial Enrollments threshold and the Force Initial Enrollments setting is disabled, no enrollment is performed, requiring a separate call to /save prior to submitting verification requests. If the Force Initial Enrollments setting is enabled, submitted patterns will be automatically enrolled, without verification, until the Minimum Initial Enrollments value is reached.

TypingDNA Postman collection

Postman is a tool that lets you build and test HTTP requests on your device. After you install Postman, clicking on the button below will automatically import TypingDNA collection into your Postman account.

Alternative: import from link

Rules to create texts

To have the best accuracy one should be aware of how text statistics are used in typing biometrics. Below is a list of rules that you should follow.

Q: What makes a typing pattern more accurate?

  1. Focus on lower case letters only. More natural typing happens on lower case letters (compared to numbers and symbols).
  2. SameText solution: tweet-long texts of ca. 30 characters (e.g. 4 words or username + password have this length) help to increase accuracy.
  3. AnyText solution: many different and rare characters. When you have a complex text (15-25 different chars), with a good percentage of usage per character, the accuracy increases, try to use chars that are found on the lower row of the keyboard (z,x,c,v,b,n,m) as often as possible, or any rare keys (q,x,z) as these seem to hide higher differences in typing.
  4. AnyText solution: longer texts. Longer texts help ensure more accurate statistics about the pressed keys, helping to increase accuracy. For enrollment we recommend recording 160-200 chars of text, but for matching afterwards you can have as few as 90 chars (120-140 is recommended).

Q: What can decrease accuracy? (and increase false positives & false negatives)

  1. Very short texts. With very short texts you typically increase the false rejection rate/false negatives, however since there are fewer chars being recorded it may also lead to a slightly higher false acceptance rate (false positives). We recommend using longer texts whenever possible, and to use a lower quality threshold for verification when you use shorter texts (but keep in mind that this will increase false positives a bit).

    Note that you only use typing biometrics authentication as a second factor. Since you don’t really need an optimized false positive rate, you can still use short texts and a lower quality threshold.

  2. Record characters from wrong inputs. When you have more inputs on your page (e.g. username, password and a short phrase to be typed) and you want to collect the typing patterns separately, indicate the target input from which you want our Recorder to gather the pattern from. See documentation on our JavaScript recorder.
  3. SameText solution: different enroll and verify text.When the user types a certain text during enrollment, but the verify text differs with more than 10% of characters, then the accuracy will decrease due to lack of proper matching. An identical text will yield the highest accuracy possible, but keep in mind that forcing the user to type identically can slightly affect user experience.
  4. AnyText solution: similar enroll and verify text. If the texts recorded for enrollment and verification are similar (a lot of similar or identical words), users may type in similar ways and be harder to distinguish. People have a natural tendency to type more similarly when letters come in the same order.

    Note that you CAN use identical enroll texts for all users, and identical verify texts for all users, but you should never have a similar sentence in both categories (even if you use multiple enroll texts and multiple verify texts). IF YOU’RE HAVING TROUBLE DECIDING ON TEXTS TO USE PLEASE CONTACT US.

  5. AnyText solution: too many identical chars. Avoid using texts with an average of less than 15 different chars, even if the whole text is longer than usual. Since we capture fewer different chars you’ll get less accuracy in matching that will result in more false positives and more false negatives.

Q: So what do you recommend to use as texts?

  1. Example for an LMS (learning management system). Some good examples would be texts that get the user permission/agreement to be recorded, or the fact that he had read and understood the terms, or even answers to particular exam questions.
  2. Example for bank transactions. You can ask the user to type his username, hometown, name, transaction details, or other details that are written with letters (not numbers). You can even ask the user to type the transaction amount in letters, or anything creative that can help you check that the desired action (eg. bank transfer) was indeed intended by the actual owner of the account.
  3. Other. Sometimes the user has details that you can verify (eg. email, name, password), that are also required to perform a desired step. You can always ask for more details and record the user typing in the background, until you are sure about the user’s identity. For example, an app that posts a text in the name of a user can simply use that text to perform the verification, or even enrollment.
  4. Numbers only. we recommend working with numbers (such as credit card numbers) on the SameText solution (identical enroll and verify). This solution works on mobile devices as well (e.g. typing on a numpad keyboard)

The quality param

You can choose between different algorithm designs via the quality parameter, according to your objective. Changing the quality parameter can result in a different Score of the Verify call in order to optimize for a different purpose.

Quality = 1 (optimize for UX) is aimed at improving the user experience by reducing the False Rejection Rate. Users will be more likely to to pass on the first try even if they type a bit differently. This algorithm design comes at the expense of an increased False Acceptance Rate.

Quality = 2 (optimize for Balance) is aimed at providing the highest accuracy (i.e. the lowest Equal Error Rate). This works well for most cases, and will attempt to minimize both the False Acceptance and False Rejection rate. This algorithm design can add delays (of up to 5 seconds) for some Verify calls.

Quality = 3 (optimize for Security) is aimed at improving security by reducing the False Acceptance Rate. For this algorithm design to work well, you should consider using longer texts. This algorithm design comes at the expense of an increased False Rejection Rate.

Please note that the word “quality” is used with the sense of “design”, and does not reflect the objective performance of the algorithm.

This parameter can be passed in /verify and /match calls or configured in the API Settings available in the User Dashboard.

Mobile Positions

The typing patterns registered on mobile devices are categorised based on the position in which the user is typing.

Examples of major typing positions:

  • typing while holding the phone in your hand in portrait orientation (90% of cases)
  • typing while holding the phone on a surface (i.e.: desk) in portrait orientation (~5% of cases)
  • typing in landscape orientation (less then 1% of cases)

  • Mobile typing patterns are compared only to other patterns coming from the same user for the same typing position. Two patterns belonging to the same user which were registered on different typing positions will not be compared during verification, as they differ greatly. Consider how a user types with one finger and how the user will type with two thumbs. The speed and the rhythm will differ so much, that the two patterns cannot be matched against.

    Visual illustrations on possible mobile typing positions:

    Position ID Description Visual illustration
    1 typing with the thumb while holding the phone in the same hand
    2 typing with one hand while holding the phone in the other hand
    3 typing with both hands while holding the phone in both hands
    4 typing with one hand while holding the phone on a surface
    5 typing with both hands while holding the phone on a surface
    6 typing in landscape orientation

    Mobile devices

    Q: What about mobile devices?

    TypingDNA’s recorders are supported on mobile devices, with score reliability depending on the context in which the typing is performed. Mobile experiences are categorized as either mobile browser or native, and are only compared with patterns from the same device type. A user’s desktop enrollments will never be matched with mobile patterns for verification purposes.

    Native: TypingDNA offers SDK’s for both Android and iOS platforms for app developers looking to capture characteristic typing behavior from end-users natively. The SDK’s require the end-user to grant the relevant platform permissions for sensor access on installation.

    Mobile browser: The standard Javascript SDK is capable of distinguishing between mobile and desktop devices in a mobile browser context. The recorder will attempt to leverage telemetry and sensor data only if the necessary browser permissions are given (usually not with modern phones). Sensor data is a very important component in authenticating a mobile user, and contains pattern data that contributes significantly to the accuracy of TypingDNA’s pattern matching algorithms. For precaution, if used for 2FA, it’s advised that mobile browsers use a different method or a much lower threshold with a quick fallback to another 2FA (e.g. Email/SMS OTP)

    Tablets: The mobile technology was developed with data from mobile phones, and it is not intended to be used on tablet devices (although it may work well). We recommend treating tablets separately.

    Q: How to use API for both desktop and mobile correctly?

      For each user that visits your app do a “check user” before switching to either enroll or verify and proceed as follows:
    1. If the user is on a desktop device and a /user call returns a count above 0 you can go ahead and do a standard verify with the new user’s typing pattern that you record in that session.
    2. If the user is on a mobile device and a /user call returns a mobilecount above 0, a standard /verify call can be performed with the new user’s typing pattern that you record in that session.
    3. Note that the API will automatically know when you submit a mobile or a desktop typing pattern but if you try to perform a verify on a device that has 0 enrolled typing patterns for that user, it will return a success=0, message=“No previous typing pattern found” and no result.

    Replay attack protection

    Typing patterns provided by the same user, even for the same text, will never be identical in real life. Not allowing identical typing patterns protects you from replay attacks.

    Performing a Save call with typing patterns previously stored for the user is disabled by design. However, you can choose whether to allow identical typing patterns for Verify calls.

    In order to do this, you can directly configure the feature in the API Settings available in the User Dashboard.

    Message codes

    Any message received on the response has a corresponding message_code. We don't recommend handling responses based on the message string, but by looking at the message_code. This can be helpful in some situations, e.g. if message_code is 3, you might want to enroll the new typing position.

    message_code message
    1 Done.
    2 Duplicate typing pattern(s).
    3 No previous patterns enrolled with this typing position.
    4 No previous valid typing patterns found.
    5 Pattern was previously sent for verification.
    6 No matching quote found.
    9 Pattern not enrolled. Not enough patterns for verification.
    10 Pattern(s) enrolled. Not enough patterns for verification.
    31 Invalid parameter in request body: Syntax error.
    32 apiKey/apiSecret combination is invalid.
    33 You provided an invalid apiKey.
    34 The method received in the request is known but not supported by the target resource.
    35 Invalid parameter in request body: Syntax error.
    36 The typing pattern that you provided is invalid.
    37 You have reached your concurrent plan limit.
    38 The requested resource could not be found. This error can be due to a temporary or permanent condition.
    40 You are trying to match patterns recorded from both mobile and desktop. Matching mobile and desktop typing patterns against each other is not supported.
    41 You are trying to match diagrams that have different length or text id.
    42 You have exceeded the maximum accepted request size. Please verify your post parameters.
    43 You have exceeded the maximum accepted request number for this IP address.
    44 You are trying to match different types of patterns.
    45 Server is inactive for maintenance.
    46 The pattern you are trying to use comes from a mobile device but has no motion data, which may lead to poor results.
    47 Matching not possible at the moment.
    48 The server encountered an internal error or misconfiguration and was unable to complete your request. If the problem persists please contact us at .
    49 The server is currently unable to handle the request due to a temporary condition. If the problem persists please contact us at .
    50 New user id cannot be set since it's already used
    51 The maximum number of users has been reached on the current subscription.
    52 You have reached your account request throughput limitation.
    53 Operation not supported on current subscription.
    55 Incompatible typing patterns submitted. Only patterns for the same Device/Type/Text are supported in the same call.
    56 Too many typing patterns submitted for verification.
    57 The maximum number of verifications for the current user has been reached on the current subscription.
    Get started - it's FREE