API Reference
API Reference
GitHub ↗
Admin Panel

User Management

Manage user accounts from the admin panel

Platform administrators create and manage the accounts that can sign in. Every route here is admin-only. Note the split: an account is a person who signs in, and what they may do inside a project is a separate membership row - see Projects .

Create a User

POST /api/v1/admin/users
{
    "email": "user@example.com",
    "password": "secure-password",
    "admin": false
}
FieldNotes
emailRequired. Normalized to lower case.
passwordOptional, minimum 12 characters, and not only whitespace. Leave it out for an account that signs in only through SSO - it then has no password to guess.
adminPlatform administration. Defaults to false.
adminWhat it grants
falseAn ordinary account. Everything it can do comes from project membership.
truePlatform administration - users, plans, platform settings, scheduled jobs, the whole security log. Also owner-equivalent in any project.

An account created here is a LOCAL account (account_type 1), whether or not you give it a password, and its owner manages their own password, two-factor authentication and passkeys from the profile page. account_type 2 is an account an identity provider owns, and only the provider mints those - those credentials are managed there, not here.

Returns 409 Conflict if the email already exists. Accounts created here are marked email-verified, so they never wait for a confirmation link - that gate is for self-registration.

No project is created here

Nothing is minted for a new account. The user either gets invited to a project or makes one from the projects page, so an install that provisions everyone into a shared project does not collect an empty tenant per employee.

List Users

GET /api/v1/admin/users

Returns every account, oldest first, as {"users": [...], "total": n}. q narrows it to addresses containing the term, email= answers one whole address alone, admin=true|false and disabled=true|false to one side of each flag, and limit with offset asks for a page of at most 200. Without limit the whole list comes back.

Update a User

PATCH /api/v1/admin/users/{id}
{
    "admin": true,
    "disabled": false,
    "email_verified": true
}

Every field is optional and absent means unchanged. email, password, admin, disabled and email_verified can be set.

Setting disabled to true blocks sign-in. email_verified is the manual release valve for a self-registered account whose confirmation mail never arrived.

You cannot change your own administrator or disabled flags

Self-edits are limited to email and password. The guard exists so the last administrator cannot demote or lock themselves out. Another admin still can.

Reset a User’s Passkeys

DELETE /api/v1/admin/users/{id}/passkeys

Removes every passkey on the account, for the user who lost the device that held the only one. They sign in with their password afterwards and enrol again. The response says how many went:

{
    "removed": 2
}

Not on your own account

Removing a passkey from your own profile asks for your password. This endpoint does not, so allowing it on yourself would let a hijacked admin session strip the phishing-resistant factor off the very account it hijacked. Another admin still can, and the security log records who did.

List a User’s Projects

GET /api/v1/admin/users/{id}/projects

Every project the account is a member of, so you can see what it touches before disabling or deleting it.

Delete a User

DELETE /api/v1/admin/users/{id}

Removes the account immediately and answers 204. Deleting your own account is refused, and an id that names nobody is 404 so a double-click reads as “already gone” rather than silent success.

Deleting the only owner of a project answers 409 and names the projects: a project with no owner can never be given away or shut down. Make another member an owner there, or delete the project, first.

There is no undo and no grace period

Deletion is immediate. If you want an account kept but locked out, set disabled instead - that is reversible and preserves the audit trail.

Disable 2FA for a User

For the person who lost their authenticator:

DELETE /api/v1/admin/users/{id}/2fa

Refused on your own account. The self-service path in your profile proves possession with a valid code, and this endpoint deliberately does not - allowing it on yourself would turn any hijacked admin session into a 2FA bypass for that admin. Returns 400 if the account has no second factor enrolled. The reset is recorded in the security log.

Revoke All Sessions

Force an account to sign in again everywhere:

POST /api/v1/admin/users/{id}/revoke-sessions

Answers {"revoked": 3}. The node handling the request is consistent immediately and other nodes converge within the session cache TTL. Also recorded in the security log.