How to Send SMS with Vonage API in Node.js: Complete Express Tutorial
Learn how to send SMS with Vonage API using Node.js and Express. Step-by-step tutorial with @vonage/server-sdk 3.24.1, delivery receipts, error handling, and production deployment guide.
Learn how to send SMS messages with Vonage SMS API using Node.js and Express. This complete guide walks you through building a production-ready SMS application with @vonage/server-sdk 3.24.1, covering secure API credential management, error handling, delivery receipt tracking, and testing best practices.
You'll create a functional Express SMS server with a REST API endpoint that accepts a recipient phone number and message text, then delivers SMS messages reliably using the Vonage API. This Node.js SMS integration works for notifications, alerts, appointment reminders, or two-factor authentication (though Vonage's Verify API is purpose-built for 2FA workflows).
This tutorial uses Vonage's official Node.js SDK (@vonage/server-sdk) with comprehensive error handling for delivery receipts (DLRs) and message status tracking.
Current Versions (as of 2024–2025):
Node.js: v22 LTS (Active LTS until October 2025)
Express.js: 5.1.0 (requires Node.js 18 or higher)
@vonage/server-sdk: 3.24.1
Project Overview: Building a Vonage SMS API Integration
What You'll Build:
A Node.js Express server with a single API endpoint (POST /send-sms). This endpoint receives a destination phone number and text message body, then uses the Vonage Node.js SDK to send SMS messages programmatically.
Problem Solved:
Integrate SMS sending capabilities into Node.js applications quickly and reliably using Vonage's enterprise-grade communication platform.
Technologies Used:
Technology
Purpose
Version
Node.js
JavaScript runtime for server-side applications
v22 LTS
Express.js
Minimal web framework for creating the API endpoint
5.1.0
Vonage SMS API
Communication Platform as a Service (CPaaS) for sending SMS
Latest
@vonage/server-sdk
Official Vonage Node.js SDK
3.24.1
dotenv
Loads environment variables from .env into process.env, keeping credentials secure
Latest
System Architecture:
A client (e.g., Postman, curl, another application) sends a POST request to the /send-sms endpoint.
Express parses the request body to extract the recipient number and message text.
The server uses the Vonage Node.js SDK (configured with your API credentials) to send a request to the Vonage SMS API.
Vonage processes the request and sends the SMS message to the recipient's phone number.
Vonage returns a response to your server, which sends a response back to the client.
Vonage Phone Number: Rent a virtual number from Vonage. Go to Numbers > Buy numbers in the Vonage Dashboard. Ensure the number supports SMS in your target region
Verified Test Phone Number (for trial accounts): Trial accounts can only send SMS to verified numbers. Add and verify numbers in the Sandbox / Test Numbers page
Text Editor or IDE: VS Code, Sublime Text, or WebStorm
Basic terminal/command line knowledge
Step 1: Set Up Your Vonage Node.js SMS Project
Initialize your Node.js project and install the necessary dependencies.
Create a Project Directory:
Bash
mkdir vonage-sms-guide
cd vonage-sms-guide
Initialize the Node.js Project:
Create a package.json file. The -y flag accepts default settings.
Bash
npm init -y
Install Dependencies:
Install express, @vonage/server-sdk, and dotenv.
Bash
npm install express @vonage/server-sdk dotenv
Create Core Files:
Bash
# On macOS/Linuxtouch index.js .env .gitignore
# On Windows (Command Prompt)type nul > index.js
type nul > .envtype nul > .gitignore
# On Windows (PowerShell)
New-Item index.js -ItemType File
New-Item .env -ItemType File
New-Item .gitignore -ItemType File
Configure Environment Variables (.env):
Open .env and add your Vonage API credentials and rented number.
Create the SMS Sending Endpoint (/send-sms):
Define a POST route to handle SMS sending requests.
JavaScript
// index.js (continued)
app.post('/send-sms', async (req, res) => {
// Basic input validationconst { to, text } = req.body;
if (!to || !text) {
return res.status(400).json({
success: false,
message: 'Missing `to` or `text` parameter in request body.'
});
}
constfrom = process.env.VONAGE_FROM_NUMBER;
try {
const resp = await vonage.sms.send({ to, from, text });
console.log('Message sent successfully:', resp);
// Status '0' indicates successful submission to the Vonage network, not delivery to the handset.// DLR statuses include: DELIVRD (delivered), UNDELIV (undelivered), EXPIRED, FAILED, REJECTD, DELETED, UNKNOWN.if (resp.messages && resp.messages.length > 0 && resp.messages[0].status === '0') {
res.status(200).json({
success: true,
message: 'SMS submitted successfully.',
messageId: resp.messages[0]['message-id']
});
} else {
console.error('Vonage API reported an issue:', resp);
const errorText = (resp.messages && resp.messages.length > 0) ?
resp.messages[0]['error-text'] : 'Unknown Vonage API error';
res.status(500).json({
success: false,
message: `Failed to send SMS. Vonage error: ${errorText}`,
details: resp
});
}
} catch (error) {
console.error('Error sending SMS:', error);
res.status(500).json({
success: false,
message: 'Internal server error while sending SMS.',
error: error.message
});
}
});
Key Points:
Define an async function to use await for the asynchronous vonage.sms.send call.
Basic validation checks if to and text are present in the request body.
Retrieve the from number from environment variables.
vonage.sms.send({ to, from, text }) makes the API call.
A try...catch block handles potential network errors or issues within the SDK call.
Inspect the resp object from Vonage. A status of '0' indicates successful submission to the network. Non-zero statuses indicate errors (e.g., invalid number, insufficient funds). Return the Vonage message-id on success.
Send appropriate JSON responses (success or error) back to the client with relevant status codes (200, 400, 500).
Start the Server:
Make the Express application listen for incoming requests on the configured port.
JavaScript
// index.js (continued)
app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
console.log(`SMS sending endpoint available at POST http://localhost:${port}/send-sms`);
});
Your index.js file is now complete.
Step 3: Test Your Vonage SMS Integration
Run the server and test the SMS sending functionality.
Run the Server:
Open your terminal in the project directory and run:
Bash
node index.js
You should see output indicating the server is running:
Code
Server listening at http://localhost:3000
SMS sending endpoint available at POST http://localhost:3000/send-sms
Test with curl or Postman:
Use curl (command-line) or Postman (GUI) to send a POST request to your endpoint.
Using curl:
Replace YOUR_RECIPIENT_NUMBER with the phone number you want to send the SMS to (use a verified number for trial accounts). Format the number including the country code (e.g., 14155550123).
Bash
curl -X POST http://localhost:3000/send-sms \
-H 'Content-Type: application/json' \
-d '{
"to": "YOUR_RECIPIENT_NUMBER",
"text": "Hello from your Vonage Node.js App!"
}'
Using Postman:
Create a new request.
Set the method to POST.
Enter the URL: http://localhost:3000/send-sms.
Go to the Body tab, select raw, and choose JSON from the dropdown.
Enter the JSON payload:
JSON
{"to":"YOUR_RECIPIENT_NUMBER","text":"Hello from your Vonage Node.js App!"}
Click Send.
Check the Response:
Successful Submission: You should receive a JSON response with a 200 OK status:
Check the recipient phone – the SMS should arrive shortly. You should also see confirmation logs in the terminal where node index.js is running.
Error Response: If something goes wrong (e.g., invalid credentials, incorrect 'to' number format, trial account restrictions), you'll get an error response with a non-200 status code:
JSON
// Example: Missing parameter{"success":false,"message":"Missing `to` or `text` parameter in request body."}
JSON
// Example: Vonage API error (e.g., non-whitelisted number){"success":false,"message":"Failed to send SMS. Vonage error: Non White-listed Destination - rejected","details":{/* ... full Vonage response ... */}}
JSON
// Example: Internal server error{"success":false,"message":"Internal server error while sending SMS.","error":"Some specific error message"}
Check the terminal logs for more detailed error information.
Step 4: Handle Vonage SMS API Errors and Delivery Receipts
Your current implementation includes basic try...catch blocks and logs errors to the console. For production systems, implement:
Structured Logging: Use libraries like Winston or Pino for structured logging (e.g., JSON format), which makes logs easier to parse and analyze, especially when sending them to log aggregation services (like Datadog, Splunk, ELK stack).
Centralized Logging: Configure your logger to send logs to a centralized platform instead of just console.log.
More Granular Error Handling: Check specific Vonage error codes (returned in the error-text or status fields) to provide more informative feedback or trigger specific actions (e.g., retry logic for temporary network issues, alerts for authentication failures). Common error codes include:
Error Code 15 (Rejection Code 10 for SMPP): "Illegal Sender" – occurs when sending SMS to the US or Canada without a US pre-approved long number, toll-free, 10DLC, or short code associated with your Vonage account.
Error Code 99: "General Error" – indicates a request was processed but failed due to various factors; check DLR details for specifics.
Non-zero status codes: Any status code other than '0' in the initial response indicates submission failure.
Delivery Receipts (DLRs): Sending the message successfully (status '0') only means Vonage accepted it for submission. To confirm delivery to the handset, set up a webhook endpoint to receive DLRs from Vonage. DLRs provide statuses like DELIVRD (delivered), UNDELIV (undelivered), EXPIRED, FAILED, REJECTD, DELETED, or UNKNOWN. Refer to the Vonage SMS API documentation and DLR Status documentation for complete error code listings.
Step 5: Secure Your Vonage API Credentials
API Key Security: Never commit your .env file or hardcode API keys/secrets directly in your source code. Use environment variables and ensure .env is in your .gitignore. In production environments, use your hosting provider's mechanism for managing secrets (e.g., AWS Secrets Manager, Heroku Config Vars, Kubernetes Secrets).
Input Validation: Your current validation is minimal. In a real application, perform more robust validation on the to phone number (e.g., check format using a library like libphonenumber-js version 1.11+ with metadata synced to September 2025, ~145 KB max metadata) and sanitize the text input to prevent potential injection attacks if the text is ever displayed elsewhere.
Rate Limiting: Protect your endpoint from abuse by implementing rate limiting (e.g., using express-rate-limit). This prevents users from sending excessive numbers of messages rapidly.
Authentication/Authorization: The current endpoint is open. In a real application, protect this endpoint, ensuring only authorized users or services can trigger SMS sending. This might involve API keys, JWT tokens, or session-based authentication added as middleware to the Express route.
Step 6: Troubleshoot Common Vonage SMS API Issues
Issue
Solution
Non-Whitelisted Destination Error
Add and verify recipient numbers in your Vonage Sandbox / Test Numbers page. Upgrade your account (add payment details) to send to any number.
Invalid Credentials
Double-check that VONAGE_API_KEY and VONAGE_API_SECRET in your .env file are correct and have no extra spaces.
Incorrect FROM Number
Ensure VONAGE_FROM_NUMBER is a valid number you rented from Vonage in the correct format (e.g., 14155550100).
Insufficient Funds
Check your balance in the dashboard. If your Vonage account runs out of credit, sending will fail.
Carrier Filtering
Mobile carriers might filter messages, especially if they appear spammy. Ensure your content is appropriate and consider using Alphanumeric Sender IDs (where supported) or Short Codes for higher volume/better deliverability.
SDK/API Changes
While @vonage/server-sdk is stable, always refer to the official Vonage documentation for the latest methods and response structures.
SMS API vs. Messages API
This guide uses the simpler Vonage SMS API flow via vonage.sms.send(). For multi-channel messaging (WhatsApp, Facebook Messenger, MMS) or advanced features, explore the Vonage Messages API with vonage.messages.send().
Step 7: Deploy Your Vonage Node.js SMS Application
Deploy this application on a server or platform (like Heroku, Render, AWS EC2, Google Cloud Run, etc.). Key steps include:
Environment Variables: Set VONAGE_API_KEY, VONAGE_API_SECRET, and VONAGE_FROM_NUMBER as environment variables on your chosen hosting platform. Do not upload the .env file.
Dependencies: Ensure npm install runs in the deployment environment to install dependencies.
Starting the App: Configure the platform to run your application using node index.js.
Port: Ensure your application listens on the port assigned by the hosting environment (often provided via a PORT environment variable, which your code already handles).
A Procfile for platforms like Heroku:
Text
web: node index.js
Complete Vonage SMS Code Example
The complete code for this guide includes index.js, package.json, .gitignore, and a .env.example file.
Frequently Asked Questions About Vonage SMS with Node.js
How do I send SMS with Vonage in Node.js?
Install @vonage/server-sdk (version 3.24.1 for 2025) and create a Vonage client with your API key and secret. Use vonage.sms.send({ to, from, text }) to send messages. You need a Vonage account, API credentials, and a rented virtual number. The complete setup requires Express for the REST endpoint, dotenv for credential management, and proper error handling for production use.
What does Vonage status code 0 mean?
Status code '0' indicates successful submission to the Vonage network, not delivery to the recipient's handset. To confirm actual delivery, implement webhook endpoints to receive Delivery Receipts (DLRs) from Vonage. DLR statuses include: DELIVRD (delivered), UNDELIV (undelivered), EXPIRED, FAILED, REJECTD, DELETED, and UNKNOWN.
What is Vonage Error Code 15?
Error Code 15 (Rejection Code 10 for SMPP) means "Illegal Sender" – this occurs when sending SMS to the US or Canada without a US pre-approved long number, toll-free, 10DLC, or short code associated with your Vonage account. To resolve this, obtain the appropriate number type for US/Canada SMS delivery through your Vonage Dashboard.
What is Vonage Error Code 99?
Error Code 99 indicates a "General Error" – meaning the request was processed but failed due to various factors. Check the Delivery Receipt (DLR) details for specifics about why the message failed. This error requires examining the error-text field in the response and consulting the Vonage SMS API error documentation for detailed troubleshooting.
What version of @vonage/server-sdk should I use in 2025?
Use @vonage/server-sdk version 3.24.1 (latest as of early 2025) with Node.js v22 LTS and Express 5.1.0. Install with npm install @vonage/server-sdk@3.24.1. This version provides stable SMS API functionality with improved error handling. Always check npm for the latest version.
How do I handle the "Non-Whitelisted Destination" error?
This is the most common error for Vonage trial accounts. Trial accounts can only send SMS to verified numbers. Add and verify recipient numbers in your Vonage Sandbox / Test Numbers page. To send to any number, upgrade your account by adding payment details in the Vonage Dashboard.
What are Delivery Receipts (DLRs) in Vonage SMS?
Delivery Receipts (DLRs) are webhook notifications from Vonage confirming whether your SMS was delivered to the recipient's handset. DLRs provide statuses like DELIVRD (delivered), UNDELIV (undelivered), EXPIRED, FAILED, REJECTD, DELETED, or UNKNOWN. Implement a webhook endpoint to receive DLRs for reliable message tracking. See the DLR Status documentation.
Should I use Vonage SMS API or Messages API?
For simple SMS sending with Node.js Express, use the SMS API via vonage.sms.send() with API Key/Secret authentication (covered in this guide). For multi-channel messaging (WhatsApp, Facebook Messenger, MMS) or advanced features, use the Vonage Messages API with vonage.messages.send(), which requires Application ID and Private Key authentication.
How do I validate phone numbers before sending SMS with Vonage?
Use libphonenumber-js version 1.11+ (with metadata synced to September 2025, ~145 KB max metadata) to validate phone number format before calling the Vonage API. Install with npm install libphonenumber-js and parse numbers to E.164 format. This prevents API errors from invalid phone numbers and improves delivery rates.
Can I send SMS from a Vonage trial account?
Yes, but with restrictions. Trial accounts receive free testing credit but can only send SMS to verified numbers added in the Sandbox / Test Numbers page. Upgrade your account (add payment details) to send SMS to any number. Trial accounts are perfect for development and testing before production deployment.
Next Steps: Enhancing Your Vonage SMS Integration
You've successfully built a Node.js application capable of sending SMS messages using Express and the Vonage API.
From here, you could:
Implement webhook endpoints to receive incoming SMS messages or delivery receipts.
Integrate this functionality into a larger application.
Add more robust error handling, logging, and monitoring.
Build a frontend interface to interact with the API.
Explore the Vonage Messages API for multi-channel communication.
Frequently asked questions
Use the Vonage API and Express.js framework within your Node.js application. This involves setting up a POST route in Express to handle requests, and then utilizing the Vonage Node.js SDK to send messages via their SMS API. The server receives the recipient's number and message text, then uses Vonage to deliver the SMS.
The Vonage API, a Communication Platform as a Service (CPaaS), enables sending SMS messages programmatically. In Node.js, you interact with it using the Vonage Node.js Server SDK, which simplifies sending SMS messages, managing two-factor authentication, and other communication tasks. The article provides a tutorial on its usage for sending SMS.
Dotenv is a crucial module for storing sensitive information such as API keys and secrets as environment variables within a .env file. It's instrumental in keeping these credentials secure and outside your main codebase, protecting them from accidental exposure through version control systems like Git.
While you can use the Vonage SMS API for two-factor authentication (2FA), Vonage's Verify API is often better suited for this specific purpose. It provides more advanced 2FA features and simplifies the process, streamlining security implementations.
Store your Vonage API_KEY, API_SECRET, virtual FROM_NUMBER, and PORT within a .env file. Then, use dotenv.config() in your index.js file to load these variables into your Node.js environment so your application can use them to authenticate with Vonage and send messages.
You'll need express for creating the API endpoint, @vonage/server-sdk to interact with the Vonage APIs, and dotenv to manage your Vonage API credentials securely as environment variables.
Define a POST route handler in your Express app, typically at /send-sms. This endpoint receives the recipient's number (to) and the message body (text) as parameters in the request. Inside the handler, use the Vonage SDK to send the message using the provided parameters.
A '0' status from the Vonage SMS API usually indicates successful message submission to the network, not final delivery to the recipient. To get confirmed delivery status, you need to implement delivery receipts (DLRs) using webhooks. These provide real-time updates on the message status as it progresses.
No, trial accounts have restrictions. You can only send SMS to numbers you've specifically verified in the Vonage dashboard's Sandbox / Test Numbers page. To lift this restriction, you must upgrade to a paid Vonage account.
The VONAGE_FROM_NUMBER is your designated Vonage Virtual Number, which acts as the sender ID for your outgoing SMS messages. This number is what recipients will see as the source of the SMS.
The example code uses basic try...catch blocks. For production, use libraries like Winston or Pino for structured logs and send them to centralized logging services. Implement more detailed error handling by checking Vonage error codes (like 'Non White-listed Destination') returned in the API response and take appropriate actions (e.g., retries or alerts).
Once your Express server is running, use tools like curl or Postman to send POST requests to the /send-sms endpoint. The request body should be JSON formatted with the recipient's number (to) and message (text). Ensure your trial account numbers are whitelisted in the Vonage dashboard.
Never expose your API keys directly in your code. Always use environment variables (.env file) and make sure this file is included in your .gitignore. In production, manage secrets securely using your platform's specific mechanisms. Also implement input validation to prevent potential injection vulnerabilities and use rate limiting to protect against abuse.
Learn how to send SMS messages with Vonage SMS API using Node.js and Express. This complete guide walks you through building a production-ready SMS application with @vonage/server-sdk 3.24.1, covering secure API credential management, error handling, delivery receipt tracking, and testing best practices.
You'll create a functional Express SMS server with a REST API endpoint that accepts a recipient phone number and message text, then delivers SMS messages reliably using the Vonage API. This Node.js SMS integration works for notifications, alerts, appointment reminders, or two-factor authentication (though Vonage's Verify API is purpose-built for 2FA workflows).
This tutorial uses Vonage's official Node.js SDK (@vonage/server-sdk) with comprehensive error handling for delivery receipts (DLRs) and message status tracking.
Current Versions (as of 2024–2025):
Project Overview: Building a Vonage SMS API Integration
What You'll Build:
A Node.js Express server with a single API endpoint (
POST /send-sms). This endpoint receives a destination phone number and text message body, then uses the Vonage Node.js SDK to send SMS messages programmatically.Problem Solved:
Integrate SMS sending capabilities into Node.js applications quickly and reliably using Vonage's enterprise-grade communication platform.
Technologies Used:
.envintoprocess.env, keeping credentials secureSystem Architecture:
POSTrequest to the/send-smsendpoint.Prerequisites: What You Need to Send SMS with Vonage
Prerequisites:
Numbers>Buy numbersin the Vonage Dashboard. Ensure the number supports SMS in your target regionStep 1: Set Up Your Vonage Node.js SMS Project
Initialize your Node.js project and install the necessary dependencies.
Create a Project Directory:
mkdir vonage-sms-guide cd vonage-sms-guideInitialize the Node.js Project: Create a
package.jsonfile. The-yflag accepts default settings.Install Dependencies: Install
express,@vonage/server-sdk, anddotenv.Create Core Files:
# On macOS/Linux touch index.js .env .gitignore # On Windows (Command Prompt) type nul > index.js type nul > .env type nul > .gitignore # On Windows (PowerShell) New-Item index.js -ItemType File New-Item .env -ItemType File New-Item .gitignore -ItemType FileConfigure Environment Variables (
.env): Open.envand add your Vonage API credentials and rented number.VONAGE_API_KEY: Your API key from the Vonage DashboardVONAGE_API_SECRET: Your API secret from the Vonage DashboardVONAGE_FROM_NUMBER: Your virtual phone number in E.164 format without spaces (e.g.,14155550100)PORT: The port your Express server listens on (e.g.,3000)Important: Replace placeholder values with your actual credentials.
Configure Git Ignore (
.gitignore): Prevent committing sensitive environment variables andnode_modules.Your project structure:
Step 2: Implement Vonage SMS API with Node.js and Express
Write the code for your Express server in
index.js.Require Dependencies and Load Environment Variables:
// index.js const express = require('express'); const { Vonage } = require('@vonage/server-sdk'); require('dotenv').config(); // Check if essential environment variables are set if (!process.env.VONAGE_API_KEY || !process.env.VONAGE_API_SECRET || !process.env.VONAGE_FROM_NUMBER) { console.error('Error: Missing Vonage API credentials or FROM number in .env file.'); process.exit(1); }Why
dotenv.config()first? It must run before accessingprocess.envvariables from.env. The code checks that critical variables load successfully.Initialize Express App and Vonage Client: Create Express and Vonage SDK instances using environment variables.
// index.js (continued) const app = express(); const port = process.env.PORT || 3000; const vonage = new Vonage({ apiKey: process.env.VONAGE_API_KEY, apiSecret: process.env.VONAGE_API_SECRET });Add Middleware: Configure Express to parse JSON request bodies.
// index.js (continued) app.use(express.json()); app.use(express.urlencoded({ extended: true }));Create the SMS Sending Endpoint (
/send-sms): Define aPOSTroute to handle SMS sending requests.// index.js (continued) app.post('/send-sms', async (req, res) => { // Basic input validation const { to, text } = req.body; if (!to || !text) { return res.status(400).json({ success: false, message: 'Missing `to` or `text` parameter in request body.' }); } const from = process.env.VONAGE_FROM_NUMBER; try { const resp = await vonage.sms.send({ to, from, text }); console.log('Message sent successfully:', resp); // Status '0' indicates successful submission to the Vonage network, not delivery to the handset. // DLR statuses include: DELIVRD (delivered), UNDELIV (undelivered), EXPIRED, FAILED, REJECTD, DELETED, UNKNOWN. if (resp.messages && resp.messages.length > 0 && resp.messages[0].status === '0') { res.status(200).json({ success: true, message: 'SMS submitted successfully.', messageId: resp.messages[0]['message-id'] }); } else { console.error('Vonage API reported an issue:', resp); const errorText = (resp.messages && resp.messages.length > 0) ? resp.messages[0]['error-text'] : 'Unknown Vonage API error'; res.status(500).json({ success: false, message: `Failed to send SMS. Vonage error: ${errorText}`, details: resp }); } } catch (error) { console.error('Error sending SMS:', error); res.status(500).json({ success: false, message: 'Internal server error while sending SMS.', error: error.message }); } });Key Points:
asyncfunction to useawaitfor the asynchronousvonage.sms.sendcall.toandtextare present in the request body.fromnumber from environment variables.vonage.sms.send({ to, from, text })makes the API call.try...catchblock handles potential network errors or issues within the SDK call.respobject from Vonage. Astatusof'0'indicates successful submission to the network. Non-zero statuses indicate errors (e.g., invalid number, insufficient funds). Return the Vonagemessage-idon success.Start the Server: Make the Express application listen for incoming requests on the configured port.
// index.js (continued) app.listen(port, () => { console.log(`Server listening at http://localhost:${port}`); console.log(`SMS sending endpoint available at POST http://localhost:${port}/send-sms`); });Your
index.jsfile is now complete.Step 3: Test Your Vonage SMS Integration
Run the server and test the SMS sending functionality.
Run the Server: Open your terminal in the project directory and run:
You should see output indicating the server is running:
Test with
curlor Postman: Usecurl(command-line) or Postman (GUI) to send aPOSTrequest to your endpoint.Using
curl: ReplaceYOUR_RECIPIENT_NUMBERwith the phone number you want to send the SMS to (use a verified number for trial accounts). Format the number including the country code (e.g.,14155550123).curl -X POST http://localhost:3000/send-sms \ -H 'Content-Type: application/json' \ -d '{ "to": "YOUR_RECIPIENT_NUMBER", "text": "Hello from your Vonage Node.js App!" }'Using Postman:
Create a new request.
Set the method to
POST.Enter the URL:
http://localhost:3000/send-sms.Go to the
Bodytab, selectraw, and chooseJSONfrom the dropdown.Enter the JSON payload:
{ "to": "YOUR_RECIPIENT_NUMBER", "text": "Hello from your Vonage Node.js App!" }Click
Send.Check the Response:
Successful Submission: You should receive a JSON response with a
200 OKstatus:{ "success": true, "message": "SMS submitted successfully.", "messageId": "some-message-id-from-vonage" }Check the recipient phone – the SMS should arrive shortly. You should also see confirmation logs in the terminal where
node index.jsis running.Error Response: If something goes wrong (e.g., invalid credentials, incorrect 'to' number format, trial account restrictions), you'll get an error response with a non-200 status code:
// Example: Missing parameter { "success": false, "message": "Missing `to` or `text` parameter in request body." }// Example: Vonage API error (e.g., non-whitelisted number) { "success": false, "message": "Failed to send SMS. Vonage error: Non White-listed Destination - rejected", "details": { /* ... full Vonage response ... */ } }// Example: Internal server error { "success": false, "message": "Internal server error while sending SMS.", "error": "Some specific error message" }Check the terminal logs for more detailed error information.
Step 4: Handle Vonage SMS API Errors and Delivery Receipts
Your current implementation includes basic
try...catchblocks and logs errors to the console. For production systems, implement:WinstonorPinofor structured logging (e.g., JSON format), which makes logs easier to parse and analyze, especially when sending them to log aggregation services (like Datadog, Splunk, ELK stack).console.log.error-textor status fields) to provide more informative feedback or trigger specific actions (e.g., retry logic for temporary network issues, alerts for authentication failures). Common error codes include:Step 5: Secure Your Vonage API Credentials
.envfile or hardcode API keys/secrets directly in your source code. Use environment variables and ensure.envis in your.gitignore. In production environments, use your hosting provider's mechanism for managing secrets (e.g., AWS Secrets Manager, Heroku Config Vars, Kubernetes Secrets).tophone number (e.g., check format using a library likelibphonenumber-jsversion 1.11+ with metadata synced to September 2025, ~145 KB max metadata) and sanitize thetextinput to prevent potential injection attacks if the text is ever displayed elsewhere.express-rate-limit). This prevents users from sending excessive numbers of messages rapidly.Step 6: Troubleshoot Common Vonage SMS API Issues
VONAGE_API_KEYandVONAGE_API_SECRETin your.envfile are correct and have no extra spaces.FROMNumberVONAGE_FROM_NUMBERis a valid number you rented from Vonage in the correct format (e.g.,14155550100).@vonage/server-sdkis stable, always refer to the official Vonage documentation for the latest methods and response structures.vonage.sms.send(). For multi-channel messaging (WhatsApp, Facebook Messenger, MMS) or advanced features, explore the Vonage Messages API withvonage.messages.send().Step 7: Deploy Your Vonage Node.js SMS Application
Deploy this application on a server or platform (like Heroku, Render, AWS EC2, Google Cloud Run, etc.). Key steps include:
VONAGE_API_KEY,VONAGE_API_SECRET, andVONAGE_FROM_NUMBERas environment variables on your chosen hosting platform. Do not upload the.envfile.npm installruns in the deployment environment to install dependencies.node index.js.PORTenvironment variable, which your code already handles).A
Procfilefor platforms like Heroku:Complete Vonage SMS Code Example
The complete code for this guide includes
index.js,package.json,.gitignore, and a.env.examplefile.Frequently Asked Questions About Vonage SMS with Node.js
How do I send SMS with Vonage in Node.js?
Install
@vonage/server-sdk(version 3.24.1 for 2025) and create a Vonage client with your API key and secret. Usevonage.sms.send({ to, from, text })to send messages. You need a Vonage account, API credentials, and a rented virtual number. The complete setup requires Express for the REST endpoint, dotenv for credential management, and proper error handling for production use.What does Vonage status code 0 mean?
Status code '0' indicates successful submission to the Vonage network, not delivery to the recipient's handset. To confirm actual delivery, implement webhook endpoints to receive Delivery Receipts (DLRs) from Vonage. DLR statuses include: DELIVRD (delivered), UNDELIV (undelivered), EXPIRED, FAILED, REJECTD, DELETED, and UNKNOWN.
What is Vonage Error Code 15?
Error Code 15 (Rejection Code 10 for SMPP) means "Illegal Sender" – this occurs when sending SMS to the US or Canada without a US pre-approved long number, toll-free, 10DLC, or short code associated with your Vonage account. To resolve this, obtain the appropriate number type for US/Canada SMS delivery through your Vonage Dashboard.
What is Vonage Error Code 99?
Error Code 99 indicates a "General Error" – meaning the request was processed but failed due to various factors. Check the Delivery Receipt (DLR) details for specifics about why the message failed. This error requires examining the
error-textfield in the response and consulting the Vonage SMS API error documentation for detailed troubleshooting.What version of @vonage/server-sdk should I use in 2025?
Use
@vonage/server-sdkversion 3.24.1 (latest as of early 2025) with Node.js v22 LTS and Express 5.1.0. Install withnpm install @vonage/server-sdk@3.24.1. This version provides stable SMS API functionality with improved error handling. Always check npm for the latest version.How do I handle the "Non-Whitelisted Destination" error?
This is the most common error for Vonage trial accounts. Trial accounts can only send SMS to verified numbers. Add and verify recipient numbers in your Vonage Sandbox / Test Numbers page. To send to any number, upgrade your account by adding payment details in the Vonage Dashboard.
What are Delivery Receipts (DLRs) in Vonage SMS?
Delivery Receipts (DLRs) are webhook notifications from Vonage confirming whether your SMS was delivered to the recipient's handset. DLRs provide statuses like DELIVRD (delivered), UNDELIV (undelivered), EXPIRED, FAILED, REJECTD, DELETED, or UNKNOWN. Implement a webhook endpoint to receive DLRs for reliable message tracking. See the DLR Status documentation.
Should I use Vonage SMS API or Messages API?
For simple SMS sending with Node.js Express, use the SMS API via
vonage.sms.send()with API Key/Secret authentication (covered in this guide). For multi-channel messaging (WhatsApp, Facebook Messenger, MMS) or advanced features, use the Vonage Messages API withvonage.messages.send(), which requires Application ID and Private Key authentication.How do I validate phone numbers before sending SMS with Vonage?
Use
libphonenumber-jsversion 1.11+ (with metadata synced to September 2025, ~145 KB max metadata) to validate phone number format before calling the Vonage API. Install withnpm install libphonenumber-jsand parse numbers to E.164 format. This prevents API errors from invalid phone numbers and improves delivery rates.Can I send SMS from a Vonage trial account?
Yes, but with restrictions. Trial accounts receive free testing credit but can only send SMS to verified numbers added in the Sandbox / Test Numbers page. Upgrade your account (add payment details) to send SMS to any number. Trial accounts are perfect for development and testing before production deployment.
Next Steps: Enhancing Your Vonage SMS Integration
You've successfully built a Node.js application capable of sending SMS messages using Express and the Vonage API.
From here, you could: