Receive delivery webhooks in Next.js
Handle Publiq delivery events (delivered, opened, bounced) in a Route Handler, verifying the HMAC signature.
Read the raw body to verify the signature in the Publiq-Signature header before trusting the event:
import { NextResponse } from 'next/server';
import crypto from 'node:crypto';
const secret = process.env.PUBLIQ_WEBHOOK_SECRET!;
export async function POST(req: Request) {
const raw = await req.text();
const sig = req.headers.get('Publiq-Signature') ?? '';
const expected = crypto.createHmac('sha256', secret).update(raw).digest('hex');
if (sig !== expected) return new NextResponse('invalid signature', { status: 401 });
const event = JSON.parse(raw);
// event.type: 'message.delivered' | 'message.opened' | 'message.bounced' ...
console.log(event.type, event.data.message_id);
return NextResponse.json({ ok: true });
}Register the webhook URL in the dashboard (or via SDK: Webhooks). The secret is shown only once on creation.
Best practices
- Always call Publiq from the server — never expose the API key on the client.
- Create the client instance once and reuse it across requests.
- Prefer
templateKeyover inline HTML to keep content versioned. - Handle
PubliqError(status/code); the SDK already retries transient errors with backoff. - Send from a verified domain — see Domains.