Frequently Asked Questions
Use the Vonage Messages API and the Node.js Server SDK. After setting up a Vonage application and installing necessary dependencies, create an Express server with routes to handle sending messages and webhooks. The provided sendSms
function handles sending messages through the API.
The Vonage Messages API is a unified interface for sending messages across various channels like SMS, MMS, WhatsApp, and more. It simplifies multi-channel communication by handling complexities of individual platforms through a single API.
The Vonage Node.js Server SDK streamlines authentication and message sending through the Vonage API. It handles low-level details, making integration easier by providing functions like messages.send()
.
Always verify webhook signatures for security, especially in production. This ensures incoming webhooks originate from Vonage and haven't been tampered with. The verifyWebhookSignature
function and rawBodyMiddleware
are crucial for this step.
Yes, use the Vonage Messages API Sandbox for initial testing. It lets you send and receive WhatsApp messages without a full business setup after linking a WhatsApp-enabled device.
Set up webhook endpoints in your Express server and configure the URLs in your Vonage Application settings. The /webhooks/inbound
route receives message data and should respond with 200 OK quickly. You can send automated replies using this route after verifying the signature.
ngrok creates a public, secure tunnel to your local development server, enabling Vonage to send webhooks to your machine during development and testing.
Implement a webhook endpoint at /webhooks/status
. This endpoint will receive POST requests from Vonage containing the message status (e.g., 'delivered', 'failed') and associated metadata.
Node.js version 18 or higher is recommended for this project, along with npm, which is included with the Node.js installation.
Implement authentication mechanisms like API keys, JWT, or OAuth2 to protect your endpoints. Validate all incoming data and use environment variables for sensitive information. Libraries like express-validator
and passport
are helpful.
The Vonage Application ID is a unique identifier for your application within Vonage, used for grouping your numbers, configuring webhooks, and managing credentials.
The private.key
file is essential for authenticating your application with the Vonage API and should be kept secure. Never commit it to version control. Load securely in production, not directly from the file system.
Create a .env
file in your project root and add your Vonage API key, secret, application ID, private key path, and other relevant configuration values. Use dotenv
package to load these variables into your Node.js application.
In the Vonage Dashboard, go to your application settings. Under 'Linked Numbers', find your purchased virtual number and click the 'Link' button to associate it with your application.
Build a Node.js Express application to send SMS and WhatsApp messages via the Vonage Messages API. This guide covers project setup, sending messages through different channels, handling incoming messages and status updates via webhooks, and implementing essential production considerations like security and error handling.
By the end of this tutorial, you'll have a functional application capable of programmatically sending SMS and WhatsApp messages and receiving delivery status updates and inbound messages from users. This provides a foundation for building chatbots, notification systems, two-factor authentication flows, and other communication-driven features.
Project Overview and Goals
What You'll Build:
Problem Solved:
This application provides a unified way to interact with customers or users over two popular messaging channels – SMS and WhatsApp – directly from your Node.js backend. It abstracts the complexities of the Vonage API into reusable functions and provides a basic structure for handling asynchronous communication events.
Technologies Used:
@vonage/server-sdk
): Simplifies interaction with Vonage APIs, including authentication and sending messages@vonage/messages
): Provides convenient classes for constructing messages for specific channels (likeWhatsAppText
)@vonage/jwt
): Used for verifying the signature of incoming webhook requests to ensure they originate from Vonagedotenv
: A module to load environment variables from a.env
file intoprocess.env
ngrok
: A tool to expose local servers to the internet, necessary for testing webhooks during developmentSystem Architecture:
Prerequisites:
How Do You Set Up a Node.js Project for Vonage Messaging?
Initialize your Node.js project and install the necessary dependencies.
Create Project Directory: Open your terminal or command prompt and create a new directory for your project_ then navigate into it:
Initialize Node.js Project: Initialize the project using npm. The
-y
flag accepts default settings.This creates a
package.json
file.Install Dependencies: Install Express_ the Vonage SDKs_ and
dotenv
:express
: Web framework@vonage/server-sdk
: Core Vonage SDK for authentication and API calls@vonage/messages
: Specific classes for constructing message types (e.g._WhatsAppText
)@vonage/jwt
: For webhook signature verificationdotenv
: For managing environment variablesCreate Project Structure: Create a basic structure for your code:
src/server.js
: Your main application code.env
: Stores sensitive credentials and configuration.gitignore
: Prevents committing sensitive files (like.env
) andnode_modules
to version controlConfigure
.gitignore
: Add the following lines to your.gitignore
file to avoid committing sensitive information and dependencies:Set up Vonage Application: Create a Vonage Application to group your numbers and configurations_ and generate authentication credentials.
private.key
file. Save this file securely in the root of your project directory (e.g._ alongsidepackage.json
). Crucially_ ensureprivate.key
is listed in your.gitignore
file and is NEVER committed to version control. For production_ load this key securely (e.g._ from environment variables_ secrets management_ or a secure volume mount) rather than directly from the filesystem. The public key is stored by Vonage.ngrok
. Leave them blank for now or use temporary placeholders likehttp://localhost
.Configure SMS API Settings: Ensure your account uses the Messages API for SMS by default_ as recommended by Vonage documentation for new integrations.
Set up WhatsApp Sandbox (for Testing): For testing WhatsApp without a full business setup_ use the Vonage Sandbox.
Start
ngrok
: To receive webhooks from Vonage on your local machine_ expose your local server to the internet.Open a new terminal window (keep your project terminal open).
Run
ngrok
_ specifying the port your Express server will listen on (use port 3000):ngrok
will display output including a Forwarding URL that looks likehttps://<random-string>.ngrok-free.app
(or similar, depending on your plan/version). Copy this HTTPS URL.Configure Webhook URLs in Vonage:
ngrok
HTTPS URL followed by/webhooks/inbound
into the Inbound URL field (e.g.,https://<random-string>.ngrok-free.app/webhooks/inbound
).ngrok
HTTPS URL followed by/webhooks/status
into the Status URL field (e.g.,https://<random-string>.ngrok-free.app/webhooks/status
)..../webhooks/inbound
and.../webhooks/status
) into the respective webhook fields on the Sandbox configuration page.Configure Environment Variables (
.env
): Open the.env
file you created and add the following variables, replacing the placeholder values with your actual credentials:VONAGE_API_KEY
&VONAGE_API_SECRET
: Found at the top of your Vonage API Dashboard.VONAGE_APPLICATION_ID
: The ID generated when you created the Vonage Application.VONAGE_PRIVATE_KEY
: The path to theprivate.key
file you downloaded and saved in your project root. Ensure this path is correct relative to where you run the node process.VONAGE_SMS_FROM_NUMBER
: Your purchased Vonage virtual number (without+
or leading00
).VONAGE_WHATSAPP_SANDBOX_NUMBER
: The specific number provided by the Vonage WhatsApp Sandbox. For production WhatsApp, this would be your registered WhatsApp Business number.VONAGE_API_SIGNATURE_SECRET
: Found in the Vonage API Dashboard under API Settings → Webhook signature secret. Click "Edit" or "Generate" if needed.PORT
: The port your Express server will run on (must match thengrok
port).How Do You Implement SMS and WhatsApp Messaging in Express?
Now, let's write the code in
src/server.js
to initialize the server, configure Vonage, send messages, and handle webhooks.Explanation:
dotenv.config()
loads variables from.env
.Vonage
client using credentials from environment variables. Checks ensure essential credentials (including signature secret) exist, exiting if not. We comment out theapiHost
override for the sandbox, preferring the default endpoint.sendSms
Function: TakestoNumber
andmessageText
, constructs the payload for the Messages API (channel: 'sms'
), and usesvonage.messages.send()
. Basic logging for success and failure is included.sendWhatsApp
Function: Similar tosendSms
, but uses theWhatsAppText
class from@vonage/messages
and specifieschannel: 'whatsapp'
. It uses theVONAGE_WHATSAPP_SANDBOX_NUMBER
by default.rawBodyMiddleware
&verifyWebhookSignature
: This is crucial for security. Vonage signs webhook requests with a JWT using your Signature Secret.verifySignature
needs the raw, unparsed request body. We create middleware (rawBodyMiddleware
) usingexpress.raw
to capture this raw body beforeexpress.json()
parses it for specific webhook routes. TheverifyWebhookSignature
function extracts the JWT from theAuthorization
header and uses@vonage/jwt
'sverifySignature
method along with the raw body and your secret to validate the request. Crucially, if the signature secret is missing or verification fails, the function now returnsfalse
, preventing insecure processing./webhooks/inbound
,/webhooks/status
):rawBodyMiddleware
first, thenexpress.json()
.verifyWebhookSignature
to ensure the request is legitimate. Unauthorized requests are rejected with401
./inbound
handler logs the incoming message, extracts sender and content based on the channel, and optionally sends a reply using our helper functions./status
handler logs delivery status updates.res.status(200).end()
promptly to prevent Vonage from retrying the webhook./api/send/sms
,/api/send/whatsapp
):express.json()
middleware applied after the webhook routes.to
,message
), including a simple digit check for the phone number, with notes on using better validation libraries. The error message clarifies the SDK's expectation for E.164 format.sendSms
orsendWhatsApp
functions.@api
comments are noted as usable withapidoc
.PORT
. We add checks/warnings on startup for missing optional environment variables.How Do You Secure and Enhance Your Messaging API for Production?
The example above includes basic API endpoints (
/api/send/sms
,/api/send/whatsapp
). For a production system, you would enhance this layer significantly:Authentication & Authorization: Protect your API endpoints. Common methods include:
API Keys: Issue unique keys to clients. Clients send the key in a header (e.g.,
X-API-Key
). Your server validates the key against a stored list.JWT (JSON Web Tokens): Implement a login flow where users/systems get a JWT upon successful authentication. They include the JWT in the
Authorization: Bearer <token>
header for subsequent requests. Libraries likepassport
withpassport-jwt
orpassport-http-bearer
(for API keys) can help.OAuth2: For third-party integrations or more complex authorization scenarios.
Implementation Example (Conceptual - using a simple API key check middleware):
Request Validation: Sanitize and validate all incoming data rigorously.
Use libraries like
express-validator
orjoi
to define schemas for request bodies and query parameters.Check data types, lengths, formats (e.g., ensure phone numbers adhere to E.164 using libraries like
libphonenumber-js
).Example using
express-validator
:Frequently Asked Questions
Can I send WhatsApp messages outside the 24-hour window?
WhatsApp enforces a 24-hour customer service window. When a user messages you or calls you, a 24-hour timer starts. During this window, you can send any type of message for free. After 24 hours, you can only send pre-approved message templates. The window resets each time the user responds. Plan your messaging strategy accordingly – use templates to initiate conversations, then engage freely within the 24-hour window.
How do I verify that webhooks are coming from Vonage?
Vonage signs webhook requests with a JWT (JSON Web Token) using HMAC-SHA256 and your signature secret. Always verify the signature before processing webhook data. The signature secret should be at least 32 bits and stored securely. Compare the JWT from the
Authorization
header against your secret using the@vonage/jwt
library'sverifySignature
method. Additionally, compare a SHA-256 hash of the payload to thepayload_hash
claim in the JWT to guard against token replay attacks. Reject any requests that fail verification with a 401 status code.What's the difference between the Vonage Sandbox and production WhatsApp?
The Vonage WhatsApp Sandbox uses a shared test number (14157386102) and allows you to test WhatsApp integration without a full WhatsApp Business Account setup. You must "allowlist" your number by sending a specific message to the Sandbox number. For production, you need a registered WhatsApp Business number linked to your Vonage application. The Sandbox is ideal for development and testing, but production requires proper WhatsApp Business API approval and your own dedicated business phone number.
How do I handle message delivery failures?
Monitor the status webhook (
/webhooks/status
) for delivery updates. Messages can fail for various reasons: invalid phone numbers, undelivered due to network issues, or rejected by WhatsApp. Implement retry logic with exponential backoff for transient failures. Log all message UUIDs and their status updates to track delivery rates. For critical messages, consider implementing a fallback channel (e.g., SMS) when WhatsApp delivery fails. Always handle errors gracefully in yoursendSms
andsendWhatsApp
functions.What phone number format does Vonage expect?
Vonage expects phone numbers in E.164 format without the leading
+
symbol. E.164 format includes the country code followed by the subscriber number (e.g., 14155550100 for a US number). Use libraries likelibphonenumber-js
to validate and format phone numbers correctly before sending them to the Vonage API. Invalid phone number formats will result in API errors and failed message delivery.How do I secure my API endpoints for production use?
Never deploy the example endpoints to production without authentication. Implement API key validation, JWT-based authentication, or OAuth2 depending on your use case. Store API keys in a secure database or secrets management service, never in code. Use HTTPS for all communications. Implement rate limiting to prevent abuse. Validate all input data rigorously using libraries like
express-validator
. Consider implementing IP whitelisting for additional security. Load your Vonage private key from environment variables or a secure vault, never commit it to version control.Can I send media files via WhatsApp using Vonage?
Yes, the Vonage Messages API supports sending images, videos, audio files, and documents via WhatsApp. Use the appropriate message type classes from
@vonage/messages
(e.g.,WhatsAppImage
,WhatsAppVideo
,WhatsAppAudio
,WhatsAppFile
). Media files must be publicly accessible via HTTPS URL, or you can upload them using Vonage's media API. WhatsApp has file size limits: images (5 MB), videos (16 MB), audio (16 MB), and documents (100 MB). The file format must be supported by WhatsApp.How do I test webhooks locally?
Use
ngrok
to expose your local Express server to the internet. Runngrok http 3000
to create a public HTTPS URL that forwards to your local port 3000. Copy the ngrok HTTPS URL and configure it in your Vonage Application settings for both Inbound URL and Status URL (e.g.,https://abc123.ngrok-free.app/webhooks/inbound
). Ngrok provides a web interface athttp://localhost:4040
where you can inspect all webhook requests and responses, making debugging easier.What are the rate limits for the Vonage Messages API?
Vonage implements rate limiting to ensure fair usage and system stability. The specific limits depend on your account type and the messaging channel. WhatsApp has its own rate limits based on your business tier (Tier 1: 1,000 unique recipients per 24 hours, scaling up with verified quality). Implement proper error handling to catch rate limit errors (HTTP 429) and implement exponential backoff retry logic. Consider implementing a message queue for high-volume applications to smooth out traffic spikes and stay within rate limits.
How do I migrate from the Sandbox to production WhatsApp?
To move to production WhatsApp, register for a WhatsApp Business Account through Vonage. Complete the business verification process with Meta (Facebook). Once approved, you'll receive a dedicated WhatsApp Business number. Update your
.env
file to use your production WhatsApp number instead of the Sandbox number. Link your production number to your Vonage Application. Update webhook URLs if needed. Test thoroughly in production with real customer opt-ins. Ensure compliance with WhatsApp's Business Policy and Commerce Policy.Related Resources: