# Update User

Change a user's email address or password. At least one of the two.

## Overview

- **One's own account**: every signed-in user changes its own email or password — an account settings screen.
- **Another user's account**: only the roles that manage the tenant's users (`owner`, `tenantadmin`, `non_signing_admin`), on their own tenant, under the rules of acting on another account ([Roles](https://docs.aureahub.com/docs/authentication.md)). Any other role answers `403` `You can only access your own account`.
- **`200` with the user.** `email` must be an email address no other account of the tenant uses (`409` `Email already exists`); `password` 8 to 100 characters.
- Where your tenant's quorum holds administrators' actions, a change of **another** user's account answers `202` `{ "state": "awaiting_quorum", "requestId" }` and waits for another administrator ([Your Tenant's Quorum](https://docs.aureahub.com/docs/guide-tenant-quorum.md)). One's own account is never held.

## Your Own Password or Email

> ℹ️ **Asking for the current password is available when Aurea enables it for your tenant** ([contact us](https://www.aureahub.com/contact)). A tenant on the institutional security profile asks for it by its profile. Send `currentPassword` in your change screen now: until it is asked for, it is ignored.

When it is asked for, a user changing **their own** password, or their own email to a different one:

- **sends `currentPassword`** — without it, `400` `CURRENT_PASSWORD_REQUIRED`; wrong, `403` `CURRENT_PASSWORD_INVALID`, counted as a failed sign-in (where Aurea throttles failed sign-ins for your tenant, too many answer `429` with `Retry-After`); an account with no password (signed up with Google or Apple), `409` `CURRENT_PASSWORD_UNAVAILABLE` — set one with a [password reset link](https://docs.aureahub.com/docs/auth-forgot-password.md) first;
- **ends their other sessions**: every refresh token issued before the change is refused from then on (`401` `Session expired after a password change — please sign in again`), the caller's own included — sign the user in again after the change. Access tokens already issued stay valid until they expire;
- **is told by email**: a new password to the account's address; a new email to the old address (the new one masked) and to the new one.

These refusals carry the full envelope, with `details.code`:

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "The current password is required to change your password or email",
  "details": { "code": "CURRENT_PASSWORD_REQUIRED" }
}
```

- `403` `CURRENT_PASSWORD_INVALID`: `The current password is not correct`.
- `409` `CURRENT_PASSWORD_UNAVAILABLE`: `This account has no password: set one with a password reset link first`.
- Another user's account, the same email again, and every other field are never asked for a password.

## Endpoint

### `PUT /v1/users/{id}`

Authentication: bearer token required.

Updates a user's email or password. At least one field required.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string (uuid) | yes | The user's id: your own, or a user of your tenant you may manage |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | no | A new email address |
| `password` | string | no | A new password, 8–100 characters |
| `currentPassword` | string | no | Your current password, 1–100 characters, when you change your own password or email: required where your tenant asks for it, ignored otherwise and on another user's account |

**Responses**

`200` OK

```json
{
  "id": "6a1c9e3f-2b7d-4f50-8e4a-0c5d3b9f7e12",
  "username": "marco.cfo",
  "email": "marco.rossi@acme.example",
  "qrCode": "data:image/png;base64,iVBORw0KGgo…",
  "displayName": null,
  "status": "active",
  "role": "tenantadmin",
  "createdAt": "2026-09-01T10:00:00.000Z",
  "updatedAt": "2026-10-09T09:12:31.000Z"
}
```

`202` Awaiting quorum

```json
{
  "state": "awaiting_quorum",
  "requestId": "4e2b9c17-8a3d-4f60-b5e1-7c9d0a2f6b38"
}
```

`400` Current password

```json
{
  "statusCode": 400,
  "error": "BadRequestError",
  "message": "The current password is required to change your password or email",
  "details": { "code": "CURRENT_PASSWORD_REQUIRED" }
}
```

`403` Not yours

```json
{
  "statusCode": 403,
  "error": "ForbiddenError",
  "message": "You can only access your own account"
}
```

`404` Not Found

```json
{ "error": "NotFoundError", "message": "User not found" }
```

`409` Email taken

```json
{ "error": "ConflictError", "message": "Email already exists", "details": {} }
```

## Implementation

```javascript
// Account settings: change your own password, with the current one
async function changeMyPassword(token, myUserId, currentPassword, newPassword) {
  const res = await fetch(`https://api.aureahub.com/v1/users/${myUserId}`, {
    method: 'PUT',
    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
    body: JSON.stringify({ password: newPassword, currentPassword }),
  });
  const body = await res.json();
  if (!res.ok) throw new Error(body.details?.code ?? body.message); // e.g. CURRENT_PASSWORD_INVALID
  // Where the current password is asked for, the other sessions ended: sign in again
  return body;
}
```

---

Web version: https://docs.aureahub.com/#users-update
