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

@raphaelvserafim/client-api-whatsapp

v1.7.0

Published

With our API, you can send text, audio, video, and image messages quickly and easily. Adapt to your business communication needs comprehensively.

Readme

WhatsApp API

About Our WhatsApp API

Unlock the Potential of WhatsApp: Powerful Integration with Our Unofficial API!

Efficient Group Management on WhatsApp

Our stable, though unofficial, API allows for efficient management of WhatsApp groups. Simplify administration, and easily add or remove members.

Versatile Message Sending

With our API, you can send text, audio, video, and image messages quickly and easily. Adapt to your business communication needs comprehensively.

Receive Instant Events

Stay updated with our API, receiving real-time events when new messages are received. Stay connected and agile in responding to interactions on WhatsApp.

Create Your Account: Visit https://api-wa.me/sign-up to create your account and start using our API today!

Contact Support

Installation

npm i @raphaelvserafim/client-api-whatsapp
yarn add @raphaelvserafim/client-api-whatsapp

Quick Start

import { WhatsApp, TypeMessage, StatusPresence } from '@raphaelvserafim/client-api-whatsapp';

const wa = new WhatsApp({ server: "https://us.api-wa.me", key: "YOUR_KEY" });

const to = "559999999999"; // Group: "[email protected]"

Backward Compatible: All legacy methods (wa.sendMessage(), wa.groups(), etc.) still work. The new service-based API is optional.


Instance

// Connect via QR Code
const qr = await wa.instance.connect();

// Connect via Pairing Code
const code = await wa.instance.pairingCode("559999999999");

// Get instance info
const info = await wa.instance.info();

// Logout
await wa.instance.logout();

// Restart
await wa.instance.restart();

// Settings
await wa.instance.setting({
  markMessageRead: true,
  saveMedia: false,
  receiveStatusMessage: false,
  receivePresence: false,
});

// Webhook
await wa.instance.updateWebhook({
  allowWebhook: true,
  allowNumber: "all",
  webhookMessage: "https://your-webhook.com/message",
  webhookGroup: "",
  webhookConnection: "",
  webhookQrCode: "",
  webhookMessageFromMe: "",
  webhookHistory: "",
});

// Webhook Statistics
const stats = await wa.instance.webhookStatistics();

// Profile
await wa.instance.updateProfileName("My Bot");
await wa.instance.updateProfileStatus("Online");
await wa.instance.updateProfilePicture("https://avatars.githubusercontent.com/u/68257896");
await wa.instance.removeProfilePicture();

// Proxy
await wa.instance.setProxy("http://user:pass@ip:port");

// MongoDB
await wa.instance.addMongoDb("mongodb+srv://...", "mydb");

// Mobile Registration (3 steps)
await wa.instance.mobileRegisterPrepare({
  phoneNumberCountryCode: "55",
  phoneNumberNationalNumber: "99999999999",
  phoneNumberMobileNetworkCode: "11",
});
await wa.instance.mobileRequestCode("sms");
await wa.instance.mobileVerifyCode("123456");

// Import a WhatsApp Web session (WAME Passkey app)
await wa.instance.importWebSession({ /* session object */ });

// Official number (Cloud API)
await wa.instance.officialRegister("123456");      // register with 2FA PIN
await wa.instance.officialTwoStepPin("123456");    // set two-step verification PIN
await wa.instance.officialDeregister();            // deregister

Receiving Webhooks

Configure your instance with webhookFormat: "meta" and use parseWebhook to turn the incoming POST body into an array of fully-typed, normalized events. A single request can batch several events, so parseWebhook always returns an array. It never throws: unrecognized events become { type: "unknown" } and an invalid body returns [], so your endpoint can always respond 200.

import express from "express";
import { parseWebhook } from "@raphaelvserafim/client-api-whatsapp";

const app = express();
app.use(express.json());

