Learn how to integrate NestSMS into your JavaScript and Node.js applications with practical examples using native fetch and popular HTTP clients.

Installation and Setup

For Node.js projects, you can use the built-in fetch (Node 18+) or install an HTTP client:

npm install axios

Environment Variables

Create a .env file:

# .env
NESTSMS_API_KEY=nsms_live_your_api_key_here

For Node.js, install dotenv to load environment variables:

npm install dotenv

Native Fetch

Use the built-in fetch available in Node.js 18+ to make requests directly to the NestSMS API.

Send SMS

// send-sms.js
require("dotenv").config();

async function sendSMS(phoneNumber, message) {
  try {
    const response = await fetch("https://api.nestsms.com/api/v1/sms/send", {
      method: "POST",
      headers: {
        "X-API-Key": process.env.NESTSMS_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        to: phoneNumber,
        message: message,
        sender_id: "YourBrand",
        message_type: "transactional",
      }),
    });

    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.error || "Failed to send SMS");
    }

    console.log("✓ SMS sent successfully!");
    console.log("Job ID:", data.job_id);
    console.log("Recipients:", data.recipients_count);
    console.log("Cost:", data.cost);

    return data;
  } catch (error) {
    console.error("✗ Error:", error.message);
    throw error;
  }
}

// Usage
sendSMS("9840123456", "Hello from NestSMS API!");

Send Bulk SMS

// send-bulk-sms.js
async function sendBulkSMS(recipients, message) {
  try {
    const response = await fetch("https://api.nestsms.com/api/v1/sms/send", {
      method: "POST",
      headers: {
        "X-API-Key": process.env.NESTSMS_API_KEY,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        to: recipients, // Array of phone numbers
        message: message,
        sender_id: "YourBrand",
        message_type: "promotional",
      }),
    });

    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.error || "Failed to send bulk SMS");
    }

    return data;
  } catch (error) {
    console.error("Bulk SMS Error:", error.message);
    throw error;
  }
}

// Usage
const recipients = ["9840123456", "9851234567", "9861345678"];
sendBulkSMS(recipients, "Special offer! Get 50% off today.");

Check SMS Status

// check-status.js
async function checkSMSStatus(messageId) {
  try {
    const response = await fetch(`https://api.nestsms.com/api/v1/sms/status/${messageId}`, {
      method: "GET",
      headers: {
        "X-API-Key": process.env.NESTSMS_API_KEY,
      },
    });

    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.error || "Failed to check status");
    }

    console.log("Status:", data.status);
    console.log("Sent at:", data.sent_at);
    console.log("Delivered at:", data.delivered_at);

    return data;
  } catch (error) {
    console.error("Status Check Error:", error.message);
    throw error;
  }
}

// Usage
checkSMSStatus("550e8400-e29b-41d4-a716-446655440000");

Get Account Balance

// get-balance.js
async function getBalance() {
  try {
    const response = await fetch("https://api.nestsms.com/api/v1/sms/balance", {
      method: "GET",
      headers: {
        "X-API-Key": process.env.NESTSMS_API_KEY,
      },
    });

    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.error || "Failed to get balance");
    }

    console.log("Balance:", data.balance, data.currency);
    console.log("SMS sent today:", data.sms_sent_today);
    console.log("SMS sent this month:", data.sms_sent_this_month);

    return data;
  } catch (error) {
    console.error("Balance Error:", error.message);
    throw error;
  }
}

// Usage
getBalance();

Axios and API Client

Send SMS with Axios

// send-sms-axios.js
const axios = require("axios");
require("dotenv").config();

const nestSMSClient = axios.create({
  baseURL: "https://api.nestsms.com/api/v1",
  headers: {
    "X-API-Key": process.env.NESTSMS_API_KEY,
    "Content-Type": "application/json",
  },
});

