code examples

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

Send SMS with Node.js and Vonage API: Complete Express Integration Guide

Learn how to build a production-ready Node.js SMS service using Express and Vonage API. Step-by-step tutorial with code examples, authentication, error handling, and deployment tips.

Send SMS with Node.js and Vonage API: Complete Express Integration Guide

This guide provides a complete walkthrough for building a simple Node.js application using the Express framework to send SMS messages via the Vonage SMS API. You'll learn how to set up a project, integrate with Vonage, and deploy a production-ready SMS endpoint.

By the end of this tutorial, you'll have a functional Express API endpoint that accepts a recipient phone number and message, then uses the Vonage API to send SMS. This implementation works for backend services, internal tools, or applications where SMS notifications are triggered by server events.

Project Overview and Goals

Goal: Create a secure and reliable Node.js service that sends SMS messages programmatically using Vonage.

Problem Solved: This service provides a foundational building block for applications needing to send transactional SMS, notifications, alerts, or one-time passwords (OTPs).

Technologies Used:

  • Node.js: JavaScript runtime for building server-side applications with strong support for I/O-bound tasks like API interactions.
  • Express: Minimal Node.js web framework for setting up API endpoints and handling HTTP requests.
  • Vonage Server SDK for Node.js (@vonage/server-sdk): Official library for interacting with Vonage APIs.
  • dotenv: Module to load environment variables from a .env file, keeping sensitive credentials out of source code.

System Architecture:

text
+-------------+       +-----------------------+       +-----------------+       +-------------+
|   Client    | ----> | Node.js/Express API   | ----> |   Vonage API    | ----> | User's Phone|
| (e.g., curl,|       | (Your Application)    |       | (SMS Gateway)   |       | (Recipient) |
|  Postman)   |       | - POST /send endpoint |       |                 |       |             |
+-------------+       | - Vonage SDK          |       |                 |       |             |
                      | - Reads .env          |       |                 |       |             |
                      +-----------------------+       +-----------------+       +-------------+

Prerequisites:

  • Node.js and npm (or yarn) installed. Check with node -v and npm -v.
  • A Vonage API account. Sign up here if you don't have one. You get free credit for testing.
  • A text editor or IDE (e.g., VS Code).
  • A tool for making HTTP requests (e.g., curl, Postman, Insomnia).
  • A test phone number to receive messages.

1. Setting up the project

