Agent skills
Teach your AI coding assistant to build webhook routes correctly.
AI assistants happily hand-roll webhook verification, and they usually get at least one of the four steps wrong. A skill file fixes that: it loads the library's rules into the assistant, so generated routes use the built-in providers, keep the raw body intact, and return the status codes that drive retries.
For Claude Code, save this file in your project and it loads automatically whenever webhooks come up:
---
name: next-webhooks
description: Build webhook receivers with the next-webhooks package. Use when adding webhook endpoints (Stripe, GitHub, Clerk, Resend, Polar, Slack, Paddle, Shopify, Lemon Squeezy, Vercel, Discord) to a Next.js App Router project.
---
# next-webhooks
Verified, typed, idempotent webhook receivers for the Next.js App Router.
## Rules
- Export the result of webhook() as POST from a route handler, or
scaffold one with: npx next-webhooks init <provider>.
- Pick the built-in provider first: stripe(), github(), svix() for
Clerk, Resend, and Polar, slack(), paddle(), shopify(),
lemonsqueezy(), vercel(), discord(). Use hmac() for other HMAC
schemes.
- Prefer events + on over an if/else chain: events maps event types
to Standard Schema validators (zod, valibot, arktype) and on maps
them to handlers. Payloads are validated at runtime and handler
types are inferred from the schemas.
- Never read or parse the request body before webhook() runs; the
signature is checked over the raw bytes.
- On serverless, pass a shared IdempotencyStore via the idempotency
option; the default store is per-instance memory. The built-in
upstash() store from next-webhooks/stores is zero-dependency.
- Do not catch handler errors just to return 200. A 500 makes the
provider retry, and the event id is released automatically so the
retry is processed.
- In tests, build signed headers with next-webhooks/testing
(stripeHeaders, githubHeaders, svixHeaders, slackHeaders,
paddleHeaders, shopifyHeaders, lemonsqueezyHeaders, vercelHeaders,
discordHeaders with discordKeys, hmacHeaders) instead of
hand-rolling crypto.
## Example
```ts
import { webhook, stripe } from "next-webhooks";
import { z } from "zod";
export const POST = webhook({
provider: stripe({ secret: process.env.STRIPE_WEBHOOK_SECRET! }),
events: {
"invoice.paid": z.object({ id: z.string(), amount_due: z.number() }),
},
on: {
"invoice.paid": async (event) => {
// event.payload is validated and typed
},
},
});
```
Docs: https://next-webhooks.clawdiu.xyzOther assistants
The same content works anywhere your assistant reads project instructions: a Cursor rule (.cursor/rules/next-webhooks.mdc), a Windsurf rule, or a section in AGENTS.md. Copy the block above and drop the frontmatter if the format does not use it.
llms.txt
This site also serves a plain-text summary of the library at /llms.txt, so AI tools that fetch documentation get the API surface without scraping HTML.