PATCH /v1/orgs/:org_id/members/:user_id
Change a member's role.
::: tip Auth
Required: cookie or Bearer. Authorized via authorize_role_grant — caller's
role must permit granting the requested target role.
:::
Request
PATCH /v1/orgs/:org_id/members/:user_id
Body
{ "role": "admin" }
| Field | Type | Required | Notes |
|---|---|---|---|
role | string | yes | One of owner, admin, billing, member, viewer. Note: owner is gated by the ownership-transfer flow and is rejected here by the authorizer. |
Response
200 OK
The updated member view:
{
"user_id": "b7e2f1c4-...",
"email": "bob@example.com",
"display_name": "Bob B.",
"role": "admin",
"joined_at": "2026-04-15T10:00:00+00:00",
"avatar_url": null
}
Error responses
| Status | Code | When |
|---|---|---|
| 400 | invalid_input | Role not in the valid set. |
| 401 | authentication_required | No valid auth credential. |
| 403 | forbidden | Org mismatch, OR caller cannot grant the requested role. |
| 404 | not_found | No such membership. |
| 409 | conflict | Attempted to demote the last owner of the org. |
Notes
- An audit entry (
members.role_changed) is recorded with old and new roles. - Roles are read from
organization_memberships, NOTusers.role. This endpoint updates the membership row.