@wazapin/sdk is the official TypeScript client for the Wazapin API. Use message builders for typed sends, let the client retry transient failures, paginate with for await, and verify webhook signatures — all on web-standard fetch (Node 20+, Bun, Deno, edge).

Type-safe builders

textMessage(), templateMessage(), and other helpers return typed send inputs. Autocomplete on every field.

Typed responses

Autocomplete on requests and responses. Errors stay in error — handle them when you wire production code.

Safe to retry

Auto-retries 429 and 5xx with backoff. Pass an idempotencyKey on sends you may retry.

Async pagination

listPaginated() on channels, contacts, and templates. for await exhausts pages for you.

Webhook verify

@wazapin/sdk/webhooks verifies Svix signatures and parses event payloads on your server.

Runs anywhere

Web-standard fetch only. Node 20+, Bun, Deno, Cloudflare Workers, Vercel — inject custom fetch when needed.

Install

npm install @wazapin/sdk
Webhook verification needs the optional svix peer:
npm install @wazapin/sdk svix
Requirements: Node 20+, ESM or CJS. Types ship with the package.

Hello, world

import { WazapinClient, textMessage } from "@wazapin/sdk";

const wazapin = new WazapinClient({
  apiKey: process.env.WAZAPIN_API_KEY!,
});

const { data: message } = await wazapin.messages.send(
  textMessage({
    channel_id: "wzp_ch_123",
    to: "6281234567890",
    body: "Hello from @wazapin/sdk",
  }),
);

console.log(message.id, message.status);
That’s the whole contract: create a client, pick your channel_id, call a resource method.
For error handling in production, see Utilities → Error handling.

Resource layout

Wazapin scopes most messaging work to a channel (your connected WhatsApp number). Pass channel_id on sends; list channels once at startup and cache the id.
wazapin                              ← root client
├── wazapin.messages                 ← send, get, status, read, react
├── wazapin.channels                 ← list, get, status
├── wazapin.contacts                 ← list, create, lookup, getByPhone
├── wazapin.templates                ← list, get, sync
├── wazapin.media                    ← upload, list, delete
├── wazapin.webhooks                 ← endpoints, deliveries, test
├── wazapin.apiKeys                  ← list, create, delete
├── wazapin.system                   ← health, version
└── wazapin.api                      ← raw OpenAPI client for advanced paths

Common calls

// List connected channels — copy id into your integration
const { data: channels } = await wazapin.channels.list({ limit: 20 });

// Send a template notification
import { templateMessage } from "@wazapin/sdk";

await wazapin.messages.send(
  templateMessage({
    channel_id: "wzp_ch_123",
    to: "6281234567890",
    name: "order_shipped",
    language: "id",
    components: [{ type: "body", parameters: [{ type: "text", text: "ORD-42" }] }],
  }),
);

// Paginate contacts
for await (const contact of wazapin.contacts.listPaginated({ limit: 50 })) {
  console.log(contact.id);
}

Configuration

new WazapinClient({
  apiKey: "wzp_...",              // required — or set WAZAPIN_API_KEY
  baseUrl: "https://api.wazapin.com", // optional — or WAZAPIN_BASE_URL
  timeoutMs: 30_000,              // optional, default 30s
  maxRetries: 3,                  // optional, default 3 (429 / 5xx)
  fetch: customFetch,             // optional, default globalThis.fetch
});
Never ship your API key to the browser. Call Wazapin from your server, serverless function, or background worker only.

Where to next

Quickstart

Install, find your channel id, send your first message.

Messages

Text, buttons, lists, catalog — plus read, react, and delivery status.

Templates

List, sync, and send approved WhatsApp templates.

Webhooks

Manage endpoints and verify signed deliveries.

Utilities

Builders, pagination, errors, and the low-level API client.

API reference

Every HTTP endpoint with an interactive playground.

Other languages

cURL, Python, and Go when you are not using TypeScript.