# WhatsApp API with Next.js: receive and reply in one route

To use the WhatsApp API from a Next.js app, you need one route handler: it verifies the signature of the webhook, reads the incoming message and replies through the API. This is the whole of it, with the Nodium TypeScript SDK.

## Install and configure

```bash
npm i @nodium.io/whatsapp

# .env.local
NODIUM_KEY=nod_…                 # console › Settings › API keys
NODIUM_WEBHOOK_SECRET=whsec_…    # shown once, when you create the webhook
```

## The route

```ts
// app/api/webhooks/nodium/route.ts
import { Nodium } from '@nodium.io/whatsapp'
import { NodiumSignatureError, verifyWebhook } from '@nodium.io/whatsapp/server'

const nodium = new Nodium(process.env.NODIUM_KEY!)

export async function POST(request: Request) {
  // The raw body, before any JSON parsing: the signature is computed on it.
  const rawBody = await request.text()
  try {
    const event = verifyWebhook(rawBody, request.headers, process.env.NODIUM_WEBHOOK_SECRET!)

    if (event.event === 'message.received' && event.data.type === 'text') {
      await nodium.messages.send({
        channelId: event.data.channel_id,
        to: event.data.from,
        type: 'text',
        text: `You wrote: ${event.data.text}`,
        idempotencyKey: `reply-${event.id}`   // the same on every redelivery: sent once
      })
    }
    return new Response(null, { status: 200 })
  } catch (error) {
    if (error instanceof NodiumSignatureError) return new Response(null, { status: 400 })
    throw error
  }
}
```

## Tell Nodium where to call you

```bash
curl https://nodium.io/api/v1/webhooks \
  -H "Authorization: Bearer $NODIUM_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://your-app.example.com/webhooks/nodium", "events": ["message.received"] }'
# → data.secret (whsec_…): shown once
```

In development, `npx @nodium.io/cli listen` replays your real events to `localhost`, without a tunnel.

## Next

- Write first to a customer with an approved [template](https://nodium.io/en/features/templates-broadcasts): free text only goes out within the [24-hour window](https://nodium.io/en/guides/24-hour-window).
- Answer `200` quickly and do slow work afterwards: an event that is not acknowledged is delivered again, with the same `id`.
- Connect your customers' numbers with [one key for all of them](https://nodium.io/en/features/multi-tenant).

## Frequently asked questions

### Does it work on Vercel and in the Edge runtime?

The route above runs in the Node.js runtime, the default for route handlers: the SDK verifies the signature with Node's crypto module.

### Can I call the API from the browser?

No. The API key must stay on the server: call Nodium from a route handler or a server action, never from client code.

Updated 2026-11-10 · https://nodium.io/en/guides/whatsapp-api-nextjs
