# organizationMembership.updated: the role-change event
Fires when a membership changes, most importantly when the role changes (member to admin, admin to member). The membership id stays the same; only the contents change.
## What to do on receipt
1. Look up your membership row by org id plus user id from the nested payload (`evt.data.organization.id`, `evt.data.public_user_data.user_id`).
2. Diff the incoming `evt.data.role` against your stored role. On change, update entitlements: grant the new role's permissions, revoke the old one's.
3. Treat a demotion (admin to member) with the same seriousness as a deletion for sensitive grants. Revoke elevated access in the same handler run, not in a later cleanup job.
4. Return 200.
## The trap
The missing middle event. Handlers that subscribe to membership created and deleted but skip updated will never see a promotion or demotion. An ex-admin keeps admin powers in your app indefinitely. This is a privilege-escalation-shaped bug caused by an incomplete subscription list.
## Checklist
- Subscribe to organizationMembership.updated explicitly. Audit your subscription list; this is the event most often forgotten.
- Role changes also affect your seat/billing logic if you price by role. Recompute on updated, not just on created.
- Like all webhooks, this can arrive out of order with created. Upsert the membership row; do not assume it exists.