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.
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
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})`);
sms, whatsapp.low · normal · high · urgent.cost · speed · reliability.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!',
});
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',
},
],
});
Buffer or a base64-encoded string.application/pdf. Defaults to application/octet-stream when omitted — set it so mail clients render the file correctly.Note
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:
api_error, timeout, application_error.