Skip to contentSkip to navigationSkip to topbar
On this page

Verification and two-factor authentication best practices


Verification is an essential first step in your online relationship with a user. By verifying that a new user is who they say they are, you can reduce spam and fraud on your site while ensuring the user's security.

Designing user verification involves more than just picking the right verification channel. Twilio has supported thousands of customers rolling out verification and two-factor authentication (2FA) implementations. This guide will provide recommendations for each step of the user verification process, from collecting phone numbers to account recovery.

These recommendations are written with the Twilio Verify API in mind but many will apply regardless of your verification provider.

(information)

Info

If you're ready to start building, check out one of our Verify Quickstarts, available in a variety of programming languages for a variety of verification channels.


Understand the difference between verification and authentication

understand-the-difference-between-verification-and-authentication page anchor

Verification and authentication are similar user experiences but have a few key differences in how you can design the user experience.

Verification happens when you first associate details with a customer account. This could be:

  • At sign up
  • When the user provides new contact information like an email address or phone number
  • When the user associates a new device or browser with their account

Authentication, including two-factor authentication (2FA) or multi-factor authentication (MFA) happens during ongoing customer interactions like:

The Twilio Verify API can be used to both verify and authenticate user identities and can be used for all of these customer interactions.


Plan a user registration flow

plan-a-user-registration-flow page anchor

Balance speed with security

balance-speed-with-security page anchor

Like every security solution, you want to make sure that the friction you're adding isn't going to prevent the user from achieving their goals, whether that's signing up for your service or completing a transaction.

Support multiple authentication channels

support-multiple-authentication-channels page anchor

The Twilio Verify API supports:

Each channel has different benefits. For example, SMS(link takes you to an external page) has the highest end user adoption while TOTP is more secure and works offline. You might ask if email-based 2FA is a good idea(link takes you to an external page) (better than no 2FA!).

Most companies support several verification channels and then let their users decide. For example, GitHub supports TOTP, SMS, and security keys and offers even more options for account recovery(link takes you to an external page).

Read more about tradeoffs between the different authentication channels supported by the Verify API.

Should I use the SMS channel?

should-i-use-the-sms-channel page anchor

SMS offers less security than TOTP or push authentications, but in many cases you should still leave it available as an authentication option. SMS support is built into all mobile phones and—without a separate application—tokens delivered by SMS will make it to your users. The user experience benefits of SMS still make it a popular choice for many companies. Learn more about why SMS 2FA isn't going away.(link takes you to an external page)

If the choice is between password-only authentication or password plus SMS, adding SMS is a clear winner.

Which channels are the most secure?

which-channels-are-the-most-secure page anchor

Push and Silent Device Approval authentications are the most secure channel for 2FA because they are tied to a specific device and resistant to phishing.

Push also offers the ability to deny an authentication request, which can be used to detect fraud. Push authentications are also very convenient for your users. Instead of having to open a mobile application and navigate to your website's token, push authentications present an "Approve"/"Deny" dialog within easy reach.

Silent Device Approval authentications simplify this process even further by happening silently in the background without any user involvement. Push and Silent Device Approval can be embedded directly into your application with our Verify Client Libraries (SDKs) so it doesn't require the user to download an additional app.

Suggested account verification, security, and usage flow

suggested-account-verification-security-and-usage-flow page anchor

For an example user registration flow with one time passcodes, smart retry logic, and voice channel fallback, check out this Code Exchange project(link takes you to an external page).

Let your customers pick the authentication channels they want to use

let-your-customers-pick-the-authentication-channels-they-want-to-use page anchor

Allow customers to set authentication preferences and store those preferences for subsequent logins. This is a great way to delight your users and reduce frustrations during the authentication process. For example, landline users will want a voice call instead of an SMS. You could store preferences in your user database or use a third-party service like Segment Personas(link takes you to an external page).

These channels can also be used for backup and account recovery (more on this below).


Design your user experience for verification success

design-your-user-experience-for-verification-success page anchor

Display complete contact information for initial user verification

display-complete-contact-information-for-initial-user-verification page anchor

For phone or email verification use cases (as opposed to ongoing login or two-factor authentication), display the complete identifier in the interface so the user can detect any typos during the registration process. You can also introduce an intermediate step that asks the user to confirm the phone number before you send the OTP in order to catch mistakes.

