curl --request POST \
--url https://api.example.com/clerkHandle user lifecycle events from Clerk authentication
curl --request POST \
--url https://api.example.com/clerksvix-id: Unique message identifiersvix-timestamp: Unix timestamp when the webhook was sentsvix-signature: HMAC signature for verificationCLERK_WEBHOOK_SECRET environment variable:
const webhook = new Webhook(process.env.CLERK_WEBHOOK_SECRET)
await webhook.verify(JSON.stringify(req.body), {
'svix-id': req.headers['svix-id'],
'svix-timestamp': req.headers['svix-timestamp'],
'svix-signature': req.headers['svix-signature'],
})
{
"type": "user.created",
"data": {
"id": "user_2abc123xyz",
"email_addresses": [
{
"email_address": "user@example.com"
}
],
"first_name": "John",
"last_name": "Doe",
"image_url": "https://img.clerk.com/user_2abc123xyz"
}
}
_id: Clerk user IDemail: Primary email addressname: Concatenation of first_name and last_nameimageUrl: Profile image URL{
"type": "user.updated",
"data": {
"id": "user_2abc123xyz",
"email_addresses": [
{
"email_address": "newemail@example.com"
}
],
"first_name": "Jane",
"last_name": "Smith",
"image_url": "https://img.clerk.com/user_2abc123xyz"
}
}
emailnameimageUrl{
"type": "user.deleted",
"data": {
"id": "user_2abc123xyz"
}
}
| Header | Type | Required | Description |
|---|---|---|---|
svix-id | string | Yes | Unique message identifier |
svix-timestamp | string | Yes | Unix timestamp of webhook delivery |
svix-signature | string | Yes | HMAC signature for verification |
Content-Type | string | Yes | Must be application/json |
{
"type": "user.created | user.updated | user.deleted",
"data": {
"id": "string",
"email_addresses": [
{
"email_address": "string"
}
],
"first_name": "string",
"last_name": "string",
"image_url": "string"
}
}
200 OK
{}
500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred"
}
CLERK_WEBHOOK_SECRET securely in environment variableshttps://yourdomain.com/clerkuser.createduser.updateduser.deletedCLERK_WEBHOOK_SECRETCLERK_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxx
server/controllers/webhooks.js:8
export const clerkWebhooks = async (req, res) => {
try {
const webhook = new Webhook(process.env.CLERK_WEBHOOK_SECRET)
await webhook.verify(JSON.stringify(req.body), {
'svix-id': req.headers['svix-id'],
'svix-timestamp': req.headers['svix-timestamp'],
'svix-signature': req.headers['svix-signature'],
})
const { data, type } = req.body
switch (type) {
case 'user.created':
// Create user in database
break
case 'user.updated':
// Update user in database
break
case 'user.deleted':
// Delete user from database
break
default:
// Acknowledge unknown events
}
res.json({})
} catch (error) {
res.status(500).json({
success: false,
message: 'An unexpected error occurred'
})
}
}