code examples

Sent logo
Sent TeamMay 3, 2025 / code examples / Article

Send SMS with Node.js and Vonage Messages API: Complete Tutorial 2025

Complete guide to sending SMS messages using Node.js, Express, and Vonage Messages API. Step-by-step tutorial with authentication, error handling, code examples, and production deployment best practices.

Send SMS with Node.js, Express, and Vonage Messages API

Build a production-ready Node.js application using Express to send SMS messages via the Vonage Messages API. This comprehensive tutorial covers initial project setup, authentication, API integration, error handling, testing, and production deployment.

Learn how to build a REST API endpoint that accepts a phone number and message, then sends SMS messages programmatically using the Vonage Node.js SDK. Perfect for adding SMS notifications, alerts, two-way messaging, and automated communication to your web applications.

Project Overview and Goals

Goal: Create a reliable backend service capable of sending SMS messages programmatically using Node.js and the Vonage Messages API.

Problem Solved: Automate SMS notifications, two-factor authentication (2FA), order confirmations, appointment reminders, marketing campaigns, and alerts from your web application or backend system.

Technologies Used:

  • Node.js: JavaScript runtime for server-side applications. Provides asynchronous processing, extensive npm ecosystem, and excellent I/O performance for API interactions. Requires Node.js v18 or later (Node.js v18 reaches end-of-life on April 30, 2025 – use v20 LTS or v22 LTS for production).
  • Express: Minimal and flexible Node.js web framework. Simplifies route setup and HTTP request handling for API development. This guide uses Express v4.x (Express v5 stabilized in October 2024 with improved async/await error handling and security features, but v4.x remains fully supported).
  • Vonage Messages API: Multichannel messaging API supporting SMS, MMS, WhatsApp, RCS, and more. This guide focuses on SMS. Offers global reach, reliability, and developer-friendly SDK.
  • @vonage/server-sdk: Official Vonage Node.js SDK for interacting with Vonage APIs (current version: v3.24.1 as of October 2025).
  • dotenv: Loads environment variables from .env files into process.env. Essential for secure credential management.

Prerequisites:

  • Node.js and npm (or yarn): Install from nodejs.org. Minimum version: Node.js v18 (recommend v20 LTS or v22 LTS)
  • Vonage API Account: Sign up for a free Vonage account to receive testing credits
  • Vonage Phone Number: Rent a phone number from the Vonage dashboard as your SMS sender ID
  • Basic JavaScript and Node.js knowledge: Understanding of async/await and Express.js fundamentals
  • Text editor (VS Code recommended)
  • HTTP request tool (curl or Postman for API testing)

Final Outcome: A production-ready Node.js Express server with a POST /send-sms REST API endpoint that sends SMS messages programmatically via the Vonage Messages API with proper authentication, validation, and error handling.

1. Node.js Project Setup for Vonage SMS Integration

Initialize your Node.js project and install required dependencies including Express, the Vonage SDK, and environment configuration tools.

  1. Create a Project Directory: Open your terminal and create a new project directory:

    bash
    mkdir vonage-sms-sender
    cd vonage-sms-sender
  2. Initialize the Node.js Project: Create a package.json file to track project details and dependencies:

    bash
    npm init -y
  3. Install Dependencies: Install Express for the web server, the Vonage SDK for API interaction, and dotenv for environment variable management:

    bash
    npm install express @vonage/server-sdk dotenv
    • express: Web framework
    • @vonage/server-sdk: Vonage library
    • dotenv: Environment variable loader
  4. Create Project Files: Create the main application file and environment variables file:

    bash
    touch index.js .env .gitignore
    • index.js: Main application code
    • .env: Stores sensitive credentials (API keys, phone numbers). Never commit this file to Git.
    • .gitignore: Specifies files Git should ignore
  5. Configure .gitignore: Prevent committing dependencies and secrets by adding them to .gitignore:

    text
    # .gitignore
    
    node_modules
    .env
    private.key
    *.log

    This prevents accidental exposure of sensitive data (API secrets in .env or the private key) and avoids repository bloat from node_modules.

  6. Add a Start Script: Open package.json and add a start script under scripts:

    json
    // package.json (partial view)
    {
      "name": "vonage-sms-sender",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "start": "node index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "@vonage/server-sdk": "^3.x.x",
        "dotenv": "^16.x.x",
        "express": "^4.x.x"
      }
    }

    Run npm start to launch your application.

