Migrate from Programmable Messaging to Verify

June 14, 2023
Written by
Reviewed by

Migrate from TPM to Verify

The Verify API is a purpose-built solution for sending One-Time Passcodes (OTP) for user verification and authentication via SMS, voice, WhatsApp, email, push and TOTP. Twilio's Programmable Messaging API provides many businesses with the foundation to build their own OTP solutions. However, maintaining an in-house OTP solution can be complex and resource intensive, especially as the messaging landscape and compliance requirements continue to shift. Many companies are migrating to Verify for the same global reliability and unparalleled delivery at scale as Twilio's programmable messaging with the added benefits of:

  • One-click Fraud Guard protection to automatically block SMS traffic pumping
  • Regulatory and compliance management, including A2P 10DLC
  • Managed sending phone number pool included, including short codes, long codes, toll free, and global alpha-sender IDs*
  • Managed worldwide delivery such as sender types and compliance on a global scale
  • Stateless API for handling token generation and checking (with an option to bring-your-own code)
  • Templatized OTP message translations in dozens of languages
  • Multi-channel support for SMS, WhatsApp, voice, email, push, and TOTP

This guide provides an introduction to the Verify API and a set of guidelines to migrate your application from Programmable Messaging to Verify.

*Pre-registration required for alpha sender IDs in certain countries. Read more.

Migration requirements for sending tokens with Verify

The migration process requires some initial one time set up and then swapping out one API call. Assuming you already have an OTP user experience, your product design can be reused. You'll also get to delete a decent amount of code, which is always satisfying.

With Verify, you don't need to buy a phone number OR store OTPs. The three steps to sending a verification code with Verify are:

  1. Create a Verify service (one time setup)
  2. Send the SMS code
  3. Check the code

With Programmable Messaging, at minimum you also need to buy a phone number(s), generate a random numeric code, and store the code in your database to associate it with the end user before sending and checking the OTP. Verify eliminates the need for these additional steps with the option to still use your phone numbers and custom codes if you choose to.

Here's an example of the Programmable Messaging code required to send an OTP:

const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require("twilio")(accountSid, authToken);

const from = "YOUR TWILIO NUMBER";
const to = "+15558675310";

// generate a 6 digit token
const token = Math.floor(Math.random() * (999999 - 100000) + 100000);
const message = `Your Example App verification code is: ${token}`;

function storeToken(to, token) {
 /*
  * Required:
  *   - Store token with the user's phone number in your database
  *   - Set token expiration
  */
}

// send OTP
client.messages.create({ body: message, from, to }).then((message) => {
 storeToken(to, token);
 console.log(message.sid);
 // prompt user for token
});

The Verify version of the same code (below) removes the need for:

  1. a from number
  2. generating a token
  3. the storeToken function
const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require("twilio")(accountSid, authToken);

const to = "+15558675310";

// send OTP
client.verify
 .services("YOUR VERIFY SERVICE SID")
 .verifications.create({ to, channel: "sms" })
 .then((verification) => {
   console.log(verification.status);
   // prompt user for token
 });

Verify Services

Verify uses Services for configuration. To send a Verify API request you will need both your Twilio Credentials and a Service SID. You can create and update a Service in two ways:

  1. With the Verify API
  2. In the Verify Console

Services can be used to edit the name (which shows up in the message template), set the code length (4-10 characters), enable settings like the "do not share warning" and more.

Bring your own custom code

We encourage you to use Verify's code generation but you could always use your own logic by providing the customCode parameter in the API call shown above. Check out the customization options and get in touch so we can enable this feature for you. If you're using custom verification codes we ask that you provide feedback that lets us know whether or not the user verified the code. This allows us to proactively monitor our global routing and stay operational.

Verification message localization

The Verify API handles localization and translation in dozens of languages from Afrikaans to Vietnamese. Learn more about how we set default languages and how to send a localized message in the documentation.

Migration requirements for checking tokens with Verify

While checking a token isn't hard, the Verify API removes the need to fetch a stored token from your storage.

In Programmable Messaging, checking a token might look like this:

const to = "+15558675310";
const token = "123456"; // acquired from UI

function fetchToken(to) {
 /*
  * Required:
  *   - Fetch the token stored with the user's phone number
  *   - Ensure the token is not expired
  */
}

// check OTP
const validToken = fetchToken(to);
if (token === validToken) {
 // successful
} else {
 // failed
}

With Verify, checking a token requires an additional API call but removes the need to store the token and fetch it:

const accountSid = process.env.TWILIO_ACCOUNT_SID;
const authToken = process.env.TWILIO_AUTH_TOKEN;
const client = require("twilio")(accountSid, authToken);

const to = "+15558675310";
const token = "123456"; // acquired from UI

// check OTP
client.verify.services("YOUR VERIFY SERVICE SID")
 .verificationChecks
 .create({to, code: token})
 .then(check => {
   if (check.status === "approved") {
     // successful
   } else {
     // failed
   }
 });

Error handling

Verify error codes are different from Programmable Messaging error codes and can be found in the documentation. Common errors include:

Strict E.164 formatted phone number

In Verify, verifications are started with E.164 format phone numbers like this: +15552317654. Programmable Messaging is more lenient with the phone number parameter, so things like spaces were allowed. Check out the Lookup API and this blog post for examples on how to format numbers in E.164.

Best practices

Use the Lookup API to convert phone numbers to E.164 format

The free Lookup formatting API call will give you two pieces of useful information:

  1. The phone number in E.164 format. Required format for ongoing verification.
  2. The country code in ISO 3166 alpha-2 format (e.g. US, CA, BR, etc.). This is necessary to build an allow list or block list of countries.

Store both the E.164 formatted phone number and the country in your database for future use.

Learn more in the Lookup documentation.

Define allowed countries

If you have a global user base, you can allow all countries. If you are only expecting traffic from a handful of countries then you can create an allow list to help mitigate toll fraud. On the flipside, you can also create a block list if there are countries you do not expect traffic from.

FAQ

Why am I getting the same code with new verification requests using Verify?

Verify tokens are valid for 10 minutes and during that period the passcode will not change. To force a new passcode, complete the verification lifecycle.

Are rate limits different in Verify?

Rate limits for Verify SMS include:

  • 5 send verification attempts within 10 minutes per unique phone number [more info].
  • 5 check verification attempts per unique phone number [more info].

Please reach out to support for more information on rate limits. Most customers find the default rate limits for Verify sufficient, but you can also protect your application with additional service rate limits.

How do I test Verify without getting rate limited?

See the blog post on How to test Twilio Verify without getting rate limited.

What is Verify's pricing?

Verifications base pricing is $0.05/checked verification. Remember that Verify includes the cost of global phone numbers and Fraud Guard. Learn more on the Verify pricing page or get in touch for volume pricing.

What other verification methods does Verify support?

Verify includes support for SMS, WhatsApp, voice, email, push, and TOTP.