Find Us

Address
123 Main Street
New York, NY 10001

Hours
Monday—Friday: 9:00AM–5:00PM
Saturday & Sunday: 11:00AM–3:00PM

Categories

TypingDNA on Mobile Phones: Best Practices for Mobile Browser-based Integrations

Typing biometrics behave differently on phones than on laptops/desktops, mainly because users grip the device in many ways and mobile operating systems protect motion sensors.

This article explains how to build a reliable mobile experience for browser-based integrations.

1. Major differences between Mobile Browser and Native integrations

QuestionMobile browser (JavaScript) – RECOMMENDEDNative app (Android, iOS)
Recorder to embedtypingdna.js (same file used on desktop)TypingDNARecorder-Android (Java) and TypingDNARecorder-iOS (Swift)
Sensor permissioniOS prompts for DeviceMotionEvent.requestPermission() every visit; Android browsers allow motion by default but a user can block it.Motion and orientation are available after install; revocations are rare

Our latest recorders are linked in the API documentation with sources available on our GitHub page. Our browser recorder is your best choice as it works well in most browsers and even in WebView. Our native recorders capture typing events using an overlay approach (draw-over-apps), which may be restricted on some devices, blocking access to keyboard data.

We strongly recommend a browser-based integration, since it offers broader compatibility.

2. Posture first: lock to position 3

The API recognises six mobile typing positions (see API docs). Typing patterns collected in one position will not match those typed in another. We recommend guiding all users to Position 3—holding the phone with both hands and typing with thumbs—because it is the most common grip, produces consistent motion data, and delivers the highest match accuracy.

Recommended flow

  1. Show a short text and image asking the user to hold the phone with both hands and type with thumbs. For example, you can use the image on the right, and the text “Type normally, with both hands”.
  2. Call /verify with post param position_only=1 and pass the recorded typing pattern; the response returns "positions":[3] when the user complies. This API call will not perform an actual authentication. It will only return the most probable typing position that was detected. The array may include more than one position, but in order to continue you should only accept the typing pattern if position 3 is first (or only) value.
  3. If the first value is not 3, prompt the user to try again. After several retries, if the user consistently types in another position (e.g. position 2), you may allow it—but you must ensure they always use that position, including at verification. This adds implementation complexity. In most cases, enforcing and sticking to position 3 is simpler, more robust, and recommended.

3. Capture settings that work

SettingRecommended valueWhy
Pattern typetype: 2 (SameText). If the prompt includes sensitive user data fall back to type: 1. Never use type: 0 for mobile.Type 2 delivers the highest accuracy on mobile. It also includes prompt text.
PromptOne fixed sentence of 14–40 characters, identical for every user. Test your prompt strength here. On mobile, a lower-strength prompt (4+) can be acceptable if motion sensor data is available—unlike on desktop (which requires 8+)Accuracy improves sharply once the text is fixed and long enough.
QualityBalanced (quality=2)The mobile engine is tuned for this quality=2 specifically. You can use a different setting for desktop.
Auto-enrollAuto-enroll ON for /verify callsAdds new samples silently, improving accuracy over time.
Minimum samplesAt least 2 saved patterns before first verification. Ideally 3.Reduces cold-start verification errors.
Endpoint choiceUse /save for enrollment and /verify for auth. Avoid /auto on mobile./auto might record patterns from a wrong posture.

4. Why motion sensors matter

Accelerometer and gyroscope data add fine-grained timing cues that improve model accuracy and allow posture detection. Each keystroke produces subtle motion, helping distinguish between typing positions and and actual finger/hand movements.

  • If motion is present: The engine can identify typing position and extract enhanced timing signals. This improves accuracy, especially on shorter texts.
  • If motion is absent: Authentication still works, but posture cannot be detected and scoring accuracy may decrease. False accepts or rejects may become more likely depending on conditions.