Initialize your Node.js project and install the necessary dependencies.

  1. Create Project Directory: Open your terminal and create a new directory for your project, then navigate into it.

    bash
    mkdir vonage-sms-sender
    cd vonage-sms-sender
  2. Initialize npm: Initialize the project using npm. The -y flag accepts the default settings.

    bash
    npm init -y

    This creates a package.json file.

  3. Install Dependencies: Install Express, the Vonage Server SDK, and dotenv.

    bash
    npm install express @vonage/server-sdk dotenv --save
    • express: The web framework.
    • @vonage/server-sdk: The official Vonage SDK.
    • dotenv: For managing environment variables.
  4. Enable ES Modules: To use modern import syntax, open your package.json file and add "type": "module" at the top level:

    json
    {
      "name": "vonage-sms-sender",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "type": "module",
      "scripts": {
        "start": "node index.js",
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC",
      "dependencies": {
        "@vonage/server-sdk": "^3.12.1",
        "dotenv": "^16.3.1",
        "express": "^4.18.2"
      }
    }

    Adding "type": "module" enables ES Module import/export syntax instead of CommonJS require.

  5. Create Project Files: Create the main application file and environment configuration file.

    bash
    touch index.js .env .gitignore
  6. Configure .gitignore: Prevent sensitive information and unnecessary files from being committed to version control. Add these lines to your .gitignore file:

    text
    # .gitignore
    
    # Dependencies
    node_modules/
    
    # Environment variables
    .env
    
    # Logs
    logs
    *.log
    npm-debug.log*
    yarn-debug.log*
    yarn-error.log*
    pnpm-debug.log*
    
    # Optional Editor directories and files
    .idea
    .vscode
    *.suo
    *.ntvs*
    *.njsproj
    *.sln
    *.sw?

2. Integrating with Vonage

Retrieve your Vonage API credentials and configure your sending number or test recipient.

  1. Get Vonage API Credentials:

    • Log in to your Vonage API Dashboard.
    • On the main dashboard page (or under "API settings"), find your API key and API secret.
    • Keep these values secure – they grant access to your Vonage account.
  2. Configure Sender ID / Virtual Number:

    • Option A (Paid Accounts – Recommended for Production): Buy a Vonage virtual number. Navigate to "Numbers" > "Buy numbers" in the dashboard. Choose a number with SMS capabilities in your desired country. Using a dedicated number improves deliverability and enables two-way communication.
    • Option B (Free Trial / Testing): Use Test Numbers. Vonage free trial accounts can only send messages to phone numbers verified within the dashboard.
      • Go to your Vonage Dashboard.
      • Navigate to "Account" > "Test Numbers".
      • Click "Add test number".
      • Enter the phone number you want to send test messages to (e.g., your personal mobile number) in E.164 format (e.g., +12015550123).
      • Vonage will send a verification code via SMS or voice call to that number. Enter the code to verify.
      • Important: While using a free trial, you must add recipient numbers here, otherwise you'll encounter a "Non-Whitelisted Destination" error when trying to send SMS.
    • Option C (Alphanumeric Sender ID): In some countries, you can use a custom text string (e.g., your brand name like "MyApp") as the sender ID instead of a phone number. Check Vonage documentation for country-specific regulations and support. This is often used for one-way notifications.
  3. Set Environment Variables: Open the .env file you created and add your Vonage credentials and sender/recipient information. Replace the placeholder values with your actual data.

    dotenv
    # .env
    
    # Server Configuration
    PORT=3000
    
    # Vonage API Credentials
    VONAGE_API_KEY=YOUR_API_KEY_HERE
    VONAGE_API_SECRET=YOUR_API_SECRET_HERE
    
    # Vonage Sender & Test Recipient
    # Use either a purchased Vonage number, an approved Alphanumeric Sender ID,
    # or keep it simple for testing (can often be text like 'VonageSMS')
    VONAGE_SENDER_ID_OR_NUMBER=VonageTest
    
    # The phone number added to your Vonage Test Numbers (E.164 format)
    # Only needed if you want a default for quick testing in the code below.
    # The API endpoint will accept the recipient dynamically.
    TEST_RECIPIENT_NUMBER=+12015550123
    • PORT: The port your Express server will listen on.
    • VONAGE_API_KEY: Your API key from the dashboard.
    • VONAGE_API_SECRET: Your API secret from the dashboard.
    • VONAGE_SENDER_ID_OR_NUMBER: The "from" value for the SMS. Use your purchased number, approved alphanumeric ID, or a simple string like "VonageTest" (check deliverability for your region).
    • TEST_RECIPIENT_NUMBER: A placeholder for quick testing; the actual recipient will come from the API request. Make sure this number is verified in your Vonage dashboard's Test Numbers section if you're on a trial account.

3. Implementing the Express API Endpoint

Write the Node.js code to create the Express server and the /send endpoint.

javascript
// index.js
import express from 'express';
import dotenv from 'dotenv';
import { Vonage } from '@vonage/server-sdk';

// Load environment variables from .env file
dotenv.config();

// --- Configuration ---
const PORT = process.env.PORT || 3000;
const VONAGE_API_KEY = process.env.VONAGE_API_KEY;
const VONAGE_API_SECRET = process.env.VONAGE_API_SECRET;
const VONAGE_SENDER_ID = process.env.VONAGE_SENDER_ID_OR_NUMBER;

// Basic validation for environment variables
if (!VONAGE_API_KEY || !VONAGE_API_SECRET || !VONAGE_SENDER_ID) {
    console.error(
        'Error: Vonage API Key, Secret, or Sender ID is missing in .env file.'
    );
    console.error('Please check your environment variable configuration.');
    process.exit(1); // Exit if critical configuration is missing
}

// --- Initialize Vonage Client ---
const vonage = new Vonage({
    apiKey: VONAGE_API_KEY,
    apiSecret: VONAGE_API_SECRET,
});

// --- Initialize Express App ---
const app = express();

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

// Simple logging middleware for incoming requests
app.use((req, res, next) => {
    console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
    next(); // Pass control to the next middleware/route handler
});

// --- API Routes ---

/**
 * @route POST /send
 * @description Sends an SMS message via Vonage.
 * @access Public (consider adding auth in production)
 * @requestBody { recipient: string, message: string }
 * @response Success: { success: true, messageId: string }
 * @response Error: { success: false, error: string }
 */
app.post('/send', async (req, res) => {
    const { recipient, message } = req.body;

    // --- Input Validation ---
    if (!recipient || !message) {
        console.error('Validation Error: Missing recipient or message in request body');
        return res.status(400).json({
            success: false,
            error: 'Bad Request: Both "recipient" and "message" are required in the request body.',
        });
    }

    // Basic check for phone number format (improve as needed for production)
    // E.164 format is generally recommended (e.g., +12223334444)
    if (!/^\+?[1-9]\d{1,14}$/.test(recipient)) {
        console.error(`Validation Error: Invalid recipient format: ${recipient}`);
        return res.status(400).json({
            success: false,
            error: 'Bad Request: Invalid recipient phone number format. Use E.164 format (e.g., +12223334444).',
        });
    }


    console.log(`Attempting to send SMS to ${recipient} from ${VONAGE_SENDER_ID}`);

    // --- Send SMS using Vonage SDK ---
    try {
        // Note: The modern Messages API (vonage.messages.send) is often preferred,
        // but vonage.sms.send is simpler for this basic use case.
        const responseData = await vonage.sms.send({
            to: recipient,
            from: VONAGE_SENDER_ID,
            text: message,
        });

        // Check the status of the first message in the response
        if (responseData.messages[0].status === '0') {
            const messageId = responseData.messages[0]['message-id'];
            console.log(`SMS sent successfully to ${recipient}. Message ID: ${messageId}`);
            res.status(200).json({
                success: true,
                messageId: messageId,
            });
        } else {
            const errorCode = responseData.messages[0].status;
            const errorText = responseData.messages[0]['error-text'];
            console.error(`SMS failed to send to ${recipient}. Status: ${errorCode} – Error: ${errorText}`);
            // Determine appropriate status code based on Vonage error
            // For simplicity, using 500, but could map specific errors (e.g., 4xx for bad number format if not caught earlier)
            res.status(500).json({
                success: false,
                error: `Failed to send SMS: ${errorText} (Code: ${errorCode})`,
            });
        }
    } catch (error) {
        console.error('Error sending SMS via Vonage:', error);
        // Handle potential SDK errors or network issues
        res.status(500).json({
            success: false,
            error: 'Internal Server Error: Could not process the SMS request.',
            details: error.message, // Include details cautiously in dev, maybe omit in prod
        });
    }
});

// --- Health Check Endpoint ---
app.get('/health', (req, res) => {
    res.status(200).json({ status: 'UP', timestamp: new Date().toISOString() });
});


// --- Error Handling Middleware (Basic) ---
// Catches errors from synchronous code or errors passed via next(err)
app.use((err, req, res, next) => {
    console.error('Unhandled Error:', err);
    res.status(500).json({
        success: false,
        error: 'Internal Server Error',
        message: err.message, // Be cautious exposing error messages in production
    });
});


// --- Start Server ---
app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
    console.log(`API endpoint available at POST /send`);
    console.log(`Using Vonage Sender ID/Number: ${VONAGE_SENDER_ID}`);
    // Log only if TEST_RECIPIENT_NUMBER is set, useful for quick dev testing
    if (process.env.TEST_RECIPIENT_NUMBER) {
       console.log(`Test recipient number set in .env: ${process.env.TEST_RECIPIENT_NUMBER}`);
    }
});

