To send SMS from Node.js, install the official esms-sms package from npm, create an API key in the eSMS dashboard and call esms.messages.send() with the recipient in international format and your text. Use a test key first: it returns real responses but never sends or charges, so your SMS API Node.js integration is proven before you spend anything.

Last reviewed: 29 October 2026

How to send an SMS with the SMS API in Node.js

  1. Create an API key

    Sign in at sms.esmsafrica.io and open API Keys under DEVELOPERS in the left menu. Type a Key name, pick the Environment and tick the Permissions the key needs: Send SMS and Read messages and reports cover sending and status checks. Choose Test (sandbox) while you build. Click Generate key and copy it straight away: the full key is shown once, right after you create it. Test keys start with esms_test_, live keys with esms_live_.

    eSMS API keys page with the key name, environment, permissions, Generate key button and keys table numbered 1 to 5
    1 Key name, 2 Environment (Live or Test), 3 Permissions checkboxes, 4 Generate key button, 5 API keys table.
  2. Install the package

    In your project folder run:

    npm install esms-sms

    The current release on npm is 1.2.0. It ships ES module and CommonJS builds plus TypeScript types, so import { Esms } from "esms-sms" and const { Esms } = require("esms-sms") both work.

  3. Keep the key in an environment variable

    Never hard-code the key or ship it to a browser or mobile app. Set it on the server:

    export ESMS_API_KEY=esms_test_your_key_here

    Use a separate key for each environment (local, staging, production) so you can revoke one without touching the others.

  4. Send a message

    Create the client and send. Numbers must include the country code, for example +254712340001.

    // send.mjs
    import { Esms } from "esms-sms";
    
    const esms = new Esms({ apiKey: process.env.ESMS_API_KEY });
    
    const res = await esms.messages.send({
      to: "+254712340001",            // international (E.164) format
      text: "Hello from eSMS Africa",
      // senderId: "YOURBRAND",       // optional: an approved sender ID, else the country default
    });
    
    console.log(res.id, res.status, res.segments);

    Run it with node send.mjs. With a test key the response has an id starting with test_, status queued and livemode: false, and the delivery lifecycle is simulated. With a live key the status is normally submitted once the network accepts it. If you leave out the sender ID, the default sender for that country is used.

  5. Check the delivery status

    Read one message, including its timeline of events:

    const msg = await esms.messages.get(res.id);
    console.log(msg.status);    // queued | submitted | sent | delivered | failed ...
    console.log(msg.timeline);  // every event in the message's delivery history

    Polling is fine for a quick test. In production, receive delivery reports by webhook instead, as shown in Webhooks and delivery reports.

  6. Handle errors by code

    Every failure is an EsmsError with the HTTP status, a stable code and a requestId you can quote to support. Catch the subclasses you care about:

    import {
      Esms,
      EsmsError,
      InsufficientBalanceError,
      RateLimitError,
    } from "esms-sms";
    
    try {
      await esms.messages.send({ to: "+254712340001", text: "Hi" });
    } catch (err) {
      if (err instanceof InsufficientBalanceError) {
        console.error(`Top up: have ${err.balance}, need ${err.cost} ${err.currency}`);
      } else if (err instanceof RateLimitError) {
        console.error("Slow down and retry later");
      } else if (err instanceof EsmsError) {
        // err.code is the stable API code, e.g. country_not_enabled
        console.error(err.status, err.code, err.message, err.requestId);
      } else {
        throw err;
      }
    }
  7. Switch to live

    When your tests pass, create a key with Environment Live, switch on each destination country on the Countries page, top up, and swap the key in your environment variable. No code change is needed.

Common errors and how to fix them

What you seeWhat it meansHow to fix it
AuthenticationError (401)The key is missing, mistyped or revoked.Check ESMS_API_KEY is set in the process that runs the code, and that the key is not revoked on the API Keys page.
403 insufficient_scopeThe key does not have the permission for this call.Generate a new key with Send SMS ticked (and Read messages and reports for status calls).
403 country_not_enabledLive sending to that country is not switched on for your account. Nothing was charged.Open Countries in the dashboard and click Enable. Test keys do not need this.
403 sender_not_approvedThe sender ID is not approved for the destination country.Leave senderId out to use the default, or request the sender ID on the Sender IDs page.
400 missing_country_codeThe number was sent in local format, such as 0712...Send it in international format, for example +254712340001. See the E.164 guide.
InsufficientBalanceError (402)Your balance does not cover the message.Top up at auth.esmsafrica.io/topup, then send again.
ReferenceError: fetch is not definedThe code is running on a Node.js version older than 18.Upgrade to Node.js 18 or later.

Frequently asked questions

Does the SDK work with TypeScript?

Yes. The package ships its own type definitions, so parameters and results are typed without installing anything extra.

Can I use the SDK in a browser or React Native app?

No. Keep the API key on your server. Call your own back end from the app, and let the back end call eSMS Africa.

Is there a test mode?

Yes. A key created with Environment Test (sandbox) uses the same endpoints but never sends or charges, and the last four digits of the number pick the simulated result.

Can I send to many numbers at once?

Yes. Use messages.sendBulk() for one text to many numbers or messages.sendBatch() for personalised messages. See the bulk and batch guide.

Where is the full method list?

The Node.js page on docs.esmsafrica.io lists every resource, including Verify, opt-outs, campaigns and contacts.

Ready? Create a free eSMS account, then create a test API key and send your first simulated message in minutes. Nothing is charged until you switch to a live key.