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:
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.