Code Explanation:

  1. Imports: Imports express, dotenv, and the Vonage SDK.
  2. Configuration Loading: dotenv.config() loads variables from .env. Basic checks ensure critical Vonage credentials exist.
  3. Vonage Initialization: Creates a vonage client instance using the API key and secret.
  4. Express Setup: Initializes the Express application.
  5. Middleware:
    • express.json() and express.urlencoded() parse incoming request bodies.
    • A custom middleware logs basic request information (method and URL).
  6. /send Endpoint (POST):
    • Defined as an async function to use await for the Vonage API call.
    • Extracts recipient and message from req.body.
    • Input Validation: Checks if recipient and message are present. Returns a 400 Bad Request error if not. Includes a basic regex check for E.164 format.
    • Vonage Call: Uses vonage.sms.send() within a try...catch block.
      • Success: If responseData.messages[0].status is '0', the message was accepted by Vonage. Logs success and returns a 200 OK response with the message-id.
      • Vonage Error: If the status is not '0', logs the error details provided by Vonage and returns a 500 Internal Server Error (could be refined) with the Vonage error message.
      • SDK/Network Error: The catch block handles exceptions during the API call (e.g., network issues, invalid credentials leading to SDK errors) and returns a generic 500 error.
  7. /health Endpoint (GET): A simple endpoint useful for monitoring to check if the service is running.
  8. Error Handling Middleware: A basic catch-all error handler for unhandled errors.
  9. Server Start: Starts the Express server, listening on the specified PORT.

