Syncing Clerk User Data with Webhooks
To store user profile records in your database (for SQL relationships), configure a webhook. When a user registers, Clerk sends a secure HTTP POST request containing profile metadata to your backend API.
1. Setting Up a Webhook endpoint in Next.js
Clerk uses Svix to sign webhooks. Install the verification library in your project:
# Install Svix package for webhook header signature checks
npm install svixConfigure a Next.js API route to receive Clerk event calls:
// app/api/webhooks/clerk/route.ts
import { Webhook } from "svix";
import { headers } from "next/headers";
import { WebhookEvent } from "@clerk/nextjs/server";
import { prisma } from "../../../lib/prisma";
export async function POST(req: Request) {
const SIGNING_SECRET = process.env.CLERK_WEBHOOK_SECRET;
if (!SIGNING_SECRET) {
throw new Error("Missing CLERK_WEBHOOK_SECRET environment config");
}
// 1. Retrieve the Svix signing headers
const headerPayload = await headers();
const svix_id = headerPayload.get("svix-id");
const svix_timestamp = headerPayload.get("svix-timestamp");
const svix_signature = headerPayload.get("svix-signature");
if (!svix_id || !svix_timestamp || !svix_signature) {
return new Response("Missing svix headers", { status: 400 });
}
// Get raw request body bytes
const payload = await req.json();
const body = JSON.stringify(payload);
const wh = new Webhook(SIGNING_SECRET);
let evt: WebhookEvent;
// 2. Verify webhook signature
try {
evt = wh.verify(body, {
"svix-id": svix_id,
"svix-timestamp": svix_timestamp,
"svix-signature": svix_signature,
}) as WebhookEvent;
} catch (err) {
console.error("Webhook verification failed:", err);
return new Response("Verification error", { status: 400 });
}
// 3. Process events payload
const eventType = evt.type;
if (eventType === "user.created") {
const { id, email_addresses, image_url } = evt.data;
const email = email_addresses[0]?.email_address;
// Save profile to database using Prisma
await prisma.user.create({
data: {
clerkId: id,
email: email,
avatarUrl: image_url,
},
});
console.log(`Saved new user profile to database: ${id}`);
}
return new Response("Success", { status: 200 });
}2. Registering Webhooks in Clerk Control Panel
- Go to the Clerk Dashboard -> Webhooks -> Add Endpoint.
- Paste your API route URL (for example,
https://your-domain.com/api/webhooks/clerk). - Under Subscribe to events, select
user.createdanduser.updated. - Click Create.
- Copy the generated Signing Secret and add it to your local environment file:
CLERK_WEBHOOK_SECRET="whsec_..."Published on Last updated: