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

zaptick

v1.0.0

Published

Official Node.js SDK for the Zaptick WhatsApp Business API

Readme

Zaptick Node.js SDK

Official Node.js/TypeScript SDK for the Zaptick WhatsApp Business API.

  • Full TypeScript support with complete type definitions
  • Zero dependencies — uses native fetch (Node 18+ / Bun)
  • Automatic retries with exponential backoff for rate limits and server errors
  • Resource-based API — clean, intuitive interface inspired by Stripe's SDK

Installation

npm install zaptick
yarn add zaptick
pnpm add zaptick
bun add zaptick

Prerequisites

  1. Create a free Zaptick account
  2. Connect your WhatsApp Business Account
  3. Generate an API key

Quick Start

import Zaptick from 'zaptick';

const zaptick = new Zaptick('zaptick_live_sk_...');

// Send a WhatsApp template message
const result = await zaptick.messages.send({
  phone: '+919876543210',
  templateName: 'welcome_message',
  variables: { '1': 'Rahul' },
});

console.log(result.messageId);

Configuration

Pass a string for simple API key auth, or an object for full control:

const zaptick = new Zaptick({
  apiKey: 'zaptick_live_sk_...',
  baseUrl: 'https://zaptick.io/api',  // default
  timeout: 30000,                      // request timeout in ms (default: 30s)
  maxRetries: 2,                       // retry count for 429/5xx (default: 2)
});

API Reference

Messages

zaptick.messages.send(params)

Send an approved template message. This is the primary way to initiate conversations.

const result = await zaptick.messages.send({
  phone: '+919876543210',        // required — E.164 format
  templateName: 'order_update',  // required — approved template name
  variables: { '1': '#12345' },  // optional — template variables
  language: 'en',                // optional — default: 'en'
});

zaptick.messages.sendText(params)

Send a text message within the 24-hour conversation window.

await zaptick.messages.sendText({
  phone: '+919876543210',
  message: 'Thanks for reaching out! How can I help?',
});

Note: Text messages only work within 24 hours of the customer's last message.

zaptick.messages.sendMedia(params)

Send media (image, video, document, audio) within the conversation window.

await zaptick.messages.sendMedia({
  phone: '+919876543210',
  type: 'image',
  mediaUrl: 'https://example.com/product.jpg',
  caption: 'Check out our latest product!',
});

Templates

zaptick.templates.list(params?)

const { templates } = await zaptick.templates.list();
const marketing = await zaptick.templates.list({ category: 'MARKETING', status: 'APPROVED' });

zaptick.templates.get(id)

const { template } = await zaptick.templates.get('64f1a2b3c4d5e6f7a8b9c0d1');

Contacts

zaptick.contacts.create(params)

const { contact } = await zaptick.contacts.create({
  name: 'Priya Sharma',
  phone: '+919876543210',
  email: '[email protected]',
  tags: ['customer', 'premium'],
  customFields: { plan: 'enterprise' },
});

zaptick.contacts.list(params?)

const { contacts, total } = await zaptick.contacts.list({
  search: 'Priya',
  tags: 'premium',
  limit: 50,
  page: 1,
});

zaptick.contacts.get(id) / zaptick.contacts.update(id, params)

const { contact } = await zaptick.contacts.get('64f1...');
await zaptick.contacts.update('64f1...', { tags: ['premium', 'active'] });

Campaigns

zaptick.campaigns.create(params)

Create a campaign draft.

const { campaign } = await zaptick.campaigns.create({
  name: 'Summer Sale 2026',
  audience: { filters: { tags: ['premium'] } },
  message: {
    type: 'template',
    template: { id: '...', name: 'summer_promo' },
  },
});

zaptick.campaigns.list(params?) / zaptick.campaigns.get(id)

const { campaigns } = await zaptick.campaigns.list({ status: 'sent' });
const { campaign } = await zaptick.campaigns.get('64f1...');
console.log(campaign.detailedStats.delivered, campaign.costBreakdown.totalCost);

zaptick.campaigns.launch(params)

Launch immediately or schedule for later.

const result = await zaptick.campaigns.launch({
  name: 'Flash Sale',
  message: { type: 'template', template: { id: '...', name: 'flash_sale' } },
  audience: { filters: { tags: ['active'] } },
  schedule: { sendTime: '2026-04-10T09:00:00Z', timezone: 'Asia/Kolkata' },
});
console.log(result.billing.totalCost, result.campaign.audienceCount);

