List users (admin)
GET /admin/users
Paginated admin user list. Newest accounts first.
Filters: q runs a case-insensitive substring match across
username / fullname / email; status narrows to active /
pending / disabled (mapping to the underlying user.approved
flag, see 1.17.B for the lifecycle state machine). Cursor
pagination via opaque cursor token; total is the
unfiltered-by-cursor count for the badge in the chrome.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters ”Case-insensitive substring match across username, fullname, email.
Opaque token from a previous response’s next_cursor.
Responses
Section titled “ Responses ”A page of admin user rows.
object
Admin-projection of a user row. Carries everything the
admin list table needs — username, email, status, last
activity, primary role — without surfacing password-bearing
columns. status maps to the underlying user.approved
column (1=active, 0=pending, 2=disabled per the lifecycle
state machine). primary_role is the user’s
alphabetically-first global role assignment; per-team
assignments live on the user detail page.
object
Resolved display string (profile.display_name → fullname → username).
Empty when the user has no global role assigned.
Hard expiry enforced at login; null = no expiry.
Per-username lockout deadline. Null when the account has never been locked OR the last lockout has been cleared. Values in the past are semantically “unlocked” (auto-clear happens at read time; the stale timestamp stays until the next failed login OR admin unlock). The frontend renders the “Locked (auto-clears at HH:MM)” badge when this > now().
Running count of consecutive failed login attempts. Zero on a fresh row + after any successful login. Threshold-crossing triggers lockout. Surfaced here so admins can see who’s under attack without waiting for a full lockout.
Login provider for this user — empty / null = native, else ‘simpleldap’ / ‘simplesaml’ / etc. for the enterprise SSO surfaces. Surfaced here so the admin list can show the auth-source badge.
Federation origin (when the profile row came from a peer instance). Null = home instance. See ADR 0007.
Total rows matching the q + status filter (cursor-independent).
Opaque pagination token. Pass back as the next request’s
cursor param to fetch the following page. Null when this
response is the final page.
Authentication required, missing, or invalid
object
Human-readable error summary
Example
the request could not be completedExample
{ "error": "authentication required: sign in and retry with a valid session or API token"}Authenticated but missing required capabilities
object
Human-readable error summary
Example
the request could not be completedUnexpected server error
object
Human-readable error summary
Example
the request could not be completed