In mobile browsers:

  • On iOS, you must call DeviceMotionEvent.requestPermission() before motion data becomes available, and you can only call it on a user gesture (which includes click on a text field – recommended), otherwise Apple will not enable motion sensor data until next browser restart. Prompt the user before typing starts and cache the response (e.g., in sessionStorage). If the user declined motion sensor data, they have to close/swipe away the app and try again. Although you could capture a typing pattern without motion data even if user declined allowing motion sensor data, this could lead to more false rejects in the future, therefore, we suggest making this mandatory for the mobile authentication process as it makes everything much easier after.
  • On Android, motion access is usually granted by default (99.9%), but can be disabled manually in browser settings (very rare). You can add a brief motion listener (for up to 5-10 seconds) which tells your app if there is motion sensor data. If no motion sensor data is recorded, we recommend you display a note for the user to activate motion sensors in the browser settings (it’s extremely rare when an Android has them turned off, and the users who do this are usually able to turn it on easily). Like with iOS, you could also capture typing patterns without motion.

Only for native apps (non-browser):

  • Motion access is typically granted silently after install. You can launch a background listener to confirm telemetry is working and notify the user if not. At launch, initiate a short-lived motion listener—about five seconds using SensorManager on Android or CMDeviceMotion on iOS.

For both browser-based and native apps, in the rare case when no motion sensor data arrives, you have 4 options:

  1. Ask the user to enable motion sensor data access in system settings.
  2. Proceed with TypingDNA authentication anyway at reduced accuracy.
  3. Proceed with TypingDNA but use a stronger/longer text prompt (desktop-like, 35-50 chars of strength 8+), at reduced accuracy (but better than option 2). Note that the same text needs to be typed at both registration and verification. If motion sensor data becomes unnavailable only at verification, you may have to re-enroll the user to be able to run this option, as you can’t use different texts for the same user.
  4. Fall back to another authentication factor until sensors are available.

Note that IF integrated correctly there should be no issues getting motion data.

5. Separate desktop and mobile logic

Desktop patterns are never compared with mobile ones. However, we propose that you separate the desktop/mobile logic if you plan to have users joining your login-based area from both environments:

A single user ID can hold both count (desktop) and mobilecount (phone) values. Always check the right counter before verifying. If you want to verify a user on mobile and their mobilecount == 0, you must first enroll that user (same applies to desktop). Since multiple mobile typing positions can be saved, a mobilecount greater than 0 doesn’t necessarily mean the user was enrolled in the same position you want to verify. That’s why we strongly recommend:

  1. Only enroll and verify position 3 mobile patterns, and/or
  2. Track position data or context on your end so you can manage consistency across sessions

If you only store position 3 patterns, the mobilecount will directly reflect the number of usable patterns, making verification simpler and more predictable.

6. TextID matters

The TypingDNA recorder on both desktop and mobile devices will capture the typing pattern for the text that was typed in a text field, however, often users may delete chars, include typos, etc. Typically 1-2 typos are allowed, but TypingDNA will only capture data that was typed (not copy pasted, not ommitted), it will statistically infer 1-2 typos (up to 7% of the length of the text), and will generate the typing pattern for exactly the phrase you have asked the user to type.

Example:

  1. Text prompt: pocket mushroom quick landlord

2. Typed text: pokket mushroom quick landlord

3. Your typing pattern function call must include the exact text prompt:

tdna.getTypingPattern({type:2, text:"pocket mushroom quick landlord"});

Why is this important?

Each text is hashed to a unique TextID, and if you change even one char the whole TextID changes. When you send a typing pattern to our API, the TextID is already included in the pattern and it will be only enrolled and verified against other patterns of the same TextID. Our suggestion is that for most use cases you should use the same text (and subsequently same TextID) for all users. This is true for both desktop and mobile integrations.

7. End-to-end checklist

  1. Pick and hard-code a 14–40 character sentence
  2. Embed the JavaScript recorder in your mobile web page
  3. Show the position 3 image and posture prompt
  4. Call /verify with post param position_only=1 until posture 3 is detected
  5. Enroll/save 2-3 initial patterns with /save
  6. Switch to /verify with Auto-enroll ON, and quality=2 (Optimized for Balanced)
  7. Separate desktop from mobile authentication flow
  8. Optionally, watch the device_similarity value to catch device switches

Wrap-up

TypingDNA works very well on mobile if you guide posture and capture motion. Use SameText with type: 2, balanced quality, and a strong, fixed phrase. Always enforce position 3 and let auto-enroll silently build a strong profile. Keep mobile and desktop logic separate, and mobile pass rates will match your desktop benchmarks with minimal effort.

If you’re interested to see a mobile demo integration please contact us and we’ll show you a working browser-based demo that works according to the suggestions in this article.

For any related questions, feel free to contact us.

Share: