Frequently Asked Questions
Use the Vonage Messages API with the @vonage/server-sdk in your Node.js application. The send-sms.js example demonstrates how to initialize the Vonage client and use the vonage.messages.send() method to send text messages. Ensure your Vonage application is set up correctly with the necessary API credentials.
A Vonage Application acts as a container that connects your Vonage API keys, private key, virtual numbers, and webhook URLs. It's essential for sending SMS messages and receiving inbound messages and delivery receipts. Create one through the Vonage API Dashboard.
First, run ngrok to create a public URL for your local server. Then, in your Vonage Application settings, set the Inbound URL to your ngrok URL + /webhooks/inbound and the Status URL to your ngrok URL + /webhooks/status. This tells Vonage where to send incoming messages and delivery updates.
A 200 OK response from your webhook endpoint acknowledges to Vonage that you've successfully received the webhook. If Vonage doesn't receive this acknowledgment, it will retry sending the webhook multiple times to avoid data loss.
The private.key file is crucial for authenticating your application with Vonage. It is generated when you create a Vonage Application and should be kept secure, never committed to version control.
Set up a webhook endpoint (e.g., /webhooks/status) in your Express server. Vonage will send POST requests to this URL with delivery status updates, including 'submitted', 'delivered', 'failed', or 'rejected'. Your endpoint should parse this data and update your application's internal state accordingly.
Configure the /webhooks/inbound endpoint on your server and link it to your Vonage Application and virtual number. When someone sends an SMS to your Vonage number, Vonage will send the message data to your inbound webhook URL.
The Messages API is Vonage's recommended API for sending and receiving SMS messages. It's more versatile than the older SMS API and offers richer features, including unified handling of different message types.
The delivery receipt webhook includes the message_uuid, status (e.g., delivered, failed), timestamp, and any error codes/reasons if the delivery failed. Log this information for debugging and monitoring.
Yes, it is highly recommended to use environment variables (.env file for development, system environment variables for production) to store sensitive credentials like API keys and secrets. This prevents accidental exposure in your codebase.
Implement a try...catch block around the vonage.messages.send() call to handle potential errors during the API request. Log detailed error information, including any Vonage-specific error responses, and implement retry logic if necessary.
ngrok provides a public URL that tunnels to your local development server. This is necessary for Vonage to send webhook requests to your local machine during development and testing.
Use a structured logging library like Winston or Pino for better organization, different log levels (info, error, warning), and easier log management in a production environment.
Start your Express server and ngrok. Run the send-sms.js script to send a test SMS and observe the logs in your server console and the ngrok web interface for delivery status updates and webhook requests. Also, send an SMS to your Vonage number to test the inbound webhook.
.gitignore
Learn how to implement SMS delivery status tracking and webhook callbacks using the Vonage Messages API with Node.js. This comprehensive guide covers sending SMS messages, receiving delivery receipts (DLR), and handling inbound message webhooks for real-time SMS communication tracking.
What You'll Build
By the end of this tutorial, you will have a production-ready Node.js application that:
This implementation is essential for applications requiring SMS delivery confirmation, including:
Understanding Vonage SMS Delivery Status and Webhooks
When you send an SMS message through the Vonage Messages API, you receive an immediate HTTP response confirming the message was submitted to the carrier network. However, this doesn't guarantee the message reached the recipient's device. To track actual delivery, you need to implement delivery receipt (DLR) webhooks that receive real-time status updates as your message progresses through the carrier network.
This tutorial builds a robust Node.js backend that integrates Vonage's webhook system for complete SMS delivery tracking and two-way messaging capabilities.
Technologies Used:
@vonage/server-sdk: The official Vonage Node.js SDK for interacting with Vonage APIs.dotenv: A module to load environment variables from a.envfile for secure configuration management.ngrok: A tool to expose local development servers to the internet, necessary for testing Vonage webhooks.System Architecture:
Prerequisites:
ngrokinstalled and authenticated (Download ngrok). A free account is sufficient.Final Outcome:
You will have two main components:
send-sms.js) to send an SMS message via Vonage and capture the unique message UUID for tracking.server.js) with webhook endpoints for receiving delivery status updates and inbound messages from Vonage.Setting Up Your Node.js Project for Vonage SMS Webhooks
Let's create the project structure and install the necessary dependencies for handling Vonage SMS delivery status callbacks.
1. Create Project Directory:
Open your terminal and create a new directory for your project_ then navigate into it.
2. Initialize Node.js Project:
Initialize a
package.jsonfile.(This accepts default settings. Feel free to omit
-yto customize.)3. Install Dependencies:
We need the Express framework_ the Vonage SDK_ and
dotenvfor managing environment variables.express: Web framework for handling webhook requests.@vonage/server-sdk: To interact with the Vonage APIs.dotenv: To load credentials securely from a.envfile.4. Create Project Files:
Create the main files we'll be working with.
.env: Stores sensitive credentials (API keys_ application ID_ etc.).server.js: Runs the Express server to listen for webhooks.send-sms.js: Contains the logic to send an SMS message..gitignore: Specifies files/directories that Git should ignore (like.envandnode_modules).5. Configure
.gitignore:Add the following lines to your
.gitignorefile to prevent committing sensitive information and unnecessary files:6. Set Up Environment Variables (
.env):Open the
.envfile and prepare it for your Vonage credentials. We'll fill these in later..env? Storing credentials directly in code is insecure. Using environment variables loaded from.env(which is gitignored) keeps secrets out of your source control.dotenvmakes this easy in development. In production, you'd typically set these variables directly in your hosting environment.Configuring Vonage Webhooks for SMS Delivery Status
To receive delivery status callbacks and inbound messages, you must configure webhook URLs in your Vonage Application. Vonage will send HTTP POST requests to these endpoints whenever message events occur (delivery status changes, incoming messages).
1. Set Default SMS API to Messages API:
2. Run
ngrok:Before creating the Vonage Application, you need a publicly accessible URL for your local server's webhooks.
ngrokprovides this. Open a new terminal window and run:(Replace
3000if you chose a different port in.env)ngrokwill display output similar to this:Copy the
https://<random-string>.ngrok-free.appURL. This is your public base URL. Keep this terminal window running.3. Create a Vonage Application:
Node SMS Callbacks App).private.key. Save this file in your project's root directory (the same place asserver.js). This key is used by the SDK to authenticate requests for this application.ngrokForwarding URL and append/webhooks/inbound. Example:https://<random-string>.ngrok-free.app/webhooks/inboundngrokForwarding URL and append/webhooks/status. Example:https://<random-string>.ngrok-free.app/webhooks/status4. Link Your Vonage Number:
5. Update
.envFile:Now, open your
.envfile and fill in the values you obtained:Ensure
VONAGE_PRIVATE_KEY_PATHcorrectly points to where you saved theprivate.keyfile.Sending SMS Messages with Node.js and Tracking Message UUIDs
Every SMS sent through the Vonage Messages API receives a unique
message_uuididentifier. This UUID is critical for tracking delivery status updates, as Vonage includes it in webhook callbacks to match status updates with the original message.File:
send-sms.jsExplanation:
.envvariables and the Node.jsfsmodule.process.env.fs.readFileSync. Includes error handling if the file is missing or unreadable.Vonageinstance, passing the API key, secret, application ID, and the content of the private key.sendSmsFunction:asyncfunction to handle the asynchronous API call.vonage.messages.send()which is the correct method for the Messages API.message_type,text,to,from, andchannel.try...catchblock for error handling.messageUuidfrom the successful response (resp.messageUuid) - this UUID is essential for correlating delivery status updates.sendSmsfunction to initiate the process.Building Express Webhook Endpoints for SMS Delivery Status
Create Express.js endpoints to receive Vonage webhook callbacks. You'll need two separate endpoints: one for delivery status updates (
/webhooks/status) and one for inbound messages (/webhooks/inbound).File:
server.jsExplanation:
require('dotenv').config();loads the variables from.env.const app = express();creates the Express application.app.use(express.json());: Parses incoming requests with JSON payloads (which Vonage uses for webhooks).app.use(express.urlencoded({ extended: true }));: Parses incoming requests with URL-encoded payloads.app.post('/webhooks/inbound', ...): Defines a handler for POST requests to the/webhooks/inboundpath. It logs relevant information from the request body (req.body).app.post('/webhooks/status', ...): Defines a handler for POST requests to the/webhooks/statuspath. It logs the delivery status information including themessage_uuidto correlate with sent messages.res.status(200).end();: This is critical. Vonage expects a200 OKresponse quickly to acknowledge receipt. Failure to send this promptly will cause Vonage to retry the webhook.app.listen(PORT, ...)starts the server on the specified port.Implementing Proper Error Handling and Logging
The current code includes basic
console.logstatements. For production, you'd want more robust logging and error handling.Error Handling (
send-sms.js):The
try...catchblock in the updatedsend-sms.jsalready handles errors during the API call more robustly. You can enhance this further:Logging (
server.js):Replace
console.logwith a dedicated logging library likewinstonorpinofor structured logging, different log levels (info, warn, error), and log rotation.Retry Mechanisms (Vonage):
200 OK. Ensure your webhook endpoints respond quickly. Offload time-consuming processing..catchblock insend-sms.jsif necessary (e.g., for transient network errors), potentially using exponential backoff.Database Schema and Data Layer (Conceptual)
This guide focuses on the core integration. In a real application, you would store message details and status updates in a database.
Conceptual Schema (e.g., PostgreSQL):
Data Layer Implementation:
vonage.messages.send()succeeds, insert a record withdirection='outbound',status='submitted', and themessage_uuid.message_uuidand update itsstatus,vonage_status_timestamp, etc.direction='inbound',status='delivered', and details from the payload.Adding Security Features
.envand.gitignore. Use environment variables or secrets management in production. Never commit secrets.X-Vonage-Signatureheader in incoming webhook requests.VONAGE_API_SECRETand compare it to the header value.@vonage/server-sdkmay offer utilities, but manual implementation might be needed. Implementing this is crucial for production security.ngrokprovides HTTPS. Ensure your production deployment uses HTTPS for webhook URLs.Understanding SMS Delivery Status Values
Vonage delivery status webhooks include a
statusfield indicating the current message state:submitted: Message accepted by Vonage and sent to the carrier networkdelivered: Carrier confirmed the message reached the recipient's devicefailed: Delivery failed (network issues, invalid number, etc.)rejected: Message rejected by carrier (often due to content filtering)expired: Message expired before delivery (recipient phone off for extended period)Important: Not all carriers support delivery receipts. In some countries/networks, you may only receive
submittedstatus. Always handle cases wheredeliveredstatus never arrives.Additional Implementation Considerations
message_type: 'text'+14155550101) for international compatibilityImplementing Performance Optimizations
200 OKimmediately. Offload slow processing (DB writes, external calls) to background jobs (e.g.,bullmq,agenda, AWS SQS).sms_messages) on frequently queried columns (message_uuid,status, numbers).pm2for process management and clustering.Adding Monitoring, Observability, and Analytics
/healthendpoint returning200 OK.Troubleshooting Common Issues
VONAGE_API_KEY,VONAGE_API_SECRET,VONAGE_APPLICATION_ID,VONAGE_PRIVATE_KEY_PATHin.env. Ensure the private key file exists and is readable.ngrokIssues:ngrokruns and points to the correct local port (3000).ngrokForwarding URL in the Vonage Application webhook settings is current (it changes on restart for free accounts).ngrokweb interface (http://127.0.0.1:4040) for requests/errors.3000).200 OK: Check server logs (server.jsoutput) for errors if Vonage retries webhooks. Ensure quick responses.submittedconfirms handoff to the carrier.private.key: Ensure theprivate.keyfile matches theVONAGE_APPLICATION_IDand its content is correct.+1...) for phone numbers.Deployment and CI/CD
ngrok: Deployserver.jsto a hosting provider (Heroku, AWS, Google Cloud, etc.)..envfile. Uploadprivate.keysecurely or store its content in an environment variable (handle newlines carefully).pm2to run your Node.js app:Testing SMS Delivery Status Webhooks
1. Start Required Services:
ngrok http 3000and copy the Forwarding URLngrokURLnode server.js2. Test Sending SMS:
node send-sms.js.SMS Sent Successfully! Message UUID: <uuid>.TO_NUMBERreceives the SMS.server.jslogs a "Delivery Status Update" (initiallysubmitted, then potentiallydelivered).3. Test Receiving Inbound SMS:
VONAGE_NUMBER.server.jslogs an "Inbound SMS Received" entry.ngrokweb interface (http://127.0.0.1:4040) for request details.4. Test Error Cases:
TO_NUMBERto an invalid format insend-sms.js, run it, and observe script errors and potentialrejected/failedstatus updates.server.js, send an SMS viasend-sms.js. Observe webhook failures inngrok. Restartserver.jsto receive queued webhooks.Verification Checklist:
npm install)..envpopulated correctly.private.keyfile present and correct path in.env.ngrok/production URL + paths.ngrokrunning, forwarding correctly.server.jsrunning without errors.node send-sms.jssends SMS successfully.server.jslogs delivery status.VONAGE_NUMBERlogs inbound message inserver.js.200 OK.Next Steps and Production Considerations
You now have a working implementation for tracking Vonage SMS delivery status with Node.js webhooks. To prepare for production:
Related Resources