app.post("/webhook", (req, res) => {
  for (const event of parseWebhook(req.body)) {
    // event.instanceId / event.metadata.phoneNumberId are always available
    switch (event.type) {
      case "text":
        console.log(`${event.from}: ${event.text.body}`);
        if (event.context) console.log(`↪ reply to ${event.context.id}`);
        break;
      case "image":
        console.log("image url:", event.image.url);
        break;
      case "button-reply":
        console.log("button:", event.buttonReply.id, event.buttonReply.title);
        break;
      case "list-reply":
        console.log("list:", event.listReply.id);
        break;
      case "reaction":
        console.log("reaction:", event.reaction.emoji);
        break;
      case "status":
        console.log("message", event.messageId, "is", event.status);
        break;
      case "connection.open":
        console.log("connected");
        break;
      case "connection.close":
        console.log("disconnected:", event.code, event.reason);
        break;
      case "qrcode":
        console.log("scan qr (base64 png):", event.code);
        break;
      case "call":
        console.log("incoming call from", event.from, "video:", event.isVideo);
        break;
      case "group.participants":
        console.log("group", event.groupId, event.action, event.participants);
        break;
      case "health":
        console.log("health:", event.status);
        break;
      default:
        // event.raw holds the untouched envelope for anything else
        break;
    }
  }

  res.sendStatus(200);
});

Event type values: text, image, audio, video, document, sticker, location, contacts, reaction, reaction-removed, button, list-reply, button-reply, referral, edit, unsupported, status, presence, connection.open, connection.close, qrcode, call, group.participants, group.update, health, unknown. Every event also carries instanceId, metadata, field and raw (the original envelope) — see the exported WhatsAppWebhookEvent union for full typings.

Messages

Send Messages

// Text
await wa.message.send({
  type: TypeMessage.TEXT,
  body: { to, text: "Hello!" },
});

// Image
await wa.message.send({
  type: TypeMessage.IMAGE,
  body: { to, url: "https://a.cdn-hotels.com/gdcs/production190/d988/1071675e-1bd7-4a81-8b40-735eb9241410.jpg", caption: "Toronto" },
});

