Frequently Asked Questions
To set up MessageBird OTP in Node.js, you'll need to install necessary dependencies like Express, the MessageBird SDK, Handlebars, dotenv, and body-parser. Create the project structure, set up your .env file with your MessageBird API key, and then implement the core logic within index.js and your Handlebars view templates as described in the guide. This allows for user interaction to send and verify the OTP codes via SMS through the MessageBird API and an Express server.
The MessageBird Verify API is used for generating and sending One-Time Passwords (OTPs) via SMS, commonly for Two-Factor Authentication (2FA). It allows you to securely verify a user's phone number by sending a unique code and then verifying it, enhancing your app's security by adding a second verification factor beyond a password.
MessageBird OTP requires a live API key because it involves sending real SMS messages to users' phones, which incurs costs. Test API keys don't have access to the SMS functionality needed for the Verify API. You can find your live API key in the "Developers" section, "API access" tab, within your MessageBird Dashboard. Create one if you haven't already.
Two-Factor Authentication with MessageBird is beneficial when you want to strengthen the security of your applications, especially during sensitive actions like login, account updates, or financial transactions. Adding 2FA helps protect against unauthorized access, even if a user's password is compromised.
You can send OTPs with the MessageBird API by making a POST request to /send-otp
route with the user's phone number in international format. Ensure your backend is set up with the MessageBird Node.js SDK and uses messagebird.verify.create()
with the user's number and message template containing %token
placeholder. A unique verification ID is generated and returned in the API's response which is then used to verify the entered OTP.
Prerequisites for MessageBird OTP integration include installed Node.js and npm (or yarn), a MessageBird account with a live API key, a phone number capable of receiving SMS for testing, and basic understanding of Node.js, Express.js, and asynchronous JavaScript.
The MessageBird OTP system uses a three-part architecture involving the user's browser, your Node.js/Express server, and the MessageBird Verify API. The browser interacts with the server for phone number and OTP submission, the server handles requests and interacts with the API using the SDK, and the MessageBird API generates, sends, and verifies the OTP.
Implement error handling by checking for errors returned by the messagebird.verify.create
and messagebird.verify.verify
functions. Use console.error
for logging detailed errors, then provide helpful messages to the user on the UI based on the error codes. This tutorial demonstrates handling errors for invalid numbers, API issues, and incorrect OTPs, improving user experience.
Enhance OTP security by using environment variables for API keys, implementing robust phone number and token validation, adding rate limiting to the /send-otp route (and potentially /verify-otp), always using HTTPS in production, and implementing secure session management.
To verify the OTP, the user enters the code they received via SMS. The backend takes this user-entered token along with the verification ID (generated when sending the initial request) and calls the messagebird.verify.verify(id, token, callback)
function. If successful, the callback renders a success page, and the user's phone number is marked as verified.
Yes, you can customize the MessageBird OTP message by providing a custom template with the template
parameter in messagebird.verify.create()
. The %token
placeholder within the template is replaced with the actual OTP, allowing flexibility in wording and branding.
You can test your integration by running the application locally with node index.js
and manually interacting with it in your browser. You should be able to submit your phone number, receive an OTP via SMS, and then submit the OTP for verification. Alternatively, test with curl
by sending POST requests to /send-otp
and /verify-otp
endpoints with appropriate parameters.
Check for common issues such as incorrect or test API keys, phone numbers not in E.164 format, originator restrictions, expired or invalid tokens, message delivery issues, and rate limits. Ensure your MessageBird account has a sufficient balance for sending messages. Review the troubleshooting section of the article.
Deployment considerations include managing environment variables securely, enforcing HTTPS, utilizing a process manager like PM2, configuring a production-ready logging solution, and ensuring all production dependencies are properly installed.
To integrate with user accounts, after successful verification, store a flag (e.g., isPhoneNumberVerified: true
) in your user database. Ideally, the verificationId
should also be stored in a server-side session during the process for enhanced security if tied to a logged-in user, rather than relying on hidden form fields.
MessageBird OTP/2FA Tutorial: Node.js + Express Implementation Guide
Build a secure One-Time Password (OTP) verification system for Two-Factor Authentication (2FA) using Node.js, Express, and the MessageBird Verify API. This step-by-step guide covers everything from project setup to deployment.
By the end of this tutorial, you'll have a functional web application that:
You'll add a second verification factor beyond passwords, confirming users possess their registered phone number.
Important Security Context: SMS-based OTP is more vulnerable to interception than Time-based One-Time Password (TOTP) authenticator apps (per OWASP Multifactor Authentication guidelines). For high-security applications, implement TOTP as your primary 2FA method with SMS OTP as a fallback or account recovery option.
Technologies You'll Use:
Prerequisites:
System Architecture:
The flow involves three main components:
1. Set Up Your Project
Create your project directory and install the necessary dependencies.
Create Project Directory: Open your terminal and create a new directory for the project:
Initialize Node.js Project: Initialize the project using npm (the
-y
flag accepts default settings):Install Dependencies: Install Express, MessageBird SDK, Handlebars, dotenv, and body-parser:
Optional but Recommended: For robust phone number validation, install
libphonenumber-js
:Create Project Structure: Set up your directory structure:
Your structure should look like this:
Configure Environment Variables: Never hardcode your MessageBird API key. Use
dotenv
to load it from a.env
file.Get Your MessageBird Live API Key:
Add the Key to
.env
: Open.env
and add:Replace
YOUR_LIVE_API_KEY
with your actual key.Add a Template to
.env.example
: Create an example file without exposing secrets:Add
.env
to your.gitignore
file (if using Git) to prevent committing secrets.2. Implement Core Functionality
Build the Express application logic in
index.js
and create the corresponding Handlebars views.Set Up
index.js
: Openindex.js
and add the initial setup:dotenv.config()
first? Load environment variables early before using them in the MessageBird SDK initialization.bodyParser
? Parse form data (application/x-www-form-urlencoded
) and make it available inreq.body
.express-handlebars
? Dynamically generate HTML pages with templates, separating presentation from logic.Create Main Layout (
views/layouts/main.handlebars
): Define the basic HTML structure shared by all pages:Step 1: Request Phone Number (
views/step1.handlebars
) Display the form for users to enter their phone number:{{#if error}}
: Conditionally displays an error message if theerror
variable is passed to the template.action="/send-otp"
: Form data is sent via HTTP POST to the/send-otp
route.type="tel"
: Mobile browsers display a numeric keypad.Add Route for Step 1 (GET
/
) Add this route toindex.js
before theapp.listen()
call:Step 2: Send OTP and Request Code (
views/step2.handlebars
) Ask the user to enter the OTP they received. Include a hidden field to pass the MessageBird verification ID.input type="hidden" name="id"
: Stores the verification ID from MessageBird. The server needs it to link the token back to the original request, but users don't need to see it.pattern="\d{6}"
: Basic HTML5 validation for a 6-digit number.Add Route for Sending OTP (POST
/send-otp
) Handle phone number submission, call the MessageBird API to send the OTP, and render the code entry form. Add this toindex.js
:libphonenumber-js
in production for accurate E.164 validation.messagebird.verify.create(number, params, callback)
: Core API call.number
: Recipient's phone number in E.164 format (e.g., +14155552671)params
: Configuration optionsoriginator
: Sender ID displayed on user's phone. Must be alphanumeric (max 11 chars) or verified MessageBird number. Important: Alphanumeric originators work in Europe but not in US/Canada. For North America, use a purchased MessageBird virtual number or shortcode.template
: Message text.%token
is replaced by the OTP.timeout
: Token validity in seconds. Default: 600 seconds (10 minutes), not 30 seconds. Adjust for your use case.tokenLength
: OTP length. Default: 6 digits.callback(err, response)
: Handles async responseerr
: Error occurred (invalid number, API key issue, insufficient balance). Log detailed error and show user-friendly message.response
: Request successful.response.id
is the unique identifier for this verification attempt.Step 3: Verification Result (
views/step3.handlebars
) Show success message upon correct verification:Add Route for Verifying OTP (POST
/verify-otp
) Take the verification ID and user-entered token, call MessageBird to verify them, and render success or failure. Add this toindex.js
:messagebird.verify.verify(id, token, callback)
: Key API callid
: Verification ID from thecreate
call (passed via hidden form field)token
: OTP entered by usercallback(err, response)
:err
: Token was incorrect, expired, or ID was invalid. Renderstep2
with error message, passid
back so user can retry.response
: Token correct! Render success page. In production, mark the user's phone number as verified in your database.3. Error Handling and Logging
Implement robust error handling and logging:
messagebird.verify.create
andmessagebird.verify.verify
. Log detailed errors to console (console.error
) for debugging. Display user-friendly messages on the appropriate page. Check specific error codes (21 for invalid recipient, 23 for invalid token) to provide better feedback./send-otp
.console.log
andconsole.error
. For production, use a dedicated logging library (Winston or Pino) to structure logs, write to files, and set log levels.4. Security Considerations
Protect your application and users:
API Key Security: Load API key from
.env
and never commit to version control. Ensure.env
is in.gitignore
. In production, use your platform's secure environment variable management.Input Validation: Sanitize and validate all user inputs. Use
libphonenumber-js
(lighter than Google's libphonenumber) for robust E.164 format checking. Validate token format (numeric, expected length).Rate Limiting: Protect
/send-otp
from abuse. Repeated code requests cost money and harass users. Implement rate limiting per IP or user account withexpress-rate-limit
. MessageBird limits 3 verification attempts per ID (maxAttempts: 3
), but add application-level rate limiting. Consider stricter limits on/verify-otp
to prevent token guessing attacks.Install rate limiting:
Configure rate limiting:
HTTPS: Always use HTTPS in production to encrypt client-server communication.
Session Management: For real applications with user accounts, use secure session management. Don't rely solely on hidden form fields for sensitive state like verification IDs. Store server-side in user's session.
Recovery Codes: Provide users with recovery codes (single-use backup codes) for production 2FA in case they lose phone access. Store hashed in your database.
5. Test Your Application
Verify everything works correctly:
Start the Application: Ensure
.env
has the correctMESSAGEBIRD_API_KEY
. Run from your terminal:You should see
Server listening on http://localhost:3000
.Manual Browser Testing:
http://localhost:3000
in your browser.+1XXXYYYZZZZ
). Click "Send Code."API Endpoint Testing (Optional – using
curl
): Test POST endpoints directly.Send OTP:
Look for HTML response with Step 2 form and hidden
id
field. Extract theid
value.Verify OTP:
Look for HTML response for Step 3 (success) or Step 2 (failure).
6. Enhance Your Implementation
Improve security and user experience:
isPhoneNumberVerified: true
) in your database upon success.verificationId
server-side in session instead of hidden field for better security with logged-in users.params.type
to'tts'
inmessagebird.verify.create
to send OTP via voice call instead of SMS.verify.create
parameters:timeout
(default 600s = 10 minutes),tokenLength
(default 6),language
, andvoice
(for TTS).7. Troubleshoot Common Issues
Solve common problems:
MESSAGEBIRD_API_KEY
in.env
is correct and is a Live key. Check for typos or spaces. Error messages mention authentication failure.+14155552671
). Include '+' and country code. API error code 21 indicates this. Uselibphonenumber-js
for production validation.timeout
duration (default 600 seconds = 10 minutes, not 30 seconds). Verification fails if users take too long (error code 20 or 23). Ensure entered token matches received code. MessageBird allows up to 3 attempts per ID (maxAttempts: 3
).8. Deploy to Production
Prepare your application for deployment:
.env
files.package.json
(notdevDependencies
). Runnpm install --production
in deployment environment.Frequently Asked Questions About MessageBird OTP/2FA
How do I implement OTP verification in Node.js?
Implement OTP verification in Node.js using the MessageBird Verify API. Install the
messagebird
SDK, initialize the client with your API key, create a verification request withclient.verify.create()
, and verify user input withclient.verify.verify()
. The process includes sending an SMS with a random token and validating the user's response within the timeout period (default 600 seconds).What is MessageBird Verify API?
MessageBird Verify API is a service that handles OTP (One-Time Password) generation, delivery, and verification for two-factor authentication. It automatically generates random tokens, sends them via SMS, manages token expiration, and provides verification endpoints. The API handles rate limiting, attempt tracking, and security features to protect against brute-force attacks.
Is SMS OTP secure for 2FA?
SMS OTP provides moderate security for two-factor authentication but has known vulnerabilities. According to OWASP Multifactor Authentication guidelines, SMS is susceptible to SIM swapping attacks, SS7 protocol exploits, and device theft. For high-security applications, use TOTP (Time-based One-Time Password) apps like Google Authenticator or hardware tokens. SMS OTP works best for low-to-medium security scenarios when combined with rate limiting and account monitoring.
How much does MessageBird SMS cost?
MessageBird SMS pricing varies by destination country. As of 2024, US SMS costs approximately $0.008 per message. International rates differ significantly—check MessageBird's pricing page for your target regions. The Verify API uses standard SMS pricing with no additional verification fees. Calculate costs based on your expected verification volume and user geography.
What's the difference between SMS OTP and TOTP?
SMS OTP delivers codes via text message to your phone number, while TOTP (Time-based One-Time Password) generates codes locally using an authenticator app. TOTP is more secure because it doesn't rely on telecom networks vulnerable to interception. SMS OTP offers better user experience since it requires no app installation. Use TOTP for high-security applications and SMS OTP for user convenience in lower-risk scenarios.
How do I handle MessageBird API errors in Node.js?
Handle MessageBird API errors using try-catch blocks around API calls. Check for specific error codes in the response: error code 20 indicates missing parameters, code 21 means the verification ID is invalid, and code 25 indicates too many verification attempts. Always provide user-friendly error messages and implement logging for debugging. Use proper HTTP status codes (400 for validation errors, 500 for server errors, 429 for rate limiting).
Can I customize the OTP message template in MessageBird?
Yes, customize the OTP message template using the
template
parameter inclient.verify.create()
. Include%token
as a placeholder where the OTP code appears. Keep messages under 160 characters to avoid SMS concatenation. Example:"Your VerifyApp code is %token. Valid for 10 minutes."
Alphanumeric sender IDs work in Europe but not in the US or Canada, where you need a registered long code.How long should OTP codes remain valid?
Set OTP validity between 5-10 minutes (300-600 seconds) using the
timeout
parameter. MessageBird's default is 600 seconds (10 minutes). Shorter timeouts improve security but may frustrate users with delayed messages. Longer timeouts reduce user friction but increase vulnerability to replay attacks. Consider your user experience needs and security requirements when setting this value.How do I implement rate limiting for OTP requests?
Implement rate limiting using
express-rate-limit
middleware. Limit OTP generation to 3-5 requests per hour per IP address and per phone number. Set verification attempt limits to 3 tries per verification ID (MessageBird's default). Store rate limit data in Redis for distributed systems or use in-memory storage for single-server deployments. Return HTTP 429 (Too Many Requests) when limits are exceeded.What happens if a user doesn't receive the OTP SMS?
If a user doesn't receive the OTP SMS, check MessageBird's delivery status using the verification ID. Common causes include invalid phone numbers, carrier filtering, or network delays. Implement a "resend code" feature with rate limiting (maximum 2-3 resends per verification attempt). Provide alternative verification methods like voice calls or email as fallbacks. Log delivery failures for monitoring and troubleshooting.
9. Complete Code Repository
A complete, runnable version of this project is available on GitHub.
(Add your repository link here.)
You now have a functional Node.js application for SMS OTP verification using MessageBird's Verify API. This provides a solid foundation for adding two-factor authentication to your web applications. Adapt the error handling, security measures, and UI/UX to fit your production environment's specific needs.