async function sendSMS(phoneNumber, message) {
  try {
    const response = await nestSMSClient.post("/sms/send", {
      to: phoneNumber,
      message: message,
      sender_id: "YourBrand",
      message_type: "transactional",
    });

    console.log("✓ SMS sent successfully!");
    console.log("Response:", response.data);

    return response.data;
  } catch (error) {
    if (error.response) {
      // API returned an error response
      console.error("API Error:", error.response.data.error);
      console.error("Error Code:", error.response.data.code);
    } else {
      // Network or other error
      console.error("Error:", error.message);
    }
    throw error;
  }
}

// Usage
sendSMS("9840123456", "Your OTP is 123456. Valid for 5 minutes.");

Complete API Client Class

// nestsms-client.js
const axios = require("axios");

class NestSMSClient {
  constructor(apiKey) {
    this.client = axios.create({
      baseURL: "https://api.nestsms.com/api/v1",
      headers: {
        "X-API-Key": apiKey,
        "Content-Type": "application/json",
      },
    });
  }

  async sendSMS(to, message, options = {}) {
    try {
      const response = await this.client.post("/sms/send", {
        to,
        message,
        sender_id: options.senderName || "YourBrand",
        message_type: options.messageType || "transactional",
        type: options.encoding || "text",
      });
      return response.data;
    } catch (error) {
      this.handleError(error);
    }
  }

  async sendBulkSMS(recipients, message, options = {}) {
    if (!Array.isArray(recipients) || recipients.length > 1000) {
      throw new Error("Recipients must be an array (max 1000)");
    }

    try {
      const response = await this.client.post("/sms/send", {
        to: recipients,
        message,
        sender_id: options.senderName || "YourBrand",
        message_type: options.messageType || "promotional",
      });
      return response.data;
    } catch (error) {
      this.handleError(error);
    }
  }

  async checkStatus(messageId) {
    try {
      const response = await this.client.get(`/sms/status/${messageId}`);
      return response.data;
    } catch (error) {
      this.handleError(error);
    }
  }

  async getBalance() {
    try {
      const response = await this.client.get("/sms/balance");
      return response.data;
    } catch (error) {
      this.handleError(error);
    }
  }

  handleError(error) {
    if (error.response) {
      const { data, status } = error.response;
      throw new Error(
        `API Error (${status}): ${data.error || "Unknown error"} [${data.code || "N/A"}]`,
      );
    } else if (error.request) {
      throw new Error("Network error: No response from server");
    } else {
      throw error;
    }
  }
}

// Export
module.exports = NestSMSClient;

// Usage Example
// const client = new NestSMSClient(process.env.NESTSMS_API_KEY);
// await client.sendSMS("9840123456", "Hello!");

Express.js and OTP

Setup Express Server

// server.js
const express = require("express");
const NestSMSClient = require("./nestsms-client");
require("dotenv").config();

const app = express();
app.use(express.json());

const smsClient = new NestSMSClient(process.env.NESTSMS_API_KEY);

// Send SMS endpoint
app.post("/api/sms/send", async (req, res) => {
  try {
    const { to, message } = req.body;

    if (!to || !message) {
      return res.status(400).json({
        success: false,
        error: "Missing required fields: to, message",
      });
    }

    const result = await smsClient.sendSMS(to, message);

    res.json({
      success: true,
      jobId: result.job_id,
      cost: result.cost,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      error: error.message,
    });
  }
});

// Bulk SMS endpoint
app.post("/api/sms/bulk", async (req, res) => {
  try {
    const { recipients, message } = req.body;

    const result = await smsClient.sendBulkSMS(recipients, message);

    res.json({
      success: true,
      jobId: result.job_id,
      recipientsCount: result.recipients_count,
      cost: result.cost,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      error: error.message,
    });
  }
});

// Check status endpoint
app.get("/api/sms/status/:messageId", async (req, res) => {
  try {
    const { messageId } = req.params;
    const result = await smsClient.checkStatus(messageId);

    res.json({
      success: true,
      status: result.status,
      sentAt: result.sent_at,
      deliveredAt: result.delivered_at,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      error: error.message,
    });
  }
});

