# Receive messages and status updates

Use a configured `WhatsAppClient` from [Install and verify](/docs/npm-whatsapp/install). Examples below assume it is named `whatsapp`. Application callbacks such as `db`, `myDatabase`, and `queue` are supplied by your app; `fileBlob` is the Blob you intend to upload.

## Webhooks

Use the native `Request -> Response` handler in Next.js route handlers, workers, Bun, Deno, or any server that supports Web Fetch APIs.

```ts
import { createWebhookHandler } from "@qentrah/whatsapp";

export const GET = createWebhookHandler(config, {
  async onMessage({ message, contact, actions }) {
    await actions.reply(`Hi ${contact?.name ?? "there"}, we received: ${message.text ?? message.type}`);
  },
});

export const POST = GET;
```

The handler:

- verifies `hub.challenge` setup requests using `verifyToken`
- verifies `X-Hub-Signature-256` when `appSecret` and a signature header are present
- extracts every `entry[].changes[]`
- parses inbound messages, status-only payloads, and template status updates
- exposes `actions.reply`, `replyWithImage`, `replyWithFile`, `sendTemplate`, `markRead`, and `react`

Enable read receipts after successful `onMessage` handling:

```ts
const handler = whatsapp.webhooks.createHandler(
  {
    async onMessage({ actions }) {
      await actions.reply("Thanks, we are on it.");
    },
  },
  { autoMarkRead: true },
);
```

## Request-body handling

Pass the original `Request` into the handler before another middleware consumes its body. Signature verification depends on the original bytes. In this release, verification is conditional on the configured secret and signature header; do not assume that every unsigned request is rejected. Restrict the endpoint according to your deployment’s requirements.