Node.js SDK

@usezend/node is the official Node.js and TypeScript client for Zend. It wraps the messaging API in one typed client, so you can send SMS, WhatsApp, email, and voice — and read templates — without hand-rolling HTTP requests.

Note

The SDK is open source on GitHub and published on npm.

Installation

npm i @usezend/node

Requires Node.js 18 or later — it uses the built-in fetch and FormData, and has no other runtime dependencies.

Authenticate

Create a client with your API key (find it in your Zend dashboard):

import { Zend } from '@usezend/node';

const zend = new Zend('sent_live_...');

You can also set the ZEND_API_KEY environment variable and construct the client with no arguments:

const zend = new Zend();

Note

Keep your API key secret — never expose it in client-side code. Store it in an environment variable rather than committing it to source control.

Every method resolves to { data, error } and never throws for API or network errors — always check error before using data (see Errors).

Send an SMS

const { data, error } = await zend.messages.send({
  to: '+233201234567',
  body: 'Hello from Zend!',
  preferredChannels: ['sms'],
  senderId: 'MyBrand',
});

if (error) throw error;
console.log(`Message ${data.id} (${data.status})`);
tostringrequired
Recipient phone number in E.164 format.
bodystring
Message text. Omit when sending a template.
preferredChannelsChannel[]
Channels to attempt, in order — one or more of sms, whatsapp.
senderIdstring
Your approved SMS sender ID. Omit to use your account default.
fallbackEnabledboolean
Try the next channel if one fails.
prioritystring
low · normal · high · urgent.
deliveryPrioritystring
cost · speed · reliability.
webhookUrlstring
URL to receive delivery-status callbacks.
scheduledForstring
ISO 8601 timestamp to send later.

Send a WhatsApp message

WhatsApp business messages use approved templates, and can fall back to SMS:

await zend.messages.send({
  to: '+233201234567',
  templateId: 'welcome',
  templateParams: { first_name: 'John' },
  preferredChannels: ['whatsapp', 'sms'],
  fallbackEnabled: true,
});

See WhatsApp for templates, media, and delivery.

Send in bulk

await zend.messages.sendBulk({
  messages: [
    { to: '+233201234567', body: 'Hi Ama!' },
    { to: '+233207654321', body: 'Your code is 123456' },
  ],
  preferredChannels: ['sms'],
  senderId: 'MyBrand',
});

See Bulk messaging for larger sends and personalization.

Send an email

const { data } = await zend.emails.send({
  from: 'you@example.com',
  to: 'user@gmail.com',
  subject: 'Hello world',
  html: '<p>It works!</p>',
  text: 'It works!',
});
fromstringrequired
A verified sender address on one of your domains.
tostringrequired
Recipient email address.
subjectstringrequired
Subject line.
htmlstring
HTML body.
textstring
Plain-text fallback.
attachmentsAttachment[]
Files to attach — see Attachments below.

Attachments

Attach files by passing an attachments array. Each file's content is a Buffer or a base64-encoded string:

import { readFileSync } from 'node:fs';

await zend.emails.send({
  from: 'you@example.com',
  to: 'user@gmail.com',
  subject: 'Your invoice',
  html: '<p>Invoice attached.</p>',
  attachments: [
    {
      filename: 'invoice.pdf',
      content: readFileSync('./invoice.pdf'), // Buffer or base64 string
      contentType: 'application/pdf',
    },
  ],
});
filenamestringrequired
File name shown to the recipient, including its extension.
contentBuffer | stringrequired
File data — a Buffer or a base64-encoded string.
contentTypestring
MIME type, e.g. application/pdf. Defaults to application/octet-stream when omitted — set it so mail clients render the file correctly.

Note

Up to 10 attachments per email, and 7 MB total across all files (measured on the decoded bytes).

See Email for sending domains and deliverability.

Send a voice call

Read a message aloud with text-to-speech, falling back to SMS if the call isn't answered:

await zend.voice.send({
  recipients: ['+233201234567'],
  text: 'Your order has shipped.',
  voice: 'female',
  fallback: { sms: true, smsText: 'Your order has shipped.' },
});

Or play a pre-recorded audio file (a hosted MP3/WAV):

await zend.voice.send({
  recipients: ['+233201234567'],
  voiceUrl: 'https://cdn.example.com/message.mp3',
});

To send a local audio file, upload it first with zend.voice.upload(file, filename) and pass the returned url as voiceUrl. See Voice for audio, TTS, and billing.

Read templates

Templates are read-only from the SDK — list them and fetch one to reuse when sending:

const { data } = await zend.templates.list({ category: 'transactional' });

const template = await zend.templates.get('welcome');

Track and manage messages

const message = await zend.messages.get('6884da240f0e633b7b979bff');
await zend.messages.cancel('6884da240f0e633b7b979bff');

Voice batches expose per-recipient results:

const batch = await zend.voice.get('voice_13d858b9-...');

Errors

Every method resolves to { data, error } — it never throws for API or network errors, so you handle failures inline:

const { data, error } = await zend.messages.send({ to: '+233201234567', body: 'Hi' });

if (error) {
  console.error(error.name, error.statusCode, error.message);
} else {
  console.log(data.id);
}

error is a ZendError (extends Error) with:

namestring
Error category, e.g. api_error, timeout, application_error.
statusCodenumber
HTTP status code, when available.
codestring
Provider error code, when available.

Next steps