# The user trio is one unit
`user.created`, `user.updated`, `user.deleted`. Clerk emits all three; your app needs all three. This is the single most common webhook failure pattern: a created-only handler that leaves stale emails, phantom users, and dead rows.
## What to do
1. In the Clerk Dashboard webhook endpoint settings, subscribe to all three user events. Check this in code review whenever the subscription list changes.
2. Route them to one sync function with a switch on `evt.type`:
- `user.created` and `user.updated` both call your upsert path. They share logic; the only difference is whether the row is expected to exist.
- `user.deleted` calls your delete/anonymize path.
3. Use the Clerk user id as your external key in all three paths. Never re-derive identity from email, because email changes arrive as `updated`.
4. Test all three with replays from the Dashboard. A test plan that only creates users is a test plan for half the system.
## The trap
The created-only handler. It works on demo day and rots immediately: users change emails and your copy lies, users delete accounts and your copy keeps billing them. Every `user.updated` you ignored is a support ticket waiting.
## Checklist
- One shared upsert for created and updated. If you find yourself writing them separately, merge them.
- The trio pattern repeats for organizations and memberships. If you sync orgs, apply the same rule there.
- Subscribe to the events explicitly per endpoint. A new endpoint that forgets `user.deleted` is the same bug in a new place.