// Get balance endpoint
app.get("/api/balance", async (req, res) => {
  try {
    const result = await smsClient.getBalance();

    res.json({
      success: true,
      balance: result.balance,
      currency: result.currency,
      smsSentToday: result.sms_sent_today,
    });
  } catch (error) {
    res.status(500).json({
      success: false,
      error: error.message,
    });
  }
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

OTP Verification Example

// otp-service.js
const NestSMSClient = require("./nestsms-client");

class OTPService {
  constructor(apiKey) {
    this.smsClient = new NestSMSClient(apiKey);
    this.otpStore = new Map(); // Use Redis in production
  }

  generateOTP() {
    return Math.floor(100000 + Math.random() * 900000).toString();
  }

  async sendOTP(phoneNumber) {
    const otp = this.generateOTP();

    // Store OTP with expiration (5 minutes)
    this.otpStore.set(phoneNumber, {
      otp,
      expiresAt: Date.now() + 5 * 60 * 1000,
    });

    // Send SMS
    await this.smsClient.sendSMS(
      phoneNumber,
      `Your verification code is ${otp}. Valid for 5 minutes.`,
      { messageType: "otp" },
    );

    return { success: true };
  }

  verifyOTP(phoneNumber, enteredOTP) {
    const stored = this.otpStore.get(phoneNumber);

    if (!stored) {
      return { success: false, error: "OTP not found or expired" };
    }

    if (Date.now() > stored.expiresAt) {
      this.otpStore.delete(phoneNumber);
      return { success: false, error: "OTP expired" };
    }

    if (stored.otp !== enteredOTP) {
      return { success: false, error: "Invalid OTP" };
    }

    // Clear OTP after successful verification
    this.otpStore.delete(phoneNumber);

    return { success: true };
  }
}

module.exports = OTPService;

Browser JavaScript

Client-Side Example

// client.js
async function sendSMSFromClient(phoneNumber, message) {
  try {
    // Call your backend API, not NestSMS directly
    const response = await fetch("/api/sms/send", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        to: phoneNumber,
        message: message,
      }),
    });

    const data = await response.json();

    if (!response.ok) {
      throw new Error(data.error || "Failed to send SMS");
    }

    console.log("SMS sent successfully!");
    return data;
  } catch (error) {
    console.error("Error:", error.message);
    throw error;
  }
}

// Usage in browser
document.getElementById("smsForm").addEventListener("submit", async (e) => {
  e.preventDefault();

  const phone = document.getElementById("phone").value;
  const message = document.getElementById("message").value;

  try {
    await sendSMSFromClient(phone, message);
    alert("SMS sent successfully!");
  } catch (error) {
    alert("Failed to send SMS: " + error.message);
  }
});

Responses and Best Practices

Successful Send Response

{
  "success": true,
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "message": "SMS queued successfully",
  "recipients_count": 1,
  "cost": 1.5
}

Error Response

{
  "success": false,
  "error": "Insufficient balance",
  "code": "INSUFFICIENT_BALANCE"
}

Error Handling

async function sendSMSWithRetry(phoneNumber, message, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const result = await sendSMS(phoneNumber, message);
      return result;
    } catch (error) {
      console.error(`Attempt ${attempt} failed:`, error.message);

      if (attempt === maxRetries) {
        throw new Error("Max retries exceeded");
      }

      // Exponential backoff
      await new Promise((resolve) => setTimeout(resolve, Math.pow(2, attempt) * 1000));
    }
  }
}

Best Practices

  1. Never expose API keys in client-side code
  2. Use environment variables for sensitive data
  3. Implement proper error handling
  4. Respect rate limits (60 req/min)
  5. Store job IDs for status tracking
  6. Use Redis for OTP storage in production
  7. Implement retry logic with exponential backoff

Next Steps