---
title: "Update Member Role"
method: PATCH
path: "/teams/{team_id}/members/{user_id}"
tags: ["teams"]
---

# Update Member Role

`PATCH /teams/{team_id}/members/{user_id}`

Update a team member's role.

Requires owner or admin role. Passing ``role=owner`` performs an
ownership transfer to an existing member; ordinary role updates cannot
directly modify the current owner.

**Accepted risk (ENG-1281):** AAL2 enforcement was intentionally removed
(PR #3928) — users without MFA enrolled were being blocked from routine
team operations. Promoting a low-privilege collaborator is part of the
L-A16 escalation chain: an AAL1 attacker on a team-admin's session could
promote a colluding member into MANAGE_BILLING and pivot into credential
minting. This risk is accepted per the design decision.

## Path parameters

- `team_id` string, required
- `user_id` string, required

## Request body

- TeamRoleUpdate — Request model for updating a member's role.
  - `role` 'owner' | 'billing' | 'admin' | 'editor' | 'viewer', required — Team member roles with hierarchical permissions. Wire DTO mirror of the ORM ``TeamRoleType`` enum. Used only for API request/response serialization; authorization decisions route through the ORM matrix (``database_tables.permissions``), never this enum.

## Response `200`

Successful Response

- TeamMemberResponse — Response model for a team member. ``mfa_enabled`` and ``mfa_factor_count`` are sensitive targeting data and are populated only on the members-list response, and only for callers holding ``MANAGE_BILLING`` — matching the gated ``/teams/{id}/members/mfa-status`` surface. ``None`` means the field was not populated (caller lacks the permission, or the endpoint does not enrich it), never that MFA is disabled. Endpoints that do not enrich (e.g. role update) leave both fields ``None``.
  - `id` string, required
  - `team_id` string, required
  - `user_id` string, required
  - `role` 'owner' | 'billing' | 'admin' | 'editor' | 'viewer', required — Team member roles with hierarchical permissions. Wire DTO mirror of the ORM ``TeamRoleType`` enum. Used only for API request/response serialization; authorization decisions route through the ORM matrix (``database_tables.permissions``), never this enum.
  - `joined_at` string, required
  - `user_email` string, nullable
  - `user_name` string, nullable
  - `user_avatar_url` string, nullable
  - `mfa_enabled` boolean, nullable
  - `mfa_factor_count` integer, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/pioneer/apis/brain-api.md) · [All operations](https://skmtc.net/pioneer/apis/brain-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/pioneer/brain-api/versions/31dfe831e079/schema)