2. Vonage API Authentication and Configuration

Configure your Vonage API account and obtain authentication credentials. The Vonage Messages API uses Application ID and Private Key authentication for secure API access.

  1. Log in to Vonage: Go to the Vonage API Dashboard.

  2. Set Default SMS API:

    • Navigate to API Settings in the left-hand menu.
    • Find the Default SMS Setting section.
    • Select Messages API. This setting is required for the Messages API SDK. The older SMS API SDK (vonage.message.sendSms) requires SMS API instead.
    • Click Save changes.
  3. Create a Vonage Application: Vonage Applications contain your communication settings and credentials.

    • Navigate to ApplicationsCreate a new application.
    • Name your application (e.g., My Node SMS Sender).
    • Click Generate public and private key. This downloads a private.key file. Save this file securely in your project root directory (vonage-sms-sender). Your .gitignore prevents committing it to version control.
    • Enable the Messages capability. Enter placeholder URLs for Inbound URL and Status URL (e.g., https://example.com/webhooks/inbound and https://example.com/webhooks/status). Update these with real endpoints when you need to receive SMS or delivery receipts.
    • Click Generate new application.
  4. Note Your Application ID: After creation, note the Application ID displayed on the application page.

  5. Link Your Vonage Number:

    • On the application page, scroll to Link virtual numbers.
    • Find your Vonage virtual number and click Link. This becomes your FROM number for sending SMS. If you need a number, go to NumbersBuy numbers.
  6. Configure Environment Variables: Open the .env file and add your Vonage credentials and sender number. Replace the placeholder values with your actual Application ID, the path to your downloaded private key file, and your linked Vonage number.

    Important: Vonage API E.164 Format Requirements – Unlike standard E.164 notation which includes a leading '+', Vonage APIs require phone numbers with NO leading '+' or '00' prefix. Numbers should start directly with the country code (e.g., 12015550123 not +12015550123). Maximum length is 15 digits.

    dotenv
    # .env
    
    # Vonage Credentials (Messages API)
    VONAGE_APPLICATION_ID=YOUR_APPLICATION_ID
    VONAGE_PRIVATE_KEY_PATH=./private.key
    
    # Vonage Number (Sender ID) - Vonage-specific E.164 format (NO leading '+')
    VONAGE_FROM_NUMBER=YOUR_VONAGE_NUMBER
    
    # Server Port
    PORT=3000
    • VONAGE_APPLICATION_ID: ID of the Vonage application you created
    • VONAGE_PRIVATE_KEY_PATH: Relative or absolute path to private.key (./ private.key assumes it's in the same directory as index.js)
    • VONAGE_FROM_NUMBER: Vonage virtual number linked to the application. Important: Use Vonage's E.164 format WITHOUT the leading '+' (e.g., 12015550123 for a US number)
    • PORT: Port your Express server will listen on

3. Implementing SMS Sending with Vonage Node.js SDK

Initialize the Vonage Node.js SDK and create a reusable SMS sending function with proper error handling and phone number validation.

Edit your index.js file:

javascript
// index.js
require('dotenv').config(); // Load environment variables from .env file
const express = require('express');
const { Vonage } = require('@vonage/server-sdk');
const path = require('path');

// --- Vonage Initialization ---
// Validate essential environment variables
if (!process.env.VONAGE_APPLICATION_ID || !process.env.VONAGE_PRIVATE_KEY_PATH || !process.env.VONAGE_FROM_NUMBER) {
    console.error("Error: Missing Vonage credentials in .env file. Check VONAGE_APPLICATION_ID, VONAGE_PRIVATE_KEY_PATH, and VONAGE_FROM_NUMBER.");
    process.exit(1);
}

// Resolve the private key path relative to the current working directory
const privateKeyPath = path.resolve(process.env.VONAGE_PRIVATE_KEY_PATH);

const vonage = new Vonage({
    applicationId: process.env.VONAGE_APPLICATION_ID,
    privateKey: privateKeyPath
});

// --- SMS Sending Function ---
async function sendSms(to, text) {
    const from = process.env.VONAGE_FROM_NUMBER;

    // Basic input validation
    if (!to || !text) {
        throw new Error("Recipient phone number ('to') and message text ('text') are required.");
    }
    // Vonage E.164 validation: NO leading '+' or '00', must start with country code (1-9), max 15 digits total
    // See: https://api.support.vonage.com/hc/en-us/articles/206515367
    if (!/^[1-9]\d{1,14}$/.test(to)) {
         throw new Error("Invalid recipient phone number format. Use Vonage E.164 format: country code + number, NO '+' prefix (e.g., 12015550123), max 15 digits.");
    }

    try {
        console.log(`Attempting to send SMS from ${from} to ${to}`);
        const resp = await vonage.messages.send({
            channel: 'sms',
            message_type: 'text',
            to: to,
            from: from,
            text: text
        });
        console.log('Message sent successfully:', resp);
        return resp;
    } catch (err) {
        console.error('Error sending SMS via Vonage:', err);
        // Log specific Vonage error details if available
        if (err.response && err.response.data) {
            console.error('Vonage API Error Details:', JSON.stringify(err.response.data, null, 2));
        }
        throw new Error(`Failed to send SMS: ${err.message}`);
    }
}

// --- Express Server Setup ---
const app = express();
const port = process.env.PORT || 3000;

// Middleware to parse JSON request bodies
app.use(express.json());
// Middleware to parse URL-encoded request bodies
app.use(express.urlencoded({ extended: true }));

// --- API Endpoint ---
// Defined in the next section

// --- Start Server ---
app.listen(port, () => {
    console.log(`Server listening at http://localhost:${port}`);
    console.log(`SMS Sender Number: ${process.env.VONAGE_FROM_NUMBER}`);
});

// --- Export for potential testing ---
module.exports = { app, sendSms };

Explanation:

  1. require('dotenv').config();: Loads variables from .env into process.env. Call this before accessing process.env variables.
  2. Imports: Import express, the Vonage class from the SDK, and Node's built-in path module.
  3. Credential Validation: Check that critical environment variables exist to prevent runtime errors from missing configuration.
  4. path.resolve: Get the absolute path to the private key for robust script execution regardless of the working directory.
  5. new Vonage(...): Initialize the Vonage client with your Application ID and private key file path (the SDK reads the file content).
  6. sendSms(to, text) Function:
    • Takes the recipient number (to) and the message text as arguments.
    • Retrieves the from number from environment variables.
    • Validates the presence and format of the to number.
    • Uses vonage.messages.send({...}) for the Messages API.
    • Specifies channel: 'sms' and message_type: 'text'.
    • Includes try...catch for robust error handling during the API call.
    • Logs success (resp.message_uuid) or detailed error information.
    • Re-throws errors so calling code (our API route) can handle them.
  7. Express Setup: Standard setup for an Express application, including middleware to parse incoming JSON and URL-encoded data.
  8. Server Start: Starts the Express server listening on the specified port.

4. Create Express API Endpoint for SMS Requests

Create an Express POST endpoint that receives HTTP requests with recipient phone numbers and messages, then triggers SMS sending via the Vonage API.

Add the following code to index.js, just before the app.listen call:

javascript
// index.js (continued)

// --- API Endpoint ---
app.post('/send-sms', async (req, res) => {
    // Extract recipient number and message from request body
    const { to, message } = req.body;

    // Input Validation (Basic)
    if (!to || !message) {
        console.error("Validation Error: 'to' and 'message' fields are required in the request body.");
        return res.status(400).json({
            success: false,
            error: "Bad Request: Both 'to' (recipient phone number) and 'message' (text content) are required."
        });
    }

    try {
        // Call the SMS sending function
        const result = await sendSms(to, message);
        // Respond with success and the message UUID
        res.status(200).json({
            success: true,
            message: "SMS sent successfully.",
            messageId: result.message_uuid
        });
    } catch (error) {
        // Log the specific error encountered during sending
        console.error(`API Error: Failed to process /send-sms request for recipient ${to}:`, error.message);
        // Respond with a server error status
        res.status(500).json({
            success: false,
            error: `Internal Server Error: Could not send SMS. ${error.message}`
        });
    }
});

// --- Error Handling Middleware (Optional but Recommended) ---
// Catch-all for unhandled errors
app.use((err, req, res, next) => {
  console.error("Unhandled Error:", err.stack);
  res.status(500).json({
      success: false,
      error: "Internal Server Error: An unexpected error occurred."
  });
});

// --- Start Server ---
// (app.listen call remains here)

Explanation:

  1. app.post('/send-sms', ...): Defines a route that listens for HTTP POST requests on the /send-sms path.
  2. async (req, res) => {...}: Uses an async function to allow await when calling sendSms.
  3. const { to, message } = req.body;: Extracts the to (recipient number) and message (SMS text) from the JSON payload of the incoming request.
  4. Input Validation: Checks if to and message are present in the request body. If not, sends a 400 Bad Request response.
  5. try...catch Block: Wraps the call to sendSms.
    • On Success: Calls sendSms. If successful, sends a 200 OK response back to the client, including the message_uuid returned by Vonage.
    • On Failure: If sendSms throws an error (either input validation within sendSms or an API error from Vonage), the catch block executes. It logs the error server-side and sends a 500 Internal Server Error response to the client, including a generic error message and the specific error from sendSms for context.
  6. Error Handling Middleware: A final app.use middleware is added after all routes. This acts as a global error handler for any errors that weren't caught by specific route handlers. It's good practice for catching unexpected issues.

5. Error Handling and Logging Best Practices for SMS APIs

Implement robust error handling and logging for your SMS API to catch validation errors, API failures, and authentication issues:

  • Input Validation: Both the route handler and sendSms function check for required inputs (to, message).
  • API Call Errors: The try...catch block in sendSms specifically handles errors during the vonage.messages.send call. It logs detailed error information from Vonage if available (err.response.data).
  • Route Level Errors: The try...catch block in the /send-sms route handler catches errors from sendSms and sends appropriate HTTP status codes (400 for bad input, 500 for server/API errors).
  • Logging: console.log for informational messages (server start, attempt to send) and console.error for logging validation failures and API errors.

Production Improvements:

ImprovementDescriptionLibrary/Tool
Structured LoggingUse JSON logs with different log levels (debug, info, warn, error) and route logs to files or external serviceswinston or pino
Centralized Error TrackingAggregate and monitor errors in productionSentry or Datadog
Retry MechanismsImplement exponential backoff for transient network issuesasync-retry

6. Security Best Practices for SMS APIs

Implement essential security measures when handling API credentials and sending SMS messages to prevent unauthorized access and abuse.

  • Credential Management:
    • .env File: Store secrets in .env to keep them out of source code.
    • .gitignore: Ensure .env and private.key are never committed to version control.
    • Environment Variables in Deployment: In production environments (Heroku, AWS, Docker), use the platform's mechanism for securely managing environment variables rather than deploying the .env file.
  • Input Validation and Sanitization:
    • Basic validation for the presence of to and message.
    • The sendSms function checks the format of the to number using a regular expression. More robust validation (e.g., using libphonenumber-js) could ensure it's a valid E.164 number.
    • SMS content is often plain text. If displaying user-provided content elsewhere, ensure proper sanitization (e.g., using libraries like dompurify if rendering in HTML) to prevent XSS attacks.
  • Rate Limiting: Implement rate limiting to prevent abuse of your SMS endpoint. Use express-rate-limit:
    bash
    npm install express-rate-limit
    javascript
    // index.js (add near the top imports)
    const rateLimit = require('express-rate-limit');
    
    // ... (after app = express()) ...
    
    // Apply rate limiting to the SMS endpoint
    const smsLimiter = rateLimit({
        windowMs: 15 * 60 * 1000, // 15 minutes
        max: 10, // Limit each IP to 10 requests per windowMs
        message: { success: false, error: 'Too many SMS requests from this IP. Try again after 15 minutes.' },
        standardHeaders: true,
        legacyHeaders: false,
    });
    
    app.use('/send-sms', smsLimiter);
    
    // ... (rest of the code)
  • Authentication/Authorization: For production, protect the /send-sms endpoint. Only authenticated and authorized users/systems should trigger SMS sending. This typically involves middleware checking for API keys, JWT tokens, or session cookies. Learn more about implementing API authentication with Node.js and Express.

7. Common Issues and Troubleshooting Guide for Vonage SMS API

  1. Error: Failed to send SMS: Missing Vonage credentials...

    • Cause: One or more of VONAGE_APPLICATION_ID, VONAGE_PRIVATE_KEY_PATH, or VONAGE_FROM_NUMBER are missing or empty in your .env file or environment variables.
    • Solution: Ensure all required variables are correctly set in .env and that require('dotenv').config(); is called at the very top of index.js. Verify the variable names match exactly.
  2. Error: ENOENT: no such file or directory, open '.../private.key'

    • Cause: The path specified in VONAGE_PRIVATE_KEY_PATH is incorrect, the private.key file doesn't exist at that location, or the file lacks read permissions.
    • Solution: Double-check the path in .env. Ensure the private.key file is in the correct directory (usually the project root). Using path.resolve() helps, but the initial path in .env still needs to be correct relative to the project root. Verify file permissions allow the Node.js process to read the key.
  3. Error: Failed to send SMS: Forbidden

    • Cause: Authentication failed. The VONAGE_APPLICATION_ID is incorrect, or the private.key content doesn't match the public key associated with that Application ID in the Vonage dashboard. Could also happen if the linked VONAGE_FROM_NUMBER isn't properly associated with the Application ID.
    • Solution: Verify the Application ID in .env. Ensure you are using the correct private.key file for this specific Vonage Application. Re-check that the FROM number is correctly linked to the application in the Vonage dashboard.
  4. Error: Failed to send SMS: ... Non-Whitelisted Destination ...

    • Cause: You are using a Vonage trial account. Trial accounts can only send SMS messages to phone numbers added to your "test numbers" list in the dashboard.
    • Solution:
      • Go to the Vonage Dashboard.
      • Navigate to AccountTest numbers.
      • Add the recipient phone number you want to send messages to. Verify it via SMS or voice call from Vonage.
      • Alternatively, upgrade your Vonage account by adding payment details.
  5. Error: Failed to send SMS: Invalid Sender or Illegal Sender Address

    • Cause: The VONAGE_FROM_NUMBER in your .env file is either not a valid Vonage number you own, not linked to the Vonage Application being used, or not in the correct E.164 format.
    • Solution: Verify the VONAGE_FROM_NUMBER in .env matches a number you have rented in the Vonage dashboard, is linked to the correct Vonage Application, and uses the E.164 format without '+'.
  6. Messages API vs. SMS API Configuration:

    • Caveat: The Vonage SDK has methods for both the older SMS API (vonage.message.sendSms) and the newer Messages API (vonage.messages.send). This guide uses the Messages API.
    • Requirement: Ensure your Vonage account's Default SMS Setting (in API Settings) is set to Messages API. If it's set to SMS API, calls using vonage.messages.send might fail or behave unexpectedly. Authentication also differs (API Key/Secret for SMS API vs. App ID/Private Key for Messages API).
  7. Rate Limits (Vonage Side): Vonage applies its own rate limits to API requests. If you send too many messages too quickly, you might receive 429 Too Many Requests errors. Check Vonage documentation for current limits.

8. Production Deployment and CI/CD Pipeline Setup

Deploy your Node.js SMS application to production environments using modern hosting platforms and automated CI/CD pipelines.

  1. Environment Configuration:

    • DO NOT deploy your .env file or private.key file directly.
    • Use your hosting provider's mechanism for setting environment variables (e.g., Heroku Config Vars, AWS Secrets Manager, Docker environment variables). Set VONAGE_APPLICATION_ID, VONAGE_FROM_NUMBER, PORT, and handle the private key securely.
    • Handling the Private Key: Since the key is multi-line, storing it directly in a standard environment variable can be problematic. Common approaches:
      • Base64 Encoding: Encode the key into a single line string (e.g., on Linux/macOS: base64 -w 0 private.key). Store this string in an environment variable (e.g., VONAGE_PRIVATE_KEY_BASE64). Your application or deployment script would then decode this string back into the multi-line key format.
      • Secure File Copy: Securely copy the private.key file to the deployment environment during the build/deploy process. Ensure the path specified by VONAGE_PRIVATE_KEY_PATH points to this location.
      • Secrets Management Services: Use dedicated secrets management tools (AWS Secrets Manager, HashiCorp Vault, Google Secret Manager) which have better support for multi-line secrets. Your application would fetch the secret from the service at runtime.
  2. Hosting Platforms:

    • PaaS (Platform-as-a-Service): Heroku, Render, Fly.io simplify deployment. Push your code via Git, and the platform builds and runs it. Configure environment variables through their dashboard/CLI.
    • Containers: Dockerize your application. Create a Dockerfile to define the image, copy your code (excluding .env/private.key), install dependencies, and define the start command (CMD ["npm", "start"]). Deploy the container to services like AWS ECS, Google Cloud Run, or Kubernetes. Environment variables are injected into the container.
    • Serverless: AWS Lambda, Google Cloud Functions. Adapt the Express app using frameworks like Serverless Framework or directly handle API Gateway events, initializing the Vonage client within the function handler. Environment variables are configured per function.
  3. CI/CD Pipeline (e.g., GitHub Actions, GitLab CI):

    • Automate testing, building, and deployment.
    • Steps: Checkout code → Install dependencies → Run tests → Build Docker image (if applicable) → Push image to registry → Deploy to hosting environment (using CLI tools like heroku, aws, gcloud, kubectl).
    • Securely inject secrets (like Vonage credentials) into the CI/CD environment using repository/organization secrets, not hardcoded in the pipeline definition.
  4. Process Management: Use a process manager like pm2 in VM/container deployments to keep your Node.js application running, manage logs, and handle restarts.

9. Testing Your Vonage SMS Integration

Test your SMS API endpoint using curl, Postman, or automated testing frameworks to verify message delivery and error handling.

  1. Start the Server: Ensure your .env file is correctly configured. Open your terminal in the project directory.

    bash
    npm start

    You should see:

    Server listening at http://localhost:3000 SMS Sender Number: 12015550123 (Your Vonage Number)
  2. Send a Test Request (using curl): Open a new terminal window. Replace 1YYYYYYYYYY with a valid recipient phone number in Vonage E.164 format (NO '+' prefix – remember whitelisting for trial accounts!) and adjust the message text.

    Important: Use the number format 1YYYYYYYYYY (for US numbers) or appropriate country code + number, NOT +1YYYYYYYYYY.

    bash
    curl -X POST http://localhost:3000/send-sms \
         -H "Content-Type: application/json" \
         -d '{
               "to": "1YYYYYYYYYY",
               "message": "Hello from my Node.js Vonage app!"
             }'
  3. Check the Response:

    • Success: You should receive a JSON response like this in the terminal where you ran curl, and the server log should show "Message sent successfully":
      json
      {
        "success": true,
        "message": "SMS sent successfully.",
        "messageId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
      }
    • Failure: If there's an error (e.g., missing field, invalid number, Vonage API issue), you'll get a different JSON response, likely with success: false and an error message. Check the server logs (npm start terminal) for more detailed error information.
  4. Verify SMS Reception: Check the recipient phone. You should receive the SMS message shortly. Delivery times can vary.

  5. Test Edge Cases:

    • Send request without to or message.
    • Send request with an invalid to number format.
    • If using a trial account, try sending to a non-whitelisted number to see the error.
  6. Automated Testing (Conceptual):

    • Unit Tests: Use frameworks like Jest or Mocha/Chai to test the sendSms function in isolation. Mock the @vonage/server-sdk to simulate successful and failed API calls without actually sending SMS messages or needing real credentials.
    • Integration Tests: Use libraries like supertest to make HTTP requests to your running Express application. Test the /send-sms endpoint's behavior, including validation and responses for success/error cases. Mock the Vonage SDK interaction during these tests.

Frequently Asked Questions About Sending SMS with Node.js and Vonage

How do I send SMS messages using Node.js and Vonage?

Install the @vonage/server-sdk package, create a Vonage application with Messages API enabled, initialize the Vonage client with your Application ID and private key, then use vonage.messages.send() with channel set to 'sms'. The complete process requires setting up environment variables, validating phone numbers in E.164 format (without '+' prefix for Vonage), and handling API responses with proper error handling.

What is the difference between Vonage Messages API and SMS API?

Vonage Messages API is the newer, more versatile API supporting SMS, MMS, WhatsApp, RCS, and other channels through a unified interface. It requires Application ID and private key authentication. The older SMS API only handles SMS/MMS and uses API Key/Secret authentication. For new projects, Vonage recommends the Messages API for better scalability and multi-channel support.

What Node.js version is required for Vonage Node.js SDK?

The Vonage Node.js SDK (v3.24.1) requires Node.js v18 or later. Node.js v18 reaches end-of-life on April 30, 2025. For production deployments, use Node.js v20 LTS (Maintenance) or v22 LTS (Active) to ensure continued security updates and long-term support.

Why does Vonage require phone numbers without the '+' prefix?

Vonage APIs require E.164 formatted phone numbers WITHOUT the leading '+' or '00' prefix, unlike standard E.164 notation. Numbers must start directly with the country code (e.g., 12015550123 for US numbers, not +12015550123). This is a Vonage-specific requirement documented in their API specifications. Including the '+' causes API errors.

How do I handle Vonage API errors in Node.js?

Handle Vonage API errors using try-catch blocks around vonage.messages.send() calls. Check err.response.data for detailed error information including error codes. Common errors include: 403 Forbidden (invalid credentials), 400 Bad Request (invalid phone format), and 429 Too Many Requests (rate limiting). Log errors with correlation IDs and return appropriate HTTP status codes (400 for validation errors, 500 for server errors).

Can I test Vonage SMS without sending real messages?

Vonage trial accounts restrict SMS sending to whitelisted test numbers that you verify in the dashboard under Account → Test numbers. For development testing without real SMS, implement a development mode check (NODE_ENV=development) that returns mock responses instead of calling the Vonage API. Always test production flows with real SMS to verify carrier compatibility.

How much does it cost to send SMS with Vonage?

Vonage SMS pricing varies by destination country, typically ranging from $0.0045 to $0.15 per message. US and Canada messages cost approximately $0.0075 per SMS. New accounts receive free trial credits for testing. Check the Vonage pricing page for specific rates by country, and monitor your usage in the Vonage dashboard to avoid unexpected charges.

What is the rate limit for Vonage Messages API?

Vonage applies rate limits based on your account tier, typically 10 – 20 requests per second for standard accounts. Enterprise accounts can request higher limits. When you exceed rate limits, the API returns a 429 Too Many Requests error. Implement exponential backoff retry logic and client-side rate limiting using libraries like express-rate-limit to prevent abuse and stay within limits.

How do I secure my Vonage API credentials in Node.js?

Store Vonage credentials in environment variables using dotenv. Never commit .env files or private.key files to version control (add to .gitignore). Use your hosting platform's secrets management (Heroku Config Vars, AWS Secrets Manager, etc.) in production. Encode multi-line private keys as base64 for easier storage. Rotate credentials if compromised. Implement rate limiting and authentication on your SMS endpoints to prevent unauthorized access.

Can I use Express v5 with Vonage Node.js SDK?

Yes, the Vonage Node.js SDK (v3.24.1) is compatible with both Express v4 and Express v5. Express v5 (stable as of October 2024) offers improved async/await error handling, automatically forwarding rejected promises to error handlers, and enhanced security features. Migration from Express v4 to v5 requires minimal code changes, primarily updating route matching patterns and status code validation.

How do I add SMS functionality to my existing Node.js application?

To integrate SMS into an existing Node.js app, install @vonage/server-sdk and dotenv, configure your Vonage credentials in environment variables, create a reusable sendSms() function with the Vonage client initialization, and add a POST endpoint to your Express routes. Implement proper error handling, input validation, and rate limiting. For production, secure your endpoint with authentication middleware to prevent unauthorized SMS sending.

Frequently Asked Questions

When should I use a rate limiter for the SMS API?

Always use a rate limiter, especially in production, to protect against excessive API usage or abuse, which can incur extra costs. Libraries like 'express-rate-limit' can help with this.

How to send SMS with Node.js and Express

Use the Vonage Messages API with Express.js and the @vonage/server-sdk to create a REST API endpoint. This endpoint takes a phone number and message as input, then uses the Vonage API to send the SMS message.

What is the Vonage Messages API?

It's a robust API for sending various message types, including SMS, MMS, and WhatsApp messages. This tutorial uses it with the official Vonage Node.js SDK (@vonage/server-sdk) to send text messages via SMS.

Why use Node.js for sending SMS messages?

Node.js is well-suited for I/O-bound operations like interacting with APIs. Its asynchronous nature and the npm ecosystem (including Express.js and the Vonage SDK) make it a good choice for building an SMS sending service.

How to set up Vonage application for SMS

Log in to your Vonage dashboard, set the Default SMS API to 'Messages API', create a new application, generate keys, enable the 'Messages' capability, and link your virtual number. Be sure to save your Application ID and private key.

What is the Vonage private key used for?

The Vonage private key is a crucial part of authenticating with the Messages API. It's used with your Application ID to initialize the Vonage client in your Node.js code. Keep this key secure and never commit it to version control.

Where do I store Vonage API credentials?

Store your credentials (Application ID, private key path, Vonage number) in a .env file. This keeps them out of your codebase. Remember to add .env to your .gitignore file to prevent accidental commits.

How to install necessary npm packages for Vonage SMS

You'll need `express`, `@vonage/server-sdk`, and `dotenv`. Run `npm install express @vonage/server-sdk dotenv` in your project's root directory to install these dependencies.

What is the purpose of path.resolve for private key?

path.resolve ensures that the private key path for the Vonage SDK is correct relative to your project's root. This helps avoid issues where the key is not found when running the script from different directories.

How to handle errors when sending SMS with Vonage

The tutorial's code includes try-catch blocks to handle errors during API calls. Log detailed error information for debugging purposes, but be cautious about exposing internal errors to clients.

Can I send SMS to any number with a Vonage trial account?

No, trial accounts are restricted. You must whitelist recipient numbers in your Vonage dashboard under 'Account' -> 'Test numbers' before you can send them test messages.

Why is my Vonage SMS failing with 'Forbidden' error?

This typically means your Application ID, private key, or linked phone number are incorrect. Double-check these credentials in your .env file and the Vonage dashboard.

What to do if Vonage private key path is not working?

Verify the VONAGE_PRIVATE_KEY_PATH in your .env file is correct relative to your project root. Ensure the private.key file exists at that location and has read permissions for the Node process.

How to test Vonage SMS API endpoint locally?

Use tools like `curl` or Postman to make POST requests to your local server's /send-sms endpoint with the required JSON payload (to and message fields). Verify the response and check if the SMS was received.

What is the best practice for deploying Vonage private key?

Never deploy the private key directly. Encode it (e.g., Base64), use secure file copy during deployment, or leverage dedicated secrets management services provided by your hosting platform.