# Node.js SDK

> Install the whabuzz package, send your first message in ten lines, verify webhooks.

Canonical: https://docs.whabuzz.com/sdks/node/

The `whabuzz` package for Node 18+ and edge runtimes. Zero dependencies, `fetch` only, ESM and CommonJS, full TypeScript types. Request bodies and responses are Meta's own.

```bash
npm install whabuzz
export WHABUZZ_API_KEY="wb_live_..."   # your key
```

## First message {#first-message}

```js
import { WhaBuzz } from 'whabuzz';

const wb = new WhaBuzz(); // reads WHABUZZ_API_KEY
const res = await wb.messages.send({
  from: '+14692311132', // your connected number
  to: process.env.TO, // the recipient, E.164
  type: 'text',
  text: { body: 'Hello from WhaBuzz' },
});
console.log(res.messages[0].id);
```

Outside the 24-hour customer window send a [template](https://docs.whabuzz.com/guides/templates.md) instead. A busy number answers `202 {"status":"queued"}`; the message then goes out in order.

## Options and resources {#surface}

`new WhaBuzz({ apiKey, baseUrl, tenant, fetch, timeoutMs })`. Platform keys pass `tenant`. Pass `{ idempotencyKey }` as the second argument of `send`, `batch` and `create` calls; see [Idempotency](https://docs.whabuzz.com/guides/idempotency.md).

`tenant.get`, `messages` (`send`, `batch`, `getBatch`, `listBatchItems`, `cancelBatch`, `markRead`), `templates` (`list`, `create`, `get`), `numbers` (`list`, `get`), `webhooks.endpoints` (`list`, `create`, `get`, `update`, `delete`, `verify`, `rotateSecret`), `events` (`list`, `get`, `iterate`), `media.get`. For any other route use `wb.request({ method, path })`.

## Errors {#errors}

Failures throw `WhaBuzzError`: `status`, `source` (`meta`, `whabuzz`, `client`), `code`, `meta` (Meta's error object, verbatim), `requestId`. See [Errors](https://docs.whabuzz.com/errors.md).

```js
try {
  await wb.messages.send(body);
} catch (e) {
  if (e.source === 'meta') console.error(e.meta.code, e.meta.message);
  else throw e;
}
```

## Verify a webhook {#verify}

```js
import { verifyWebhook } from 'whabuzz';

// rawBody must be the exact bytes received, before JSON parsing
const event = await verifyWebhook(rawBody, request.headers, process.env.WHABUZZ_WEBHOOK_SECRET);
console.log(event.type);
```

It throws `WebhookVerificationError` with a `reason` when the signature, timestamp (300 s) or header is wrong. Details of the scheme: [Webhooks](https://docs.whabuzz.com/guides/webhooks.md#verify-node).

## Next {#next}

The same package ships the [`whabuzz` CLI](https://docs.whabuzz.com/sdks/cli.md).