4. Running and Testing the Application

  1. Start the Server: Open your terminal in the project directory and run:

    bash
    npm start

    You should see output indicating the server is running:

    Server is running on http://localhost:3000 API endpoint available at POST /send Using Vonage Sender ID/Number: VonageTest Test recipient number set in .env: +12015550123
  2. Test with curl: Open a new terminal window and use curl to send a POST request to your /send endpoint. Replace +1YOUR_TEST_NUMBER with the actual phone number you verified in the Vonage dashboard's Test Numbers section.

    bash
    curl -X POST http://localhost:3000/send \
         -H "Content-Type: application/json" \
         -d '{
               "recipient": "+1YOUR_TEST_NUMBER",
               "message": "Hello from your Node.js Vonage App!"
             }'
  3. Test with Postman/Insomnia:

    • Create a new request.
    • Set the method to POST.
    • Set the URL to http://localhost:3000/send.
    • Go to the "Body" tab, select "raw", and choose "JSON" from the dropdown.
    • Enter the JSON payload:
      json
      {
          "recipient": "+1YOUR_TEST_NUMBER",
          "message": "Hello from Postman/Insomnia via Node.js Vonage!"
      }
    • Send the request.

Expected Responses:

  • Success:

    json
    {
        "success": true,
        "messageId": "some-unique-message-id-from-vonage"
    }

    You should also receive the SMS on the recipient phone shortly after.

  • Validation Error (Missing Field):

    json
    // Status: 400 Bad Request
    {
        "success": false,
        "error": "Bad Request: Both \"recipient\" and \"message\" are required in the request body."
    }
  • Vonage Error (e.g., Non-Whitelisted Number on Trial):

    json
    // Status: 500 Internal Server Error (or potentially mapped 4xx)
    {
        "success": false,
        "error": "Failed to send SMS: Non White-listed Destination – rejected (Code: 15)" // Example error
    }
  • Server Error (e.g., Invalid API Key):

    json
    // Status: 500 Internal Server Error
    {
        "success": false,
        "error": "Internal Server Error: Could not process the SMS request.",
        "details": "Authentication failed" // Example SDK error message
    }

5. Error Handling and Logging

The current implementation includes basic error handling:

  • Input Validation: Checks for required fields (recipient, message) and basic format.
  • Vonage API Errors: Checks the status code in the Vonage response and logs/returns the error-text.
  • SDK/Network Errors: Uses a try...catch block around the vonage.sms.send call.
  • Basic Logging: Uses console.log and console.error.

Production Enhancements:

  • Structured Logging: Implement a dedicated logging library like winston or pino. This enables structured JSON logs, different log levels (debug, info, warn, error), and easier integration with log management systems (e.g., Datadog, Splunk, ELK stack).
  • Detailed Error Mapping: Map specific Vonage error codes (from responseData.messages[0].status) to appropriate HTTP status codes (4xx for client errors like invalid number, 5xx for server-side issues) and potentially retry logic.
  • Retry Mechanisms: For transient errors (e.g., network timeouts, temporary Vonage issues), implement a retry strategy with exponential backoff using libraries like async-retry. Be cautious not to retry errors indicating permanent failure (like invalid number).
  • Centralized Error Handling: Refine the final error handling middleware to provide consistent error responses without leaking sensitive stack traces in production.