one time passcode input field with message that shows complete phone number with option to edit.

Think internationally for phone verification

think-internationally-for-phone-verification page anchor

Building international support for telephone numbers includes separating country code and phone number input fields in your form fields and storing phone numbers in the standard E.164 format.

If you're sending OTPs to countries that require pre-registration of sender IDs, you'll need to complete this application(link takes you to an external page). Learn more about international support for Alphanumeric Sender IDs(link takes you to an external page).

Learn how to build international phone number input in HTML and JavaScript(link takes you to an external page) on the Twilio Blog.

Validate phone numbers before sending one-time passwords (OTPs)

validate-phone-numbers-before-sending-one-time-passwords-otps page anchor

This topic is covered in depth in our blog post on best practices for phone number validation during new user enrollment(link takes you to an external page).

You can also use Twilio's Lookup API to build an allow list of country codes(link takes you to an external page) in order to filter sign ups to meet compliance requirements, reduce fraud, or otherwise control your onboarding pipeline.

International telephone input plugin transforming a valid number to E.164 format and detecting an invalid number.

Here are a few additional resources on building phone number inputs and validating numbers at this stage:

  1. Quick Deploy: international telephone input(link takes you to an external page) (seen above)
  2. How to Validate Phone Number Input in HTML and JavaScript(link takes you to an external page)

Take advantage of HTML attributes to improve your users' 2FA experience

take-advantage-of-html-attributes-to-improve-your-users-2fa-experience page anchor

Look no further than the humble <input> element as a place to optimize the user experience. Learn more abouthow to design your HTML attributes to support autocomplete and more in this blog post.(link takes you to an external page)

Use smart retry logic for delivering OTPs

use-smart-retry-logic-for-delivering-otps page anchor

To prevent abuse (and impatient users!) we always recommend building retry buffers into verification workflows. This helps prevent:

  • Accidentally spamming a user with repeated text messages
  • Hitting API rate limits
  • Toll fraud or unnecessary spend

We suggest limiting verifications to 1 request / 30 seconds per phone number with exponential backoff. Learn more in the blog post about best practices for managing retry logic with SMS 2FA(link takes you to an external page) or check out this Code Exchange project with an example retry logic flow(link takes you to an external page) seen below.

SMS Verification input box with title Enter the code sent to your device and subtitle resend code in 4 seconds.

Add account recovery options early

add-account-recovery-options-early page anchor

Think about what happens when a user no longer has access to an authentication channel like a forgotten password or lost phone. Register at least one additional way to authenticate a user at sign up so that you always have a backup. Common combinations include:

  • Password + email
  • Email + phone number
  • Authenticator app (TOTP) + backup codes
  • Push authentication + phone number

Then if you're supporting two-factor authentication (2FA), add a third channel. For more recommendations, check out these slides on designing customer account recovery in a 2FA world(link takes you to an external page).


Plan for verification and authentication after sign up

plan-for-verification-and-authentication-after-sign-up page anchor

Always verify each new contact method you're adding

always-verify-each-new-contact-method-youre-adding page anchor

Send a one-time password(link takes you to an external page) to a phone number or email address the first time a user provides it. This ensures that the user has control of the device or identity. For email, verifying a user's email address the first time they provide it is a best practice to reduce fraud, ensure deliverability, and maintain a good sending reputation. If the user is using your mobile application, register the device as a factor to be used for Verify Push.

Wait until the information has been verified to store it in your database. Alternatively, add a "verified" flag. This helps prevent typos or other unverified information from being connected to a user account.

If you don't care about verifying a piece of contact information, ask if you need to collect it at all.

Mask phone numbers or other PII for ongoing authentication

mask-phone-numbers-or-other-pii-for-ongoing-authentication page anchor

Once the phone number has been verified the first time, subsequent uses should mask the phone number in order to prevent leaking PII. Unlike during initial verification, there is no option to edit a phone number for ongoing authentication in the example below. We recommend exposing 3 or 4 numbers and masking the rest like +1 (5**) ***-**67 or ********567.

Input box with title Enter the code sent to your device and subtitle showing that an SMS verification was sent to a partially obscured phone number.

Incentivize two-factor authentication (2FA)

incentivize-two-factor-authentication-2fa page anchor

Offering 2FA doesn't help secure your customers if they don't opt in to the feature. Incentives can help users who feel burdened by the security investment.

