---
title: "TypeScript SDK"
description: "Official @wazapin/sdk client — typed builders, automatic retries, pagination, and webhook verification."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.wazapin.id/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

`@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).

<section class="wz-sdk-features" aria-label="SDK highlights">
  <div class="wz-sdk-feature">
    <h3>Type-safe builders</h3>
    <p><code>textMessage()</code>, <code>templateMessage()</code>, and other helpers return typed send inputs. Autocomplete on every field.</p>
  </div>
  <div class="wz-sdk-feature">
    <h3>Typed responses</h3>
    <p>Autocomplete on requests and responses. Errors stay in <code>error</code> — handle them when you wire production code.</p>
  </div>
  <div class="wz-sdk-feature">
    <h3>Safe to retry</h3>
    <p>Auto-retries 429 and 5xx with backoff. Pass an <code>idempotencyKey</code> on sends you may retry.</p>
  </div>
  <div class="wz-sdk-feature">
    <h3>Async pagination</h3>
    <p><code>listPaginated()</code> on channels, contacts, and templates. <code>for await</code> exhausts pages for you.</p>
  </div>
  <div class="wz-sdk-feature">
    <h3>Webhook verify</h3>
    <p><code>@wazapin/sdk/webhooks</code> verifies Svix signatures and parses event payloads on your server.</p>
  </div>
  <div class="wz-sdk-feature">
    <h3>Runs anywhere</h3>
    <p>Web-standard <code>fetch</code> only. Node 20+, Bun, Deno, Cloudflare Workers, Vercel — inject custom <code>fetch</code> when needed.</p>
  </div>
</section>

## Install

### npm

```bash
npm install @wazapin/sdk
```
### pnpm

```bash
pnpm add @wazapin/sdk
```
### yarn

```bash
yarn add @wazapin/sdk
```
### bun

```bash
bun add @wazapin/sdk
```

Webhook verification needs the optional `svix` peer:

```bash
npm install @wazapin/sdk svix
```

Requirements: **Node 20+**, ESM or CJS. Types ship with the package.

## Hello, world

```ts
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.

:::tip
For error handling in production, see [Utilities → Error handling](/sdk/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.

```text
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

```ts
// 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

```ts
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
});
```

:::warning
Never ship your API key to the browser. Call Wazapin from your server, serverless function, or background worker only.
:::

## Where to next

- [Quickstart](/sdk/quickstart) — Install, find your channel id, send your first message.
- [Messages](/sdk/messages) — Text, buttons, lists, catalog — plus read, react, and delivery status.
- [Templates](/sdk/templates) — List, sync, and send approved WhatsApp templates.
- [Webhooks](/sdk/webhooks) — Manage endpoints and verify signed deliveries.
- [Utilities](/sdk/utilities) — Builders, pagination, errors, and the low-level API client.
- [API reference](/api-reference) — Every HTTP endpoint with an interactive playground.
- [Other languages](/api/sdks) — cURL, Python, and Go when you are not using TypeScript.

Source: https://docs.wazapin.id/sdk/typescript/index.mdx
