# Managing users (/docs/using/app-users/managing-users)



You manage a project's users as a platform user, not through the public key. In Studio, the project's **Users** tab (it appears once app users are enabled) has all of it. The same operations are in the Management API, under `/v1/projects/{id}/users`, with your member access token.

| Operation                | Request                                    |
| ------------------------ | ------------------------------------------ |
| List                     | `GET /v1/projects/{id}/users`              |
| Create                   | `POST /v1/projects/{id}/users`             |
| Get                      | `GET /v1/projects/{id}/users/{user_id}`    |
| Change email or password | `PATCH /v1/projects/{id}/users/{user_id}`  |
| Deactivate               | `POST …/users/{user_id}/deactivate`        |
| Reactivate               | `POST …/users/{user_id}/reactivate`        |
| List live sessions       | `GET …/users/{user_id}/sessions`           |
| Sign out everywhere      | `DELETE …/users/{user_id}/sessions`        |
| Delete                   | `DELETE /v1/projects/{id}/users/{user_id}` |

Each user has a `state`: `active` or `inactive` (deactivated: it can't sign in).

## List [#list]

50 users per page. `search` matches part of the email, ignoring case; `page_token` is the `next_page_token` of the previous page.

## Create [#create]

```json
{ "email": "ann@example.com", "password": "Str0ng!pass", "email_verified": true }
```

`email_verified` defaults to `true`: the address counts as verified and no email is sent. The identity user is created first, then the user's row is written to the users table. The table's own constraints can refuse the row (422 `constraint_violation`, with the constraint's name), and the identity user is then deleted again. Columns of your own get their defaults. An address another user has is 409 `email_taken`.

## Change [#change]

`PATCH` takes `email` and `email_verified`, at least one. A password can't be changed here; sending `password` is a 422.

* a new `email` is verified unless `email_verified` is `false`;
* any `email`, even the address the user already has, ends the user's sessions;
* `email_verified: true` alone marks the current address verified; `false` alone is refused for an address that is already verified.

The users table follows through the sync.

A 5xx for a new address can mean the address changed but the sessions didn't all end. Send the same request again: it ends them.

## Deactivate and sessions [#deactivate-and-sessions]

Deactivating a user bans them: sign-in stops and their sessions end. The sessions end first, so a 503 `identity_unavailable` from a deactivate or delete still ended them, even when the identity service isn't configured. The users table's `banned_at` is set on every branch, so your policies can read it, and cleared when they are reactivated. Reactivating lets them sign in again. Listing sessions returns the live (not revoked) sessions, oldest first, with their creation, last-use and expiry times, never a token. **Sign out everywhere** revokes them all; the data API stops accepting the user's access tokens within 30 seconds.

## Delete [#delete]

Ends the user's sessions and deletes the identity user. The users table's row follows the project's `on_delete` setting (delete it, or set `deleted_at`). In Studio you confirm by typing the user's email.

All of these answer 409 `app_users_disabled` when app users aren't enabled for the project, and 409 `project_deleting` while the project is being deleted.
