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

@duochat/sdk

v1.0.6

Published

Official JavaScript/TypeScript SDK for DuoChat APIs

Readme

duochat-sdk

Lightweight TypeScript SDK for sending WhatsApp messages via DuoChat.

npm version license types


Overview

duochat-sdk wraps the DuoChat API with a clean, strongly-typed interface so you can send WhatsApp messages and manage leads without touching raw HTTP.

  • One client. Two methods. Production-ready.
  • Send messages and create/manage leads with camelCase, IDE-friendly types.
  • No billing APIs. No workspace internals. No controller soup.

Installation

npm install duochat-sdk axios
# or
pnpm add duochat-sdk axios

axios is a required peer dependency used internally by the SDK.


Quick Start

import { DuoChatClient } from "duochat-sdk";

const duo = new DuoChatClient({
  apiKey: process.env.DUOCHAT_API_KEY!,
});

await duo.sendMessage({
  countryCode: "91",
  phoneNumber: "9999999999",
  type: "text",
  text: "Hello from DuoChat 🚀",
});

API Reference

new DuoChatClient(options)

const duo = new DuoChatClient({
  apiKey: string;    // required — generate at https://duochat.io
  baseUrl?: string;  // optional — defaults to https://api.duochat.in
});

duo.sendMessage(input)

import { MessageType } from "duochat-sdk";

await duo.sendMessage({
  countryCode: string;       // e.g. "91"
  phoneNumber: string;       // without country code
  type: MessageType;         // "text" | "template" | "image" | ...

  // type: MessageType.TEXT
  text?: string;

  // type: MessageType.TEMPLATE
  templateName?: string;
  components?: Array<Record<string, any>>;

  // type: MessageType.IMAGE / VIDEO / DOCUMENT / AUDIO
  media?: Record<string, any>;

  // optional — attaches lead name to conversation
  lead_name?: string;
});

Text Message

await duo.sendMessage({
  countryCode: "91",
  phoneNumber: "9876543210",
  type: MessageType.TEXT,
  text: "Your order has been shipped.",
});

Template Message

await duo.sendMessage({
  countryCode: "91",
  phoneNumber: "9876543210",
  type: MessageType.TEMPLATE,
  templateName: "order_confirmed",
  components: [
    {
      type: "body",
      parameters: [{ type: "text", text: "ORD-12345" }],
    },
  ],
});

Media Message

await duo.sendMessage({
  countryCode: "91",
  phoneNumber: "9876543210",
  type: MessageType.IMAGE,
  media: {
    id: "MEDIA_ID_FROM_DUOCHAT",
    caption: "Here's your invoice",
  },
});

duo.createLead(input)

Creates or upserts a lead in your DuoChat workspace.

import { LeadSource } from "duochat-sdk";

await duo.createLead({
  countryCode?: string;           // e.g. "91"
  phoneNumber?: string;           // without country code
  name?: string;
  email?: string;
  tagsId?: string[];              // array of tag IDs to assign
  customFields?: Array<{
    fieldId: string;
    value: string;
  }>;
  isOptedIn?: boolean;            // WhatsApp opt-in status
  source?: LeadSource;            // where the lead originated
  companyName?: string;
  assignedToUserId?: string;      // assign to a workspace user
  instagramUsername?: string;
  leadLifecycleId?: string;
  customField?: Record<string, any>;
});

Basic Lead

await duo.createLead({
  countryCode: "91",
  phoneNumber: "9876543210",
  name: "Rahul Sharma",
  email: "[email protected]",
  isOptedIn: true,
  source: LeadSource.SDK,
});

Lead with Tags and Custom Fields

await duo.createLead({
  countryCode: "91",
  phoneNumber: "9876543210",
  name: "Priya Mehta",
  tagsId: ["tag_vip", "tag_renewal"],
  customFields: [
    { fieldId: "plan_type", value: "enterprise" },
    { fieldId: "region",    value: "north" },
  ],
  source: LeadSource.SHOPIFY,
  companyName: "Acme Corp",
});

LeadSource values

| Constant | When to use | | ---------------------------- | ------------------------------------ | | LeadSource.SDK | Programmatic / API creation (default)| | LeadSource.SHOPIFY | Shopify store integration | | LeadSource.GOOGLE_SHEETS | Google Sheets import | | LeadSource.CLICK_TO_WHATSAPP_AD | CTWA / Meta ad click | | LeadSource.META_LEAD_FORM | Meta lead gen form | | LeadSource.ORGANIC | Organic inbound | | LeadSource.CHAT_WIDGET | Website chat widget | | LeadSource.INSTAGRAM | Instagram DM | | LeadSource.CTWA | Click-to-WhatsApp ad (alias) | | LeadSource.ZOHO_CRM | Zoho CRM sync | | LeadSource.MESSENGER | Facebook Messenger |


Error Handling

The SDK throws structured ApiError instances on failed requests — no more guessing from raw HTTP responses.

import { ApiError } from "duochat-sdk";

try {
  await duo.sendMessage({ ... });
  await duo.createLead({ ... });
} catch (err) {
  if (err instanceof ApiError) {
    console.error(`[${err.status}]`, err.body);
  } else {
    throw err;
  }
}

| Error Type | Cause | | ------------------- | ----------------------------- | | 401 Unauthorized | Invalid or missing API key | | 400 Bad Request | Invalid or missing fields | | 422 Unprocessable | Payload failed server validation | | 5xx | DuoChat server-side error | | Network error | No connectivity / timeout |


Security

This SDK is designed for server-side use only.

| ✅ Use here | ❌ Don't use here | | -------------------- | ----------------- | | Node.js backends | Browser / client | | Serverless functions | React / Vue apps | | Workers / cron jobs | Mobile apps |

If you need to trigger messages from the frontend, proxy the request through your own backend endpoint.


Versions

| Component | Version | | --------- | ------- | | SDK | 1.x | | API | 1.0.0 |


Support


License

MIT © DuoChat