Users
The Users view lists every registered Lumio user across all accounts. Admins can edit user details (display name, email), manage login connections (disconnect, set reconnect flags), manage account memberships (add to / remove from accounts), override account creation and max-account limits, and delete users entirely.
Where to find it
Admin sidebar → Users. The list lives at /users; detail pages live at /users/\{id\}.
Quick start
- Open Admin → Users.
- Search by display name or email using the top search bar.
- Click any row to open the user detail page.
- Inspect login connections and account memberships in the stacked cards.
- If a login provider needs to be detached, use the delete button on that connection row.
Detailed walkthrough
Users list (/users)
- Search - debounced 300 ms search on display name and email.
- Columns - Avatar + display name, Email, Created date, Last Login date. When a user's display name is a localized (non-Latin) name that differs from their platform handle - e.g. Twitch's
こさむんwhose login iskosamun- the handle is shown in brackets after it (こさむん (kosamun)) so operators can still identify the account. Ordinary case-variant names (Cruex/cruex) render the display name alone. This applies wherever an operator sees a person's name across the admin app (user search, account owners and members, role members, audit-log actors, developers and teams, ideas authors). - Pagination - 25 users per page; "Page X of Y (N users)" footer.
- Row click - navigates to
/users/\{id\}.
User detail (/users/[id])
The detail page stacks these cards:
- User Information - Display name and email (both editable inline, requires
users:edit), User ID, Created At, Last Login. A Delete User button (requiresusers:delete) opens a confirmation dialog before permanently deleting the user and all their data. While the user's developer profile still has a revenue balance or a payout in progress, the dialog stays open and says so: the user can be deleted once Lumio has paid it out. If Lumio cannot pay the balance out (no payout method, or identity not verified), operators withdeveloper-funds:release-deletionandusers:deletesee Release balance as a liability and delete in that dialog; see Releasing an unpayable developer balance. - Login Connections - table of every identity provider the user has linked: Provider (the
googleprovider renders as "YouTube"), Username on that provider (falling back to the provider account ID; a localized Twitch handle whose display name differs from the login renders asこさむん (kosamun), using the same rule as the person-name columns above - only Twitch connections bracket, since only Twitch has freely-editable localized display names), Connected Since, Actions. Each row carries a reconnect-flag toggle and a Disconnect button. - Account Memberships - table of every account the user belongs to: Account (linked to
/accounts/\{account_id\}), Plan badge, Role, Owner flag, Actions. An Add to Account button (requiresaccounts:edit) adds the user to an account by account ID. Each non-owner membership row has a Remove button with a confirmation dialog. - Account Creation - 3-state override dropdown that controls whether this user may create new accounts (see Account Creation Override below). Rendered only for admins with
users:edit. - Account Limit Override - optional integer override for how many accounts the user can own (see Max Accounts Override below). Rendered only for admins with
users:edit. - Extension Dev Mode - enable/disable extension development mode for this user. Rendered only for admins with
developer-limits:edit. 6b. Setting Presets - lists this user's setting presets (name, kind, default badge, last-changed; never the payload) with a Delete action per preset. Viewing requiresusers:read, deleting requiresusers:edit. Presets are user-bound, so a delete removes the preset for this user across every account they belong to; it emitssystem:user_setting_preset_deleted. The account detail page mirrors this list per member. - Roles - the user's user-role and admin-role assignments in one list, each entry badged
UserorAdmin. A user can hold several of each. Assign via the grouped dropdown at the bottom of the card; remove with the trash button on an entry. User-role rows are gated onuser-roles:edit, admin-role rows onadmin-roles:edit. - Permission Overrides - per-user overrides of user-scope permissions. Columns: Permission, Status (Granted / Denied), Reason, Set (timestamp), remove button. Add via the Add Override form. Gated on
user-roles:edit. - Effective Permissions - the fully resolved permission set for the user, grouped by category. Permissions that come from an override are highlighted in amber with an Overridden badge.
The Support Identity card shows the user's Lumio ID and current hourly support code, lets an operator check a code supplied by the user, and lists recent checks. All three actions require admin support:verify, seeded to the system_admin and support admin roles and assignable to custom admin roles; revealing and checking are audited without recording the code. The check is limited to five attempts per profile per ten minutes. The card needs LUMIO__SUPPORT__CODE_SECRET outside development; without it the API logs a startup warning and the support code is unavailable — the card then says so as soon as it opens, in place of Show code, and the check is disabled (see Installation). Reset 2FA requires admin users:edit and a written reason. The card shows counts of authenticator apps and passkeys, never their user-chosen names. A reset removes all methods, recovery codes and trusted devices and notifies the user.
Max Accounts Override
The Max Accounts Override section lets admins grant a specific user the ability to own more (or fewer) Lumio accounts than their plan normally allows.
The field is stored as max_accounts_override on the user record and accepts an optional positive integer. When set, it replaces the plan-derived account limit for that user. When null, the plan default (the plan's max_accounts column) is used.
Field values:
| Value | Meaning |
|---|---|
null | Use the plan default (no override). |
1 or more | User may own up to this many accounts regardless of plan. |
Updating this field goes through GraphQL: adminUpdateUserMaxAccountsOverride(userId: UUID!, maxAccounts: Int). PATCH /v1/admin/users/\{id\} does not accept a max_accounts_override field - its body is limited to account_creation_override, display_name, and email. The admin UI reaches the mutation through its own proxy route at /api/users/\{id\}/max-accounts-override. Requires the users:edit admin permission.
The override is exposed in:
GET /v1/admin/users/\{id\}response body (max_accounts_overridefield)adminUser(id)GraphQL query (maxAccountsOverridefield onAdminUser)
Account Creation Override
The Account Creation section lets admins grant or deny a specific user the ability to create streaming accounts, regardless of the global system:account_creation flag setting.
Dropdown options:
| Option | REST value | GraphQL enum | Meaning |
|---|---|---|---|
| Default (inherit global) | "default" | DEFAULT | Defer to the global system:account_creation flag. If the flag is ON, the user can create accounts; if OFF, they cannot. |
| Allow | "allow" | ALLOW | User may always create an account, even if the global flag is OFF. |
| Deny | "deny" | DENY | User is always blocked from creating an account, even if the global flag is ON. |
The value is persisted as a nullable boolean on the user row (null / true / false); both wire formats map onto it.
Effective state - a line below the dropdown shows the resolved outcome by combining the dropdown value with the global flag state: Allowed, Blocked, or Allowed (global block bypassed) when the global flag is off but this user is explicitly allowed.
Saving the override calls PATCH /v1/admin/users/\{id\} with { "account_creation_override": "default" \| "allow" \| "deny" } (REST) or the adminUpdateUserAccountCreationOverride(userId, override) mutation (GraphQL). The admin UI reaches it through /api/users/\{id\}/account-creation-override.
Common scenarios
- Abuse investigation - open a user, check their account memberships to see what data they control, then follow up in each account.
- Compromised OAuth - delete the affected login connection. The user must re-link that provider before using it again.
- Duplicate account merge - the admin UI does not merge users. Use the CLI/DB for merges; use this page to verify account memberships first.
- "Why can't user X log in?" - inspect Login Connections to confirm they still have at least one working provider link.
Releasing an unpayable developer balance
A deletion is refused while the person's developer profile still has a revenue balance (DEVELOPER_FUNDS_OUTSTANDING). A payable balance goes through the closing payout first. When Lumio cannot pay it out — no payout method, or the identity is not verified — and the person asked for the deletion, the delete dialog offers Release balance as a liability and delete. It is shown only to operators with developer-funds:release-deletion and the plain delete permission (users:delete here, developer-verification:edit on the developer pages).
- Open the action from the delete dialog. The dialog states what happens: the user or profile is deleted now, the person gets an e-mail with the amount and a claim code, and Lumio keeps the record until 31 December of the third year after the release year (longer if the person files a claim before then).
- Enter the Request reference (ticket or request ID of the deletion request, up to 64 characters) and the Reason (up to 500 characters). Both are mandatory. Do not enter names, e-mail addresses or other contact data in either field — the release mail tells the person that Lumio stores none.
- Click Book and delete. The server decides the case. It refuses a payable balance ("use the closing payout instead") and a payout in progress; in both cases nothing is deleted and the dialog names the reason.
- If the release mail could not be sent, the dialog shows the claim code once, with a copy button. Pass it to the person through their request channel, then click I have saved the code. Lumio does not store the code in plain text and cannot show it again.
The action emits developer:funds_deletion_released (System scope) in the audit log.
A refund or chargeback of a sale made before the release finds no developer to debit any more (the extensions are deleted with the profile). The released amount still contains that sale's share, so Lumio owes the person slightly more than the sale finally earned; this is accepted, and the release is not held back for the refund window. The API logs such a refund as a warning.
Settling a released balance
When the person comes back with the claim code, an operator with developer-funds:settle settles the claim in two steps on the developer pages. Both steps need an interactive session; API keys are refused. The claim code is sent in the request body only, never in a URL.
- Code presented: on the Developers list, click Claim code presented, enter the code (separators, spaces and case are ignored) and click Record code (
adminStartReleasedBalanceClaim/POST /v1/admin/released-balances/claim). Do this as soon as the person sends the code, even before they have a new developer profile. The dialog shows the amount, the reason for the release (no payout method / identity not verified), the release date and when the code was first presented. From then on Lumio keeps the record until the claim is settled, even past the end of the third year after the release. A repeat is harmless: it keeps the first time and says the code was already presented. - Settle: open the person's new developer profile and click Settle a released balance in the Released balance section. Enter the code and click Record code (repeats step 1 harmlessly and shows the amount), then the Credit button with the amount (
adminSettleReleasedBalance/POST /v1/admin/released-balances/settle). The profile's identity must be verified. The dialog shows the profile's new balance. The normal payout then pays the amount out with its credit note, where the settled amount is its own line with the release date (see Developer Credit Notes). A code can be settled only once.
The dialog names each refusal: an invalid code, no released balance for the code, a code that is already settled, a profile whose identity is not verified yet, and a profile that no longer exists.
The steps emit developer:funds_released_claim_started and developer:funds_released_settled (System scope). A settled record is kept for 8 years after the settlement year, and longer while part of the amount has not been paid out from the new profile yet. Once settled, the record belongs to the new profile: the person's data export lists it under settled_released_balances in developer.json.
Permissions
| Action | Permission |
|---|---|
| View user list / detail | users:read |
| Edit display name / email | users:edit |
| Reveal/check a user's support code and see recent checks | support:verify |
| Reset a user's 2FA with a recorded reason | users:edit |
| Delete a user's login connection | users:edit |
| Set reconnect flag on login connections | users:edit |
| Update account creation / max accounts override | users:edit |
| Delete a user | users:delete |
| Release an unpayable developer balance as a liability and delete the user | developer-funds:release-deletion + users:delete |
| Record a presented claim code / settle a released balance on a new profile | developer-funds:settle |
| Add / remove account memberships | accounts:edit |
| Assign / remove user roles, manage per-user permission overrides | user-roles:edit |
| Assign / remove admin roles | admin-roles:edit |
| Toggle Extension Dev Mode | developer-limits:edit |
All actions additionally require admin:access. System admins (system_admin.is_system = true) implicitly have every permission.
API
| UI action | GraphQL | REST |
|---|---|---|
| List users (paginated, searchable) | adminUsers | GET /v1/admin/users |
| Get user detail | adminUser | GET /v1/admin/users/\{id\} |
| Update display name / email | adminUpdateUser | PATCH /v1/admin/users/\{id\} |
Delete user (refused with 409 DEVELOPER_FUNDS_OUTSTANDING while the user's developer profile has a balance or a payout in progress) | adminDeleteUser | DELETE /v1/admin/users/\{id\} |
Release an unpayable developer balance as a liability, then delete the user (admin developer-funds:release-deletion + users:delete, interactive session; see Developer balance release) | adminReleaseFundsAndDeleteUser | POST /v1/admin/users/\{id\}/release-funds-delete |
Record that a person presented the claim code of a released balance (admin developer-funds:settle, interactive session) | adminStartReleasedBalanceClaim | POST /v1/admin/released-balances/claim |
Credit a released balance to the person's new, verified developer profile (admin developer-funds:settle, interactive session) | adminSettleReleasedBalance | POST /v1/admin/released-balances/settle |
| Delete a login connection | adminDeleteUserLoginConnection | DELETE /v1/admin/users/\{id\}/login-connections/\{provider\} |
| Set login reconnect flag | adminSetLoginReconnectFlag | PUT /v1/admin/login-connections/\{id\}/reconnect-flag |
| Update account creation override | adminUpdateUserAccountCreationOverride | PATCH /v1/admin/users/\{id\} (body field account_creation_override) |
| Update max accounts override | adminUpdateUserMaxAccountsOverride | -- |
| List / assign / remove user roles | userRoleAssignments / assignUserRole / removeUserRole | GET / POST /v1/users/\{user_id\}/roles, DELETE /v1/users/\{user_id\}/roles/\{role_id\} |
| List admin roles for a user | adminUserAdminRoles | -- |
| Assign / remove admin role | adminAssignUserRole / adminUnassignUserRole | PUT / DELETE /v1/admin/admin-roles/\{id\}/members/\{userId\} |
| Per-user permission overrides | userPermissionOverrides / setUserPermissionOverride / removeUserPermissionOverride | GET / PUT /v1/users/\{user_id\}/permission-overrides, DELETE /v1/users/\{user_id\}/permission-overrides/\{permission\} |
| Effective permissions | resolvedUserPermissions | GET /v1/users/\{user_id\}/permissions/resolved |
| Toggle Extension Dev Mode | setExtensionDevMode | -- |
| List a user's setting presets | adminUserSettingPresets | GET /v1/admin/users/\{id\}/setting-presets |
| Delete a user's setting preset | adminDeleteUserSettingPreset | DELETE /v1/admin/setting-presets/\{id\} |
Tips & gotchas
- There is no ban / unban surface in the admin app today. Blocking a user from logging in is done by removing all of their login connections or deleting the user entirely.
- There is no sessions management in the admin user view. Session admin is handled per-account by the account owner (see the user-facing docs for the sessions page).
- Admins can add/remove account memberships from the user detail page. Changing a member's account role still happens inside the account itself, not from the admin panel.
- The list uses the Next.js proxy route
/api/userswhich calls the REST admin endpoint underneath. - Deleting a user is permanent and cascades to all their data. Use with caution.
Related
- Accounts - which accounts a user belongs to
- Audit Log - record of login / logout / admin events
- OAuth Clients - public OAuth apps that can act on behalf of users