Introducing Template Management for Verify
Published on August 22, 2024

Developers can now customize the message sent with a One-Time Password (OTP) rather than using the default Vonage template. This functionality is extensive, so in this article, we'll walk through how to implement it and how it works.

What does Template Management do?

Template management allows developers to change the OTP delivery message on SMS or Voice across any supported locale. These are known as custom templates. A new Verify request can either detect the locale to which the request is being sent or use a specified locale given in the request. Verify, then see if you have created a custom template for that locale and channel and use it if it is present. If not, it tries to use a boilerplate Vonage template, and if you are using an unsupported locale within that channel, it finally defaults to en_US.

How is it structured?

The Template Management feature is a set of 10 new API endpoints to Verify, coded according to our Vonage's HAL standards.

There are two important entities in custom templates. Because templates have the potential to grow very large (think: one template being used for 15 locales across all three channels means 45 separate combinations), the custom template is split into two logical parts:

* The template which has a unique name and contains a GUID and whether it is the default template for that channel and locale (they are always set to default when being created and can be changed later)

* template_fragments, which are all entities with a many-to-one relationship with a template. The fragments attached to the template are unique combinations of locale and channel, which have their own GUID, the text contents of the template, and timestamps.

When creating fragments, a couple of static variables are available to use within the message text. The only important thing to note here is that the message must contain the code which is represented in the text by ${code}. There are other reserved static variables, here are all of them:

  • ${code} - the code for the end user to enter

  • ${brand} - the brand parameter used in the request

  • ${time-limit} - integer representing the expiry time

  • ${time-limit-unit} - string representing the unit of time

User Journey Example: 2 templates for SMS

Let's go through the happy path to show a custom template being used for two locales en-gb and fr_fr for SMS delivery. Currently, signing up to Vonage's API Platform and sending a test request via. SMS will give you the following message, assuming you sent the brand as "ACME":

ACME code: 5244. Valid for 3 minutes

OK, let's change that. First, we need to create the template using the following request:

POST https://api.nexmo.com/v2/verify/templates

{

	"name": "acme-template"

}

You will get an HTTP 201 to inform you that it has been created:

HTTP 201

{

   "template_id": "8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9",

   "name": "acme-template",

   "is_default": true,

   "_links": {

      "self": {

         "href": "https://api.nexmo.com/v2/verify/templates/8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9"

      },

      "fragments": {

         "href": "https://api.nexmo.com/v2/verify/templates/8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9/template_fragments"

      }

   }

}

We now need to create two fragments for our two locales. This is done with the following two requests:

POST https://api.nexmo.com/v2/verify/templates/8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9/template_fragments

{
   "channel": "sms",
   "locale": "en-gb",
   "text": "Thank you for continuing to use ${brand}! Your OTP is: ${code}"
}

POST https://api.nexmo.com/v2/verify/templates/8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9/template_fragments

{

   "channel": "sms",
   "locale": "fr-fr",
   "text": "Merci de continuer à utiliser ${brand}! Votre OTP est: ${code}"

}

Both should give 201 responses. Our customization is complete, so there are four methods in total to trigger these two messages:

Auto locale to UK Number.

This example new Verify request will result in the custom en_GB message:

POST

https://api.nexmo.com/v2/verify

{

   "channel_timeout": 180,

   "client_ref": "my-personal-reference",

   "brand": "ACME",

   "template_id": "4ed3027d-8762-44a0-aa3f-c393717413a4",

   "workflow": [

      {

         "channel": "sms",

         "to": "447700900000"

      }

   ]

}

The reason the en-gb template is picked up automatically here is because Verify has detected the to number contains a UK number, so it maps to the template. You can, however, specify the locale to use instead, so a use case might be that you are sending to a Canadian number (where the official languages are both English and French) but want to make sure that English is used:

Given locale to Canadian Number.

POST

https://api.nexmo.com/v2/verify

{

   "locale": "en-gb"

   "channel_timeout": 180,

   "client_ref": "my-personal-reference",

   "brand": "ACME",

   "template_id": "4ed3027d-8762-44a0-aa3f-c393717413a4",

   "workflow": [

      {

         "channel": "sms",

         "to": "17700900000"

      }

   ]

}

These two situations can also be used with our French language translation.

Auto locale to French Number.

POST

https://api.nexmo.com/v2/verify

{

   "channel_timeout": 180,

   "client_ref": "my-personal-reference",

   "brand": "ACME",

   "template_id": "4ed3027d-8762-44a0-aa3f-c393717413a4",

   "workflow": [

      {

         "channel": "sms",

         "to": "847700900000"

      }

   ]

}

Très Bon! Finally, you can send it to a Vietnamese number, but specify you want the French template:

Given locale to Vietnamese Number

POST

https://api.nexmo.com/v2/verify

{

   "locale": "fr-fr"

   "channel_timeout": 180,

   "client_ref": "my-personal-reference",

   "brand": "ACME",

   "template_id": "4ed3027d-8762-44a0-aa3f-c393717413a4",

   "workflow": [

      {

         "channel": "sms",

         "to": "847700900000"

      }

   ]

}

How do locales work?

Deciding what locale gets sent out is essentially a "net". As you have quite a few options, this decision tree looks like this:

Diagram showing how Verify works out which locale to useVerify locale logic

It is important to note that while it might appear quite complex, there is no "error" at the end of the process. If all else fails, you get a default Vonage template in English with a code. End users might not be able to understand the whole text, but they're very likely to recognize a code after a colon.

Common Pitfalls

Here are some common errors you might encounter when trying to use custom templates:

  • The account is not enabled

While reading templates are available to all users, writing custom templates needs to be enabled on your account. Please contact your account manager or talk to support to enable the feature.

  • Template or fragment exists

Each template must have a unique name, and each fragment on that template must be a combined unique entry for a locale and channel.

  • Attempting to delete template with fragments

You cannot delete a template if it has existing fragments. You can use the HAL fields for discovery in the get template response to traverse the IDs of existing fragments to delete before deleting the template itself.

  • Not using ${code} in the text

When creating a fragment, you must include the code within the text. If you don't deliver the code to your end user, you don't have a two-factor authentication system - so the API will not let you do this.

  • Max number of templates

There is a cap of 10 templates per user, and an attempt to generate more will result in an error.

Conclusion

While custom templates are a relatively large addition to Verify, we're not done yet: more features to watch are coming soon! In the meantime, you can contact us on our community Slack if you have questions or feedback on Verify.

James SecondeSenior PHP Developer Advocate

A trained actor with a dissertation on standup comedy, I came into PHP development via. the meetup scene. You can find me speaking and writing on tech, or playing/buying odd records from my vinyl collection.

Ready to start building?

Experience seamless connectivity, real-time messaging, and crystal-clear voice and video calls-all at your fingertips.