Browse documentation

Webhook examples

Next.js webhook example

Receive and verify Yanola webhook events in a server-side Next.js route handler.

DevelopersAdvancedAvailable

What this guide covers

  • Read the request body as text or bytes before parsing JSON.
  • Keep the webhook signing secret in server-only environment configuration.
  • Return a prompt 2xx response after safely accepting the event.

Create a server-only Route Handler

Place the handler in the App Router and keep YANOLA_WEBHOOK_SECRET in server-only deployment configuration. Route Handlers use the standard Request API; read the body as text exactly once.

.env.local
dotenv
YANOLA_WEBHOOK_SECRET=your_copy_once_endpoint_secret

Complete Next.js App Router route

app/api/webhooks/yanola/route.ts
ts
import {
  verifyYanolaWebhookSignature,
} from "@yanola/whatsapp"

export const runtime = "nodejs"

export async function POST(request: Request): Promise<Response> {
  const signingSecret = process.env.YANOLA_WEBHOOK_SECRET
  if (!signingSecret) {
    return Response.json(
      { error: "Webhook signing secret is not configured" },
      { status: 500 }
    )
  }

  const rawBody = await request.text()
  const valid = verifyYanolaWebhookSignature({
    secret: signingSecret,
    signature: request.headers.get("yanola-signature"),
    rawBody,
  })

  if (!valid) {
    return Response.json(
      { error: "Invalid Yanola signature" },
      { status: 400 }
    )
  }

  const event = JSON.parse(rawBody)
  await acceptEventOnce(event)

  return new Response(null, { status: 204 })
}

Keep the Node.js runtime

The Node.js runtime is the default for Route Handlers and is declared explicitly here because the SDK verifier uses Node's crypto implementation. Do not move this handler into a client component or expose the secret through NEXT_PUBLIC_ configuration.

Persist once, process later

  1. Use event.id as a unique key in your database or durable queue.
  2. Write the event and enqueue future work atomically where possible.
  3. Treat a duplicate ID as successful durable acceptance.
  4. Return 204 within Yanola's 10-second timeout.
  5. Run slow calls from a background worker.

Configure Yanola

  1. Deploy the route and confirm the public URL ends at /api/webhooks/yanola.
  2. Create a matching endpoint in the Agent Project dashboard.
  3. Use a Test endpoint and secret first.
  4. Select the payload mode your runtime validator expects.
  5. Send a dashboard test event and inspect its delivery record.

Common Next.js mistakes

Next.js webhook mistakes
MistakeCorrection
Calling request.json() before verificationCall request.text() once, verify, then JSON.parse(rawBody).
Using NEXT_PUBLIC_YANOLA_WEBHOOK_SECRETUse a server-only environment variable.
Returning before durable persistenceAwait the database or durable queue acceptance.
Parsing as a typed object without validationValidate untrusted JSON after signature verification.