Clerk Webhook Setup Guide
Overview
This guide explains how to set up and troubleshoot the Clerk webhook that automatically assigns the "waitlist" role to new users upon signup.
Webhook Configuration
1. Create Webhook in Clerk Dashboard
- Go to Clerk Dashboard
- Navigate to Webhooks in the left sidebar
- Click Add Endpoint
- Configure the webhook:
- Endpoint URL:
https://your-domain.com/api/webhooks/clerk - Events to listen:
- ✅
user.created - ✅
user.updated - ✅
user.deleted
- ✅
- Endpoint URL:
- Click Create
- Copy the Signing Secret (you'll need this for
CLERK_WEBHOOK_SECRET)
2. Set Environment Variables
Add the following to your .env.local or Vercel environment variables:
CLERK_WEBHOOK_SECRET="whsec_xxxxxxxxxxxx" # From Clerk webhook settings
CLERK_SECRET_KEY="sk_test_xxxxxxxxxxxx" # From Clerk API Keys3. Verify Webhook is Working
Option 1: Check Webhook Configuration (Admin Only)
curl https://your-domain.com/api/admin/check-webhook-config \
-H "Cookie: your-auth-cookie"This endpoint will check:
- ✅ Environment variables are set
- ✅ Recent users have waitlist role
- ✅ Webhook URL configuration
Option 2: Check Clerk Dashboard Logs
- Go to Clerk Dashboard > Webhooks
- Click on your webhook endpoint
- Check the Logs tab for:
- ✅ Successful deliveries (200 status)
- ❌ Failed deliveries (check error messages)
Fix Existing Users Without Waitlist Role
1. Dry Run (Check How Many Users Need Fixing)
curl https://your-domain.com/api/admin/fix-missing-waitlist-roles \
-H "Cookie: your-auth-cookie" \
-H "Content-Type: application/json" \
-d '{"dryRun": true, "limit": 10}'2. Fix Users (Actually Apply the Waitlist Role)
curl https://your-domain.com/api/admin/fix-missing-waitlist-roles \
-H "Cookie: your-auth-cookie" \
-H "Content-Type: application/json" \
-d '{"dryRun": false, "limit": 10}'Parameters:
dryRun: (boolean) If true, only shows what would be changedlimit: (number) Maximum number of users to process (default: 10, for safety)
How It Works
- New User Signs Up → Clerk creates user account
- Clerk Webhook Fires → Sends
user.createdevent to/api/webhooks/clerk - Webhook Handler → Updates user with:
{ "publicMetadata": { "roles": ["waitlist"], "onboardingCompleted": false, "createdAt": 1234567890, "source": "organic" } } - User Has Waitlist Role → Can access waitlist-only features
Troubleshooting
Webhook Not Firing
- Check Clerk Dashboard Logs: Look for failed deliveries
- Verify Environment Variables: Run the check-webhook-config endpoint
- Check Network: Ensure your app is publicly accessible
- Verify HTTPS: Clerk requires HTTPS for production webhooks
Users Not Getting Waitlist Role
- Check Webhook Secret: Must match exactly from Clerk dashboard
- Check Permissions: Ensure
CLERK_SECRET_KEYhas user update permissions - Check Logs: Look for errors in your app logs
- Manual Fix: Use the fix-missing-waitlist-roles endpoint
Common Issues
- 400 Error: Usually means webhook secret is wrong
- 401 Error: CLERK_SECRET_KEY is invalid
- No logs in Clerk: Webhook URL might be wrong or app not deployed
Testing Locally
For local development, use ngrok or similar to expose your local server:
# Install ngrok
brew install ngrok
# Start your dev server
pnpm dev
# In another terminal, expose it
ngrok http 3000
# Use the ngrok URL in Clerk webhook settings
# Example: https://abc123.ngrok.io/api/webhooks/clerkSecurity Notes
- Never commit
CLERK_WEBHOOK_SECRETto version control - The webhook handler verifies signatures to prevent spoofing
- Only admin users can run the fix-missing-waitlist-roles endpoint
- Bulk operations are limited to 50 users at a time for safety