6. Security Considerations

  • API Key Security:
    • NEVER commit API keys or secrets directly into source code.
    • Use environment variables (.env locally, platform-specific configuration in deployment).
    • Ensure .env is in your .gitignore.
    • Consider using secrets management solutions (like HashiCorp Vault, AWS Secrets Manager, Google Secret Manager) for production environments.
  • Input Validation & Sanitization:
    • The current validation is basic. Robustly validate phone numbers (e.g., using libraries like google-libphonenumber).
    • While Vonage handles SMS content, if you were displaying the message content elsewhere in your app, you would need to sanitize it (e.g., using express-validator or libraries like DOMPurify if rendering as HTML) to prevent Cross-Site Scripting (XSS). For sending via Vonage, validation of length and format is more relevant.
  • Rate Limiting: Protect your API endpoint from abuse. Implement rate limiting based on IP address or API keys (if you add authentication) using middleware like express-rate-limit.
  • Authentication/Authorization: The current endpoint is public. In a real application, you would protect it:
    • API Keys: Issue keys to legitimate clients and require them in headers (e.g., X-API-Key). Validate the key on the server.
    • JWT/OAuth: For user-driven actions, use standard authentication mechanisms.
  • HTTPS: Always run your application behind HTTPS in production (usually handled by load balancers or reverse proxies like Nginx).

7. Troubleshooting and Caveats

  • Non White-listed Destination - rejected (Error Code 15): This is the most common issue on free trial accounts. Solution: Ensure the recipient phone number has been added and verified under "Account" > "Test Numbers" in your Vonage Dashboard.
  • Authentication failed / 401 Unauthorized: Double-check that VONAGE_API_KEY and VONAGE_API_SECRET in your .env file are correct and that the .env file is being loaded properly (dotenv.config() is called before initializing Vonage). Ensure no extra spaces or characters were copied.
  • Invalid Sender ID: If using an alphanumeric sender ID, ensure it's registered and approved for the destination country. If using a number, ensure it's a valid Vonage number with SMS capabilities. Some networks might override alphanumeric IDs.
  • Incorrect Phone Number Format: Vonage generally expects E.164 format (+ followed by country code and number, e.g., +447700900000, +12125551234). Ensure the recipient number follows this format.
  • SDK Version Issues: Occasionally, breaking changes occur in SDKs. If you encounter unexpected errors after updating, check the SDK's changelog. Potential TypeScript issues might arise in specific version combinations, though less likely with this pure JavaScript setup.
  • Deliverability Issues: SMS delivery can be affected by carrier filtering, country regulations, and content. Check Vonage's documentation for best practices and country-specific guidelines.
  • Firewall/Network Issues: Ensure your server can make outbound HTTPS requests to Vonage's API endpoints (rest.nexmo.com, api.nexmo.com).

8. Deployment and CI/CD

  • Platform Choice: Deploy your Node.js application to platforms like Heroku, Vercel, AWS (EC2, Elastic Beanstalk, Fargate), Google Cloud (App Engine, Cloud Run), Azure App Service, or DigitalOcean App Platform.
  • Environment Variables: Configure your VONAGE_API_KEY, VONAGE_API_SECRET, and VONAGE_SENDER_ID_OR_NUMBER securely within your chosen hosting platform's environment variable settings. Do not deploy your .env file.
  • NODE_ENV=production: Set the NODE_ENV environment variable to production. This often enables performance optimizations in Express and other libraries.
  • Process Manager: Use a process manager like pm2 or rely on the platform's built-in mechanisms (e.g., Heroku Dynos, systemd) to keep your application running and handle restarts.
  • CI/CD: Set up a pipeline (e.g., using GitHub Actions, GitLab CI, Jenkins, CircleCI) to:
    1. Lint and test your code automatically.
    2. Build your application (if necessary, though often not required for simple Node.js apps).
    3. Deploy automatically to staging/production environments upon successful builds/merges.
  • Database/State: This simple service is stateless. If you needed to store message logs, track status updates via webhooks, or manage user data, you would add a database (e.g., PostgreSQL, MongoDB, Redis).

9. Verification and Final Checks

