Getting started

Install next-webhooks and receive your first verified webhook.

next-webhooks gives you verified, typed, idempotent webhook receivers for the Next.js App Router. It has zero dependencies and uses Web Crypto only, so the same code runs on the Node and Edge runtimes.

Install

pnpm add next-webhooks

Your first route

Create a route handler and export the result of webhook() as POST. This example receives Stripe events:

app/api/webhooks/stripe/route.ts
import { webhook, stripe } from "next-webhooks";

export const POST = webhook({
  provider: stripe({ secret: process.env.STRIPE_WEBHOOK_SECRET! }),
  handler: async (event) => {
    if (event.type === "invoice.paid") {
      // event.payload is the parsed JSON body
    }
  },
});

What it handles for you

  • Reads the raw body before anything parses it, so signatures verify correctly
  • Verifies the provider's signature and rejects forgeries with a 401
  • Skips duplicate deliveries, since providers send events at least once
  • Returns the status code that drives the provider's retry logic

Status codes

401  invalid signature       provider stops retrying, body includes the reason
400  verification threw      onError is called
422  payload failed schema   onInvalidPayload is called, event id not consumed
200  duplicate delivery      handler is skipped
200  no handler matched      acknowledged, unhandled: true in the body
200  handler succeeded       or return your own Response
500  handler threw           provider retries, the event id is released
500  idempotency store threw handler is skipped, provider retries later
405  method is not POST

Where to next

The if chain above works, but the recommended shape declares payload schemas and routes per event type. The events and routing guide covers it.