zaptick.campaigns.progress(id)

Real-time campaign progress tracking.

const progress = await zaptick.campaigns.progress('64f1...');
console.log(`${progress.progress.percent}% complete`);

Contact Groups

zaptick.contactGroups.create(params)

// Static group
const { group } = await zaptick.contactGroups.create({
  name: 'VIP Customers',
  contacts: ['id1', 'id2', 'id3'],
  color: '#8B5CF6',
});

// Dynamic segment
const { group } = await zaptick.contactGroups.create({
  name: 'Active This Week',
  segmentType: 'dynamic',
  ruleGroups: [{
    conditions: [{ field: 'lastMessageAt', operator: 'within', value: '7d' }],
    operator: 'AND',
  }],
});

zaptick.contactGroups.list() / get(id) / update(id, params) / delete(id)

const { groups } = await zaptick.contactGroups.list({ search: 'VIP' });
await zaptick.contactGroups.update('grp-id', { name: 'Super VIP' });
await zaptick.contactGroups.delete('grp-id');

Analytics

zaptick.analytics.get(params)

Comprehensive analytics and reporting.

const { analytics } = await zaptick.analytics.get({
  wabaId: 'your-waba-id',
  timeRange: 'month',
});

console.log('Total messages:', analytics.totalMessages);
console.log('Active conversations:', analytics.activeConversations);
console.log('Cost:', analytics.costMetrics.totalSpent);

for (const insight of analytics.insights) {
  console.log(`[${insight.type}] ${insight.title}`);
}

Interactive Lists

zaptick.interactiveLists.create(params)

const { list } = await zaptick.interactiveLists.create({
  name: 'Product Menu',
  wabaId: 'your-waba-id',
  body: { text: 'Browse our categories:' },
  action: {
    button: 'View Menu',
    sections: [{
      title: 'Electronics',
      rows: [
        { id: 'phones', title: 'Phones', description: 'Latest smartphones' },
        { id: 'laptops', title: 'Laptops', description: 'Work & gaming' },
      ],
    }],
  },
});

list() / get(id) / update(id, params) / delete(id)

const { lists } = await zaptick.interactiveLists.list({ wabaId: '...' });
await zaptick.interactiveLists.update('list-id', { body: { text: 'Updated menu' } });
await zaptick.interactiveLists.delete('list-id');

Error Handling

The SDK throws typed errors that you can catch and handle:

import Zaptick, {
  ZaptickError,
  ZaptickAuthError,
  ZaptickValidationError,
  ZaptickRateLimitError,
  ZaptickNotFoundError,
} from 'zaptick';

try {
  await zaptick.messages.send({ phone: '+91...', templateName: 'welcome' });
} catch (err) {
  if (err instanceof ZaptickAuthError) {
    console.error('Auth failed:', err.message);       // 401
  } else if (err instanceof ZaptickValidationError) {
    console.error('Validation:', err.message, err.errors);  // 400
  } else if (err instanceof ZaptickRateLimitError) {
    console.error(`Rate limited. Retry after ${err.retryAfter}s`);  // 429
  } else if (err instanceof ZaptickNotFoundError) {
    console.error('Not found:', err.message);          // 404
  } else if (err instanceof ZaptickError) {
    console.error(`Error ${err.status}: ${err.message}`);  // any
  }
}

| Error Class | Status | When | |---|---|---| | ZaptickAuthError | 401 | Invalid API key | | ZaptickForbiddenError | 403 | Insufficient permissions | | ZaptickNotFoundError | 404 | Resource not found | | ZaptickValidationError | 400 | Invalid parameters | | ZaptickRateLimitError | 429 | Too many requests (auto-retried) | | ZaptickConnectionError | — | Network failure, timeout | | ZaptickError | any | Base class for all API errors |

CommonJS Usage

const Zaptick = require('zaptick').default;
const zaptick = new Zaptick('zaptick_live_sk_...');

Bun

The SDK works natively with Bun — zero configuration needed:

bun add zaptick
import Zaptick from 'zaptick';
const zaptick = new Zaptick('zaptick_live_sk_...');
// Works exactly the same as Node.js

Requirements

  • Node.js 18+ or Bun 1.0+
  • Zaptick account with a connected WABA
  • API key (Growth, Advanced, or Enterprise plan)

Links

License

MIT