Before considering the implementation complete:

  • Environment Setup: Can you successfully run npm install and npm start?
  • Configuration: Are VONAGE_API_KEY, VONAGE_API_SECRET, and VONAGE_SENDER_ID_OR_NUMBER correctly set in .env (or deployment environment)?
  • Test Number Verification: If using a trial account, is the recipient number verified in the Vonage Dashboard?
  • Health Check: Does GET /health return a 200 OK response with { "status": "UP", ... }?
  • Successful SMS: Can you successfully send an SMS using curl or Postman to a valid (and potentially whitelisted) recipient?
    • Does the API return a 200 OK with { "success": true, "messageId": "..." }?
    • Do you receive the SMS on the recipient's phone?
  • Validation Error Handling: Does sending a request without recipient or message return a 400 Bad Request with an appropriate error message?
  • Vonage Error Simulation (if possible): Can you trigger a known Vonage error (e.g., sending to a non-whitelisted number on trial) and verify the API returns a non-200 status (e.g., 500) with the correct error message from Vonage?
  • Security: Is .env included in .gitignore? (Crucial!)
  • Logging: Do requests and errors appear in the console logs during testing?

Final Thoughts

You have successfully built a basic but functional Node.js service to send SMS messages using Express and the Vonage API. This provides a solid foundation for integrating SMS capabilities into various applications. Remember to enhance security, error handling, and logging for production environments.

Consider exploring Vonage's other features like receiving SMS (using webhooks), number insight, voice calls, or two-factor authentication (Verify API) to further enhance your communication workflows.

Frequently Asked Questions

How to send SMS with Node.js and Express

Set up a Node.js project with Express and the Vonage Server SDK. Create an API endpoint that accepts recipient and message details, then uses the SDK to send the SMS via the Vonage API. Ensure you have Vonage API credentials and a sender ID configured.

What is Vonage SMS API used for

The Vonage SMS API enables sending text messages programmatically from your applications. It's used for transactional messages, notifications, alerts, two-factor authentication, and more by integrating with the API via their SDK.

Why use Express framework with Node.js for SMS

Express simplifies creating API endpoints and handling HTTP requests, which streamlines the integration with the Vonage SMS API in a Node.js application. It provides a structured way to build your SMS service.

How to set up Vonage API credentials

Obtain your API key and secret from the Vonage API Dashboard. Store them securely, preferably in environment variables (.env file locally), to avoid exposing them in your code.

When to use a virtual number for sending SMS

A dedicated virtual number is recommended, especially for production, as it enhances deliverability and enables two-way communication. Obtain one from your Vonage Dashboard under 'Numbers'.

Can I use an alphanumeric sender ID with Vonage

Yes, in certain countries, you can use a text string (like your brand name) as the sender ID. Consult Vonage's documentation for regional regulations and availability as this is country-specific.

How to fix 'Non-Whitelisted Destination' error

This usually occurs with free trial accounts. Verify that you've added and confirmed the recipient phone number in the 'Test Numbers' section of your Vonage Dashboard. This is required for trial usage.

What is dotenv used for in Node.js project

The `dotenv` module loads environment variables from a `.env` file into `process.env`. This helps manage credentials and configuration securely without directly embedding them in your code.

Why does my Vonage SMS fail to send

Check several potential issues: incorrect API credentials, unverified recipient number (for trial accounts), invalid sender ID, incorrect phone number format, or network connectivity issues.

When should I implement rate limiting for my SMS API

It's best to implement rate limiting in production to prevent abuse and control costs. Middleware like express-rate-limit can help enforce limits based on IP address or API key.

How to improve error handling in Node.js SMS app

Implement structured logging (Winston or Pino), map Vonage error codes to HTTP status codes, add retry mechanisms for transient errors, and centralize error handling middleware.

What are security best practices for Vonage API integration

Secure API keys using environment variables or dedicated secrets management. Validate and sanitize input data, implement rate limiting, add authentication/authorization, and ensure HTTPS in production.

How to deploy my Node.js SMS application

Deploy to platforms like Heroku, AWS, or Google Cloud, configuring environment variables securely. Use process managers and set NODE_ENV=production. Set up CI/CD for automated deployment and testing.

How to test my Vonage SMS API endpoint

Use tools like curl or Postman to send POST requests to your /send endpoint with recipient and message in JSON format. Check the responses for success or specific error messages and ensure you receive the SMS.