npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@usezend/node

v0.2.1

Published

Official Node.js/TypeScript client for the Zend messaging platform

Readme

@usezend/node

Official Node.js/TypeScript client for the Zend messaging platform. Send SMS, WhatsApp, email, and voice messages — and manage message templates — from a single, typed client.

📚 Read the docs →

Installation

npm i @usezend/node

Requires Node.js 18 or later (uses the global fetch and FormData APIs).

Usage

Create a client with your API key:

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

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

The API key can also be supplied via the ZEND_API_KEY environment variable, in which case you can construct the client with no arguments:

const zend = new Zend();

You can override the base URL (e.g. for a staging environment) or the request timeout, in milliseconds, via options — or the ZEND_BASE_URL environment variable:

const zend = new Zend('sent_live_...', {
  baseUrl: 'https://staging.api.tryzend.com',
  timeout: 30_000,
});

Note: baseUrl defaults to https://api.tryzend.com, and timeout defaults to 30s.

Every method returns a promise that resolves to { data, error } — see Errors below.

Send SMS / WhatsApp

Send a plain-text SMS:

const sms = await zend.messages.send({
  to: '+233201234567',
  body: 'Hello from Zend!',
  preferredChannels: ['sms'],
  senderId: 'MyBrand',
  fallbackEnabled: true,
  priority: 'high',
  deliveryPriority: 'speed',
  webhookUrl: 'https://your-app.com/webhooks/zend',
});

if (sms.error) throw sms.error;
console.log(`Message ${sms.data.id} (${sms.data.status})`);

Send over WhatsApp with a template, falling back to SMS:

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

Media (images, documents) on WhatsApp is defined in the approved template itself, not passed at send time.

Send to many recipients in one call:

await zend.messages.sendBulk({
  messages: [
    { to: '+233201234567', body: 'Hi Ama!' },
    { to: '+233207654321', body: 'Your code is 123456', templateParams: { code: '123456' } },
  ],
  preferredChannels: ['sms'],
  senderId: 'MyBrand',
  fallbackEnabled: true,
  webhookUrl: 'https://your-app.com/webhooks/zend',
});

Other messages methods: get(id), list(params?), cancel(id), retry(id).

Send Email

const email = await zend.emails.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Hello world',
  html: '<p>It works!</p>',
  text: 'It works!',
});

if (email.error) throw email.error;
console.log(`Email ${email.data.id} sent`);

Attach files with attachmentscontent is a Buffer or base64 string:

await zend.emails.send({
  from: '[email protected]',
  to: '[email protected]',
  subject: 'Your invoice',
  html: '<p>Invoice attached.</p>',
  attachments: [{ filename: 'invoice.pdf', content: pdfBuffer, contentType: 'application/pdf' }],
});

Limits: at most 10 attachments, 7 MB total.

Other emails methods: get(id), list(params?).

Send Voice

Send a call using text-to-speech, falling back to SMS if it isn't answered:

await zend.voice.send({
  recipients: ['+233201234567'],
  text: 'Your order has shipped.',
  voice: 'female',
  retry: true,
  callbackUrl: 'https://your-app.com/webhooks/voice',
  fallback: {
    sms: true,
    smsText: 'Your order has shipped.',
    senderId: 'MyBrand',
  },
});

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

await zend.voice.send({
  recipients: ['+233201234567'],
  voiceUrl: 'https://cdn.example.com/message.mp3',
  fallback: { sms: true, smsText: 'You have a new message.' },
});

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

Other voice methods: get(batchId), list(params?), upload(file, filename).

Templates

Templates are read-only from this SDK — list and fetch templates managed elsewhere:

const templates = await zend.templates.list({
  category: 'transactional',
  status: 'active',
  limit: 20,
  offset: 0,
});

console.log(`You have ${templates.data?.total ?? 0} templates`);
const template = await zend.templates.get('welcome');
console.log(template.data?.name);

list() accepts optional filters: { category?, status?, limit?, offset? }.

Errors

Every SDK method resolves — it never throws for API or network errors. The result is always one of:

{ data: T; error: null } | { data: null; error: ZendError }

Check error before using data:

const sms = await zend.messages.send({ to: '+233201234567', body: 'Hello!' });

if (sms.error) {
  throw sms.error;
}

console.log(sms.data.id);

ZendError extends Error and adds:

  • name — e.g. "api_error", "timeout", "application_error"
  • statusCode — HTTP status code, when available
  • code — provider error code, when available

Full example

See examples/quickstart.ts for a complete, type-checked walkthrough of sending SMS, WhatsApp, email, and voice messages, plus listing templates.