How to Configure Supabase Webhook for Welcome Emails¶
Important: Supabase Auth Schema Limitations¶
Why We Use the users Table (Not auth.users)¶
Supabase intentionally prevents users from creating triggers on the auth schema through the standard Table Editor or Webhook UI to prevent accidental system breakage. This means:
- You cannot create webhooks directly on
auth.usersvia the Dashboard UI - If you need to monitor
auth.users, you must: - Use a database trigger function that runs as Security Definer (admin privileges)
- The Dashboard UI does not provide a toggle/checkbox for this property
- This requires direct SQL access and advanced configuration
Recommended Approach: Use Public users Table¶
For this application, we use the public users table instead of auth.users because:
- ✅ Easier setup: Can be configured through the Dashboard UI
- ✅ No permission elevation needed: Works with standard webhook permissions
- ✅ Same functionality: Your app should sync
auth.users→userstable via triggers or application logic - ✅ More maintainable: Standard webhook configuration without SQL-level changes
Note: If your app doesn't automatically sync auth.users to a public users table, you'll need to set up a database trigger or handle this in your application code.
Want to monitor auth.users directly? See SUPABASE_AUTH_TRIGGER_SETUP.md for step-by-step instructions on creating a database trigger with SECURITY DEFINER to call webhooks directly from auth.users.
Step-by-Step Guide¶
Step 1: Access Supabase Dashboard¶
- Go to https://app.supabase.com
- Log in to your account
- Select your project
Step 2: Navigate to Webhooks¶
- In the left sidebar, click "Database"
- Click "Webhooks" (in the Database section)
- You'll see a list of existing webhooks (if any)
Step 3: Create or Edit Webhook¶
If you already have a webhook (user_signup_notifications):¶
- Click on your existing webhook:
user_signup_notifications - Click "Edit" or look for edit settings
- Update the HTTP Request URL to:
- Make sure these settings are correct:
- Table:
users - Events:
INSERT(andUPDATEif you want login notifications) - HTTP Request method:
POST - HTTP Request headers:
Content-Type: application/json - Click "Save" or "Update"
If you need to create a new webhook:¶
- Click "Create a new webhook" or "New webhook"
- Fill in the details:
- Name:
User Signup Notifications - Table: Select
usersfrom dropdown - Events:
- ✅ Check
INSERT(for new signups) - ✅ Optionally check
UPDATE(for login notifications) - ❌ You can skip
DELETE(not needed)
- ✅ Check
- HTTP Request:
- URL:
https://ai-assisted-pcb-stackup-generator.onrender.com/api/webhooks/auth - Method:
POST - HTTP Request headers:
- Key:
Content-Type - Value:
application/json
- URL:
- Click "Create webhook" or "Save"
Step 4: (Optional) Add Webhook Secret for Security¶
For production security, you can add a webhook secret:
- In your webhook settings, find "HTTP Request headers"
- Add a new header:
- Key:
x-supabase-signature - Value:
your-secret-key-here(use a random string, e.g., generate with:openssl rand -hex 32) - In your Render environment variables, add:
- Key:
SUPABASE_WEBHOOK_SECRET - Value:
your-secret-key-here(same value as above) - This ensures only Supabase can call your webhook
Step 5: Test the Webhook¶
- After saving, the webhook will be active
- Create a test user account on your app (pcbgenerator.com)
- Check:
- Supabase Dashboard → Webhooks → Your webhook → "Recent deliveries"
- Should show a successful delivery (200 status)
- Check your email inbox for the welcome email
Webhook Configuration Summary¶
Webhook URL for Supabase:
Settings:
- Table: users
- Events: INSERT (and UPDATE if needed)
- Method: POST
- Headers: Content-Type: application/json
Verify Webhook is Working¶
Check Supabase Webhook Logs:¶
- Go to Supabase Dashboard → Database → Webhooks
- Click on your webhook
- Check "Recent deliveries" tab
- Look for:
- ✅ Status:
200 OK(success) - ❌ Status:
400/500(error - check response details)
Test Manually:¶
You can test the webhook endpoint directly:
curl -X POST https://ai-assisted-pcb-stackup-generator.onrender.com/api/webhooks/auth \
-H "Content-Type: application/json" \
-d '{
"type": "INSERT",
"table": "users",
"record": {
"id": "test-123",
"email": "test@example.com",
"created_at": "2025-01-15T10:00:00Z"
}
}'
Expected response:
{
"status": "success",
"message": "Webhook processed",
"event_type": "INSERT",
"table": "users",
"processed": true
}
Troubleshooting¶
Webhook not being called:¶
- ✅ Verify webhook URL is correct
- ✅ Check that webhook is enabled
- ✅ Verify table name matches (
users) - ✅ Check that events are selected (INSERT)
- ⚠️ If using
auth.users: You cannot create webhooks onauth.usersvia UI - you must use a database trigger with Security Definer privileges (requires SQL access)
Cannot create webhook on auth.users:¶
- This is expected behavior - Supabase prevents webhook creation on auth schema via UI
- Solution: Use the public
userstable instead, or create a database trigger function manually with SQL - If you must use
auth.users, the trigger function must be created withSECURITY DEFINERto run as admin
Webhook returns error:¶
- Check Supabase webhook delivery logs for error details
- Check Render logs for backend errors
- Verify webhook payload format matches expected format
Emails not sending:¶
- Check email service status:
GET /api/webhooks/test/email-status - Verify SMTP credentials in Render environment variables
- Check Render logs for SMTP errors
Security Note¶
For production, it's recommended to:
1. Add webhook secret (SUPABASE_WEBHOOK_SECRET)
2. Enable signature verification
3. Use HTTPS only (already configured)
This prevents unauthorized calls to your webhook endpoint.