// Audio
await wa.message.send({
  type: TypeMessage.AUDIO,
  body: { to, url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3" },
});

// Video
await wa.message.send({
  type: TypeMessage.VIDEO,
  body: { to, url: "https://www.w3schools.com/html/mov_bbb.mp4", caption: "Big Buck Bunny" },
});

// Document
await wa.message.send({
  type: TypeMessage.DOCUMENT,
  body: { to, url: "https://raphaelvserafim.com/RaphaelSerafimResume.pdf", mimetype: "application/pdf", fileName: "Resume.pdf" },
});

// Contact
await wa.message.send({
  type: TypeMessage.CONTACT,
  body: {
    to,
    contact: { fullName: "Raphael", phoneNumber: "559999999999", organization: "api-wa.me" },
  },
});

// Location
await wa.message.send({
  type: TypeMessage.LOCATION,
  body: {
    to,
    location: { latitude: 37.7749, longitude: -122.4194, address: "San Francisco, CA" },
  },
});

// Reaction
await wa.message.send({
  type: TypeMessage.REACTION,
  body: { to, msgId: "MESSAGE_ID", text: "👍" },
});

// Link Preview
await wa.message.send({
  type: TypeMessage.LINK,
  body: {
    to,
    title: "API WhatsApp",
    text: "Check out our API",
    description: "Powerful WhatsApp integration",
    thumbnailUrl: "https://avatars.githubusercontent.com/u/68257896",
    sourceUrl: "https://api-wa.me",
  },
});

// Title with Footer
await wa.message.send({
  type: TypeMessage.TITLE,
  body: { to, title: "Order #123", text: "Your order is ready", footer: "Thank you!" },
});

// Presence
await wa.message.send({
  type: TypeMessage.PRESENCE,
  body: { to, status: StatusPresence.COMPOSING },
});

Reply to a Message

Pass true as second argument and include msgId:

await wa.message.send({
  type: TypeMessage.TEXT,
  body: { to, text: "This is a reply!", msgId: "ORIGINAL_MSG_ID" },
}, true);

Button Messages

// Quick Reply Buttons
await wa.message.send({
  type: TypeMessage.BUTTON_REPLY,
  body: {
    to,
    header: { title: "Choose an option" },
    text: "What do you prefer?",
    footer: "Select one",
    buttons: [
      { type: "quick_reply", id: "1", text: "Yes" },
      { type: "quick_reply", id: "2", text: "No" },
    ],
  },
});

// Call to Action Buttons
await wa.message.send({
  type: TypeMessage.BUTTON_ACTION,
  body: {
    to,
    header: { title: "Actions" },
    text: "Choose an action",
    footer: "Select one",
    buttons: [
      { type: "cta_url", url: "https://api-wa.me", text: "Visit website" },
      { type: "cta_call", phone_number: "+559999999999", text: "Call us" },
      { type: "cta_copy", copy_code: "PROMO2025", text: "Copy code" },
    ],
  },
});

// Buttons with Media Header
await wa.message.send({
  type: TypeMessage.BUTTON_REPLY,
  body: {
    to,
    header: {
      title: "Check this out",
      hasMediaAttachment: true,
      imageMessage: { url: "https://a.cdn-hotels.com/gdcs/production190/d988/1071675e-1bd7-4a81-8b40-735eb9241410.jpg" },
    },
    text: "What do you think?",
    buttons: [
      { type: "quick_reply", id: "1", text: "Like" },
      { type: "quick_reply", id: "2", text: "Dislike" },
    ],
  },
});

List Menu

await wa.message.send({
  type: TypeMessage.MENU,
  body: {
    to,
    buttonText: "View Menu",
    text: "Choose an item",
    title: "Menu",
    description: "Our products",
    footer: "Prices may vary",
    sections: [
      {
        title: "Pizzas",
        rows: [
          { title: "Margherita", description: "Classic cheese pizza", rowId: "1" },
          { title: "Pepperoni", description: "Spicy pepperoni", rowId: "2" },
        ],
      },
      {
        title: "Drinks",
        rows: [
          { title: "Cola", description: "350ml", rowId: "3" },
        ],
      },
    ],
  },
});

Poll / Survey

// Survey (via sendMessage)
await wa.message.send({
  type: TypeMessage.POLL,
  body: { to, name: "Do you like TypeScript?", options: ["Yes", "No"] },
});

// Poll (dedicated method with selectableCount)
await wa.message.sendPoll(to, "Favorite language?", ["TypeScript", "Python", "Go"], 1);

PIX Payment

await wa.message.send({
  type: TypeMessage.BUTTON_PIX,
  body: {
    to,
    title: "Pizza Order",
    text: "Your order details",
    referenceId: "order-123",
    code: "0020101021226700014br.gov.bcb.pix",
    key: "23711695000115",
    merchantName: "MY STORE",
    keyType: "CNPJ",
    items: [
      { id: "1", name: "Pizza G", price: 45, quantity: 2 },
      { id: "2", name: "Soda", price: 8, quantity: 2 },
    ],
    subtotal: "106",
    totalAmount: "106",
  },
});

Sticker, Video Note, Event, Pin, Call Link

// Sticker
await wa.message.sendSticker(to, "https://www.gstatic.com/webp/gallery/1.webp");

// Video Note (circular/PTV)
await wa.message.sendVideoNote(to, "https://www.w3schools.com/html/mov_bbb.mp4");

// Event
await wa.message.sendEvent({
  to,
  name: "Team Meeting",
  description: "Weekly sync",
  startTime: "2025-01-15T14:00:00Z",
  locationName: "Office",
  locationAddress: "123 Main St",
});

// Pin Message
await wa.message.pin("MESSAGE_ID", 604800); // 7 days in seconds

// Call Link
await wa.message.sendCallLink(to, "video", "Join the meeting");

Base64 Messages

await wa.message.sendImageBase64(to, "data:image/png;base64,...", "Caption");
await wa.message.sendAudioBase64(to, "data:audio/mp3;base64,...");
await wa.message.sendDocumentBase64(to, "data:application/pdf;base64,...", "application/pdf", "file.pdf", "My document");

Forward & List Messages

// Forward a message
await wa.message.forward(to, "MESSAGE_ID");

// List messages from a contact
const messages = await wa.message.list("559999999999", 1, 20);

Additional Message Methods

// Unpin message
await wa.message.unpin("MESSAGE_ID");

// Send multiple contacts
await wa.message.sendContacts({ to, displayName: "My Contacts", contacts: [{ fullName: "Name", phoneNumber: "559999999999" }] });

// Send live location
await wa.message.sendLiveLocation({ to, latitude: 37.7749, longitude: -122.4194, caption: "I'm here" });

// Get message details
await wa.message.getDetails("MESSAGE_ID");

// Get message media
await wa.message.getMedia("MESSAGE_ID", "base64");

// Send product message
await wa.message.sendProduct({ to, businessOwnerJid: "[email protected]", productId: "product_id", catalogId: "catalog_id" });

// Send group invite
await wa.message.sendGroupInvite({ to, groupJid: "[email protected]", groupName: "Developers", inviteCode: "ABC123" });

// Request phone number
await wa.message.requestPhone(to);

// Create call link (without sending)
await wa.message.createCallLink("video");

// Mark a message as read (and optionally show typing)
await wa.message.markRead("MESSAGE_ID", true);

// Send an approved template message (official only)
await wa.message.sendTemplate({ to, name: "order_confirmation", language: "pt_BR", components: [] });

// Request the recipient to share their location
await wa.message.sendLocationRequest(to, "Please share your location");

// Send a message with ad context
await wa.message.sendAd({ to, text: "Check this out", sourceUrl: "https://example.com" });

// Send a product list (official only)
await wa.message.sendProductList({ to, header: "Our products", body: "Pick one", sections: [], catalogId: "catalog_id" });

// Order with payment link (Payments BR)
await wa.message.sendOrderDetails({
  to, text: "Your order", title: "Order #123", referenceId: "REF123",
  paymentLinkUri: "https://pay.example.com/123", totalAmount: 10000, subtotal: 10000,
  items: [{ name: "Item", amount: 10000, quantity: 1 }],
});

// Update an order status (official only — Payments BR)
await wa.message.sendOrderStatus({ to, referenceId: "REF123", status: "shipped" });

Chat

// List all chats
const chats = await wa.chat.list();

// Get messages from a chat
const msgs = await wa.chat.messages("[email protected]");

// Mark as read
await wa.chat.modify("[email protected]", "markRead", true);

// Pin chat
await wa.chat.modify("[email protected]", "pin", true);

// Delete chat
await wa.chat.delete("[email protected]");

// Subscribe to presence updates
await wa.chat.presenceSubscribe("[email protected]");

// Set disappearing messages
await wa.chat.disappearing("[email protected]", 86400);

// Get privacy settings
const privacy = await wa.chat.privacy();

Call

// Make a call
await wa.call.call(to, false);      // audio
await wa.call.call(to, true);       // video

// Reject a call
await wa.call.reject("CALL_ID", "[email protected]");

// Accept a call
await wa.call.accept("CALL_ID", "[email protected]");

// End a call
await wa.call.end("CALL_ID", "[email protected]");

// Send audio into an active call
await wa.call.sendAudio("CALL_ID", { url: "https://example.com/audio.mp3" });

Labels

// List labels
const labels = await wa.label.list();

// Create label
await wa.label.create("VIP");

// Add label to chat
await wa.label.addToChat("label_id", to);

// Get chats with label
const labeled = await wa.label.getChats("label_id");

// Remove label from chat
await wa.label.removeFromChat("label_id", to);

// Delete label
await wa.label.delete("label_id");

Contacts

// List all contacts
const contacts = await wa.contact.list();

// Get contact profile
const profile = await wa.contact.profile("559999999999");

// Block / Unblock
await wa.contact.block("559999999999", "block");
await wa.contact.block("559999999999", "unblock");

// Check if registered on WhatsApp
const check = await wa.action.checkRegistered("559999999999");

// Add contact
await wa.contact.add("559999999999", "Raphael");

// Remove contact
await wa.contact.remove("559999999999");

// Clear contact session
await wa.contact.clearSession("559999999999");

// Get contact status
await wa.contact.getStatus("559999999999");

// List blocked contacts
const blocked = await wa.contact.listBlocked();

// Resolve LIDs
await wa.contact.resolveLids(["lid1", "lid2"]);

Groups

// List groups
const groups = await wa.group.list();

// Group info
const info = await wa.group.info("[email protected]");

// Create group
const newGroup = await wa.group.create("Developers", ["559999999999"]);

// Update group
await wa.group.update("[email protected]", "New Name", "New description");

// Change settings
await wa.group.changeSettings("[email protected]", "announcement");     // only admins can send
await wa.group.changeSettings("[email protected]", "not_announcement"); // everyone can send
await wa.group.changeSettings("[email protected]", "locked");           // only admins edit info
await wa.group.changeSettings("[email protected]", "unlocked");         // everyone can edit info

// Invite code
const invite = await wa.group.getInviteCode("[email protected]");

// Group picture
await wa.group.updatePicture("[email protected]", "https://a.cdn-hotels.com/gdcs/production190/d988/1071675e-1bd7-4a81-8b40-735eb9241410.jpg");
await wa.group.removePicture("[email protected]");

// Participants
await wa.group.addParticipants("[email protected]", ["559999999999"]);
await wa.group.removeParticipants("[email protected]", ["559999999999"]);
await wa.group.updateParticipantRole("[email protected]", "promote", ["559999999999"]);
await wa.group.updateParticipantRole("[email protected]", "demote", ["559999999999"]);

// Pending participants
const pending = await wa.group.getRequestParticipants("[email protected]");
await wa.group.updateRequestParticipants("[email protected]", {
  participants: ["559999999999"],
  action: "approve",
});

// Leave group
await wa.group.leave("[email protected]");

// Get group members
const members = await wa.group.getMembers("[email protected]");

// Get invite info from code
const inviteInfo = await wa.group.getInviteInfo("INVITE_CODE");

// Check groups readiness (diagnostic)
await wa.group.readiness();

Community

// List communities
const communities = await wa.community.list();

// Create community
const newComm = await wa.community.create({ name: "My Community", subject: "Tech" });

// Community info
const commInfo = await wa.community.info("community_id");

// Update community
await wa.community.update("community_id", { subject: "Updated", description: "New description" });

// Community picture
await wa.community.updatePicture("community_id", "https://a.cdn-hotels.com/gdcs/production190/d988/1071675e-1bd7-4a81-8b40-735eb9241410.jpg");

// Invite code
const commInvite = await wa.community.getInviteCode("community_id");

// Participants
await wa.community.removeParticipants("community_id", ["559999999999"]);
const commPending = await wa.community.getRequestParticipants("community_id");
await wa.community.updateRequestParticipants("community_id", {
  participants: ["559999999999"],
  action: "approve",
});

// Leave community
await wa.community.leave("community_id");

// Accept invite
await wa.community.acceptInvite("INVITE_CODE");

// Get invite info
await wa.community.getInviteInfo("INVITE_CODE");

// Create group inside community
await wa.community.createGroup("community_id", { subject: "New Group", participants: ["559999999999"] });

// Set ephemeral messages
await wa.community.ephemeral("community_id", 86400);

// Update community settings
await wa.community.updateSettings("community_id", "announcement");

// Set member add mode
await wa.community.memberAddMode("community_id", "admin_add");

// Set join approval mode
await wa.community.joinApproval("community_id", "on");

Business

// Get catalog
const catalog = await wa.business.getCatalog();
const catalogPage = await wa.business.getCatalog(10, "cursor_token");

// Create product
await wa.business.createProduct({
  name: "Premium T-Shirt",
  description: "100% cotton",
  originCountryCode: "BR",
  currency: "BRL",
  price: 79.90,
  images: [{ url: "https://a.cdn-hotels.com/gdcs/production190/d988/1071675e-1bd7-4a81-8b40-735eb9241410.jpg" }],
});

// Update product
await wa.business.updateProduct("product_id", {
  name: "Premium T-Shirt v2",
  price: 89.90,
});

// Delete product
await wa.business.deleteProduct("product_id");

// List collections
await wa.business.getCollections(10);

// Get order details
await wa.business.getOrder("order_id", "token");

// Commerce settings (official only)
await wa.business.getCommerceSettings();
await wa.business.updateCommerceSettings({ isCartEnabled: true, isCatalogVisible: true });

Newsletter

// Create a newsletter
await wa.newsletter.create("My Newsletter", "Description");

// Get metadata
await wa.newsletter.getMetadata("type", "newsletter_id");

// Get subscribers & admins
await wa.newsletter.getSubscribers("newsletter_id");
await wa.newsletter.getAdmins("newsletter_id");

// Follow / Unfollow
await wa.newsletter.follow("newsletter_id");
await wa.newsletter.unfollow("newsletter_id");

// Update
await wa.newsletter.updateName("newsletter_id", "New Name");
await wa.newsletter.updateDescription("newsletter_id", "New description");
await wa.newsletter.updatePicture("newsletter_id", "https://example.com/pic.jpg");
await wa.newsletter.removePicture("newsletter_id");

// Transfer ownership & demote admin
await wa.newsletter.transferOwnership("newsletter_id", "new_owner_jid");
await wa.newsletter.demoteAdmin("newsletter_id", "user_jid");

// Messages
await wa.newsletter.getMessages("newsletter_id", 10);

// React to a message
await wa.newsletter.react("newsletter_id", "server_id", "👍");

// Mute / Unmute
await wa.newsletter.mute("newsletter_id");
await wa.newsletter.unmute("newsletter_id");

// Delete
await wa.newsletter.delete("newsletter_id");

Status

// Text status
await wa.status.sendText({ text: "Hello World!", statusJidList: ["[email protected]"] });

// Image status
await wa.status.sendImage({ url: "https://example.com/image.jpg", caption: "My photo", statusJidList: ["[email protected]"] });

// Video status
await wa.status.sendVideo({ url: "https://example.com/video.mp4", caption: "My video" });

// Audio status
await wa.status.sendAudio({ url: "https://example.com/audio.mp3" });

// Mention a status
await wa.status.mention({ jid: "[email protected]", statusMsgId: "STATUS_MSG_ID" });

Actions

// Check if number is on WhatsApp
const result = await wa.action.checkRegistered("559999999999");

// Download media (deprecated)
const media = await wa.action.downloadMedia("image", {
  mediaKey: "...",
  directPath: "...",
  url: "...",
});

// Delete stored media
await wa.action.deleteStorage();

Templates (official only)

// List templates
await wa.templates.list();

// Create a template
await wa.templates.create({
  name: "order_confirmation",
  language: "pt_BR",
  category: "UTILITY",
  components: [{ type: "BODY", text: "Your order {{1}} is confirmed." }],
});

// Upload a header media sample and get its handle
await wa.templates.uploadHeaderMedia("https://example.com/header.jpg");

// Get / edit / delete
await wa.templates.get("template_id");
await wa.templates.update("template_id", { category: "MARKETING" });
await wa.templates.delete("order_confirmation");

Analytics (official only)

await wa.analytics.usage();
await wa.analytics.conversations({ start: "2026-01-01", end: "2026-01-31", granularity: "DAILY" });
await wa.analytics.messages({ start: "2026-01-01", end: "2026-01-31" });
await wa.analytics.templates({ start: "2026-01-01", end: "2026-01-31" });
await wa.analytics.pricing({ start: "2026-01-01", end: "2026-01-31" });

Calling (official only)

// Get / update calling settings
await wa.calling.getSettings();
await wa.calling.updateSettings({ status: "ENABLED" });

// Control a call: connect / pre_accept / accept / reject / terminate
await wa.calling.controlCall({ action: "accept", callId: "CALL_ID", to: "559999999999" });

Conversation (official only)

// Get / update conversational components
await wa.conversation.getComponents();
await wa.conversation.updateComponents({
  enableWelcomeMessage: true,
  prompts: [],
  commands: [],
});

Custom HTTP Client

You can inject your own HTTP client (e.g., fetch, got, undici) for full control:

import { WhatsApp, IHttpClient, RequestOptions } from '@raphaelvserafim/client-api-whatsapp';

class MyHttpClient implements IHttpClient {
  async request<T>(options: RequestOptions): Promise<T> {
    const response = await fetch(`https://us.api-wa.me/MY_KEY/${options.route}`, {
      method: options.method,
      headers: { 'Content-Type': 'application/json' },
      body: options.body ? JSON.stringify(options.body) : undefined,
    });
    return response.json() as Promise<T>;
  }
}

const wa = new WhatsApp(
  { server: "https://us.api-wa.me", key: "MY_KEY" },
  new MyHttpClient(),
);

Error Handling

All API errors throw WhatsAppError with status code and response body:

import { WhatsAppError } from '@raphaelvserafim/client-api-whatsapp';

try {
  await wa.message.send({ type: TypeMessage.TEXT, body: { to, text: "Hello" } });
} catch (error) {
  if (error instanceof WhatsAppError) {
    console.error(error.message);       // Error message
    console.error(error.statusCode);    // HTTP status code (e.g., 401, 404)
    console.error(error.responseBody);  // API response body
  }
}