Learn more about how companies are incentivizing users to enable 2FA(link takes you to an external page).


Use the Twilio Verify API for comprehensive verification support

use-the-twilio-verify-api-for-comprehensive-verification-support page anchor

The Verify API helps you quickly build trust with the users accessing your platform and focus on your business logic.

Explore customization options

explore-customization-options page anchor

Choose the right token length

choose-the-right-token-length page anchor

The API supports token lengths between 4 and 10 digits with a default of 6 digits. Longer verification codes have more combinations and are harder to guess or brute force. The API has robust rate limits that counter brute forcing attempts of any token length size. You can change the token length in the Verify Service section of the Twilio Console(link takes you to an external page).

Customize the verification message

customize-the-verification-message page anchor

The Verify API supports a standard template. The English example is:

Your <App Name> verification code is: 123456

Verify will automatically resolve the template's locale based on phone number country code or fallback to English. Using this automatic resolution is highly recommended. If you still must override locale for the verification, use the locale parameter for any of our dozens of supported languages.

You can also provide a template to support use cases like do not share warnings, origin bound SMS codes, and your own verbiage.

Bring your own one-time passcode

bring-your-own-one-time-passcode page anchor

If you already have token validation and generation logic and would like to keep those systems in place, you can do so. We have a feature where you can use your own OTP and still use our pre-screened message templates and localizations for both text and voice. Contact Twilio Sales(link takes you to an external page) and we'll help you enable this option.

Know the limits and timeouts

know-the-limits-and-timeouts page anchor

Once generated, tokens are valid for 10 minutes. We are unable to change the timeout for token validity for your application. If your users make another request within the 10 minutes, they will receive the same token.

Rate limits are in place to help prevent fraud and protect your application and Twilio's servers. For example, we limit send attempts to the same entity (phone number or email). Our built-in rate limits are sufficient for most customers, but you can also define your own rate limits. In addition, this blog post covers how to test and develop with the Verify API without getting rate limited.(link takes you to an external page)

With the 10 minute timeout, the majority of the delay you'll see during verification will be user input and not API requests.

Check out this document for more details about Twilio's REST API best practices and rate limits.

Limit SMS messages to one message segment to avoid extra cost

limit-sms-messages-to-one-message-segment-to-avoid-extra-cost page anchor

SMS messages sent with Programmable Messaging and Verify are priced per message segment.

Character limits for message segments depend on the types of characters used:

Character setCharacter limit
Contains only GSM characters160 characters
Contains Non-GSM characters (e.g. ó and ¡)70 characters

When a message doesn't fit into one segment, it's automatically broken into two or more segments and you'll be billed for all of those segments. Therefore we recommend constructing your OTP messages to fit into one segment or be aware when it's going to take more than one. Use the segment calculator(link takes you to an external page) to confirm how many segments a message will result in.

Twilio Verify and message segments

twilio-verify-and-message-segments page anchor

The default, standard messages that Verify provides currently all fit within one message segment, except in the following circumstances:

In the case of these exceptions, your specific message may still fit within one message segment, depending on parameters that affect character length like friendly_name, code_length, locale, and other customization options that you select. You can check how many message segments your message will use with the Messaging Segment Calculator tool(link takes you to an external page).

Prepare for the unexpected

prepare-for-the-unexpected page anchor

Monitor verification conversion rates

monitor-verification-conversion-rates page anchor

Monitor based on geography to detect spikes in unchecked verifications that could indicate abuse or delivery issues.

Create Twilio account usage triggers

create-twilio-account-usage-triggers page anchor

Get notified if something goes wrong or if abuse happens on your account with Twilio's usage triggers, available via the API, CLI(link takes you to an external page), or Twilio Console(link takes you to an external page).

Finally, leverage the Verify and Lookup error dictionary to handle errors appropriately in the customer application.


Still wondering about verification? We're happy to help

still-wondering-about-verification-were-happy-to-help page anchor

Now that you have all of the best practices, you can send an SMS OTP in less than 5 minutes with the Verify API(link takes you to an external page) with Twilio's Code Exchange. Learn more about the parameters supported in the API documentation or check out one of our quickstarts in the language of your choice. If you have questions about your implementation, please reach out(link takes you to an external page). We can't wait to see what you build and secure!

Need some help?

Terms of service

Copyright © 2024 Twilio Inc.