Netmon Docs · API Reference

Users & Accessv7.0.20

Manage the appliance’s local user accounts, their permissions, and per-user multi-factor authentication — plus the two self-service reads every authenticated client needs: the current user and the assignable permission list.

These endpoints administer local accounts: create and edit users, grant permissions, and manage per-user multi-factor authentication (MFA). Two self-service reads ride along — the current user and the assignable permission list — because every authenticated client needs them, not just administrators.

The endpoints belong to the system functional area: an MCP or OAuth token needs the mcp:system scope. The permission requirement, however, varies within this chapter:

The super-admin account (user id 1) is protected: its id, username, and active flag are immutable, so it cannot be renamed or disabled through these endpoints.

The MFA write endpoints carry their own per-call authorization on top of the users permission: a caller may only generate, confirm, or disable MFA for their own account unless they hold the sa permission, in which case they may act on any user.

Users

List users

GET/api/getUsers

Permission any authenticated user

Returns user accounts with their permissions and tags. Admins (callers holding users or sa) get every user; everyone else gets only their own row. The self_only flag tells the caller which mode the response is in, and caller_id echoes the authenticated user’s id.

Response 200

{
  "status": 201,
  "hasError": false,
  "users": [
    {
      "id": 7,
      "first_name": "Ada",
      "last_name": "Lovelace",
      "email": "ada@example.com",
      "username": "ada",
      "active": true,
      "totp": false,
      "auth_source": "local",
      "permissions": ["devices", "alerts"],
      "tags": ["sitea"]
    }
  ],
  "self_only": false,
  "caller_id": 7
}

totp is true when the user has MFA enabled; auth_source is local or ldap; permissions and tags are slug arrays.

Example

curl -sS https://APPLIANCE/api/getUsers \
  -H "Authorization: Bearer $TOKEN"

Create a user

POST/api/createUserusers

Creates a new local user. The account is created active. All fields are required; the password must meet the complexity policy.

Request body

FieldTypeRequiredNotes
first_namestringyesMax 255.
last_namestringyesMax 255.
emailstringyesValid email, unique across users.
usernamestringyesMax 255, unique across users.
passwordstringyesMin 8 chars; must contain a lowercase letter, an uppercase letter, and a digit.

Response 200

{ "status": 201 }

Errors

StatusBodyWhen
200{"status":false,"hasError":true,"message":"…"}Validation failed (e.g. duplicate email/username, weak password). The message is the first validation error.
Response shape

Both success and validation failure return HTTP 200. Branch on the status field (201 on success) and hasError, not on the HTTP status code.

Example

curl -sS -X POST https://APPLIANCE/api/createUser \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"first_name":"Ada","last_name":"Lovelace","email":"ada@example.com","username":"ada","password":"Sup3rSecret"}'

Update a user

POST/api/saveUserusers

Updates an existing user’s details, active state, tags, password, and permissions. Every field except user is optional — only the fields present in the body are touched. Deactivating a user (active: false) also revokes that user’s live API tokens immediately, not just future logins.

Request body

FieldTypeRequiredNotes
userintegeryesId of the user to update.
first_namestringnoNew first name.
last_namestringnoNew last name.
emailstringnoNew email; rejected if already used by another user.
usernamestringnoNew username; rejected if already used by another user.
activebooleannoActive state. Setting false also revokes the user’s live tokens.
tagsarraynoArray of {value: <slug>} objects; replaces the user’s tag set. null clears all tags.
passwordstringnoNew password; same complexity policy as create. Not allowed for LDAP users.
permissionsarraynoPermission slugs; replaces the user’s permission set. For LDAP users, LDAP-managed permissions are left untouched.
Super-admin protection

User id 1’s id, username, and active flag are immutable. Attempts to rename or disable the super-admin through this endpoint are ignored at the model layer.

Response 200

{ "status": 201 }

Errors

StatusBodyWhen
200{"status":false,"hasError":true,"message":"Email is already in use"}New email collides with another user.
200{"status":false,"hasError":true,"message":"Username is already in use"}New username collides with another user.
200{"status":false,"hasError":true,"message":"Cannot change password for LDAP users"}Password change attempted on an LDAP-sourced account.
200{"status":false,"hasError":true,"message":"…"}Password failed the complexity policy.

Example

curl -sS -X POST https://APPLIANCE/api/saveUser \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"user":7,"active":false,"permissions":["devices","alerts"]}'

Delete a user

POST/api/deleteUserusers

Permanently deletes a user account.

Destructive

This permanently removes the user account. It cannot be undone.

Request body

FieldTypeRequiredNotes
userintegeryesId of the user to delete.

Response 200

{ "status": 201 }

Errors

StatusBodyWhen
200{"status":false,"message":"…"}The user id was not found (or another error occurred).

Example

curl -sS -X POST https://APPLIANCE/api/deleteUser \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"user":7}'

MFA

MFA uses a stage-then-confirm flow. generateMfa stages a fresh TOTP secret and returns the provisioning material, but does not turn MFA on. The operator scans the QR, then calls confirmMfa with a working code to promote the staged secret to live. This guarantees the user can never lock themselves out if the QR scan fails. Each of these endpoints lets a caller act on their own account, or on any account if they hold sa.

Generate (stage) an MFA secret

POST/api/generateMfausers

Stages a new TOTP secret for the user and returns the key, hostname, and username for building a provisioning QR. The user’s existing MFA state is unchanged until confirmMfa succeeds.

Request body

FieldTypeRequiredNotes
userIdintegeryesUser to stage MFA for. Must be the caller unless the caller holds sa.

Response 200

{
  "status": true,
  "message": "MFA key staged — call /confirmMfa with a TOTP code to enable",
  "mfaKey": "JBSWY3DPEHPK3PXP",
  "hostname": "netmon",
  "username": "ada",
  "pending": true
}

Errors

StatusBodyWhen
403{"status":false,"message":"Not authorized to modify this user"}Caller is acting on another user without sa.
404{"status":false,"message":"User not found …"}Unknown userId.
500{"status":false,"message":"Error generating MFA key"}Unexpected error.

Example

curl -sS -X POST https://APPLIANCE/api/generateMfa \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"userId":7}'

Confirm and enable MFA

POST/api/confirmMfausers

Verifies a TOTP code against the staged secret. On success the staged secret is promoted to live and the user’s next login enforces MFA. On failure the live MFA state is unchanged.

Request body

FieldTypeRequiredNotes
userIdintegeryesUser to confirm. Must be the caller unless the caller holds sa.
codestringyesCurrent TOTP code from the authenticator app.

Response 200

{ "status": true, "message": "MFA enabled successfully" }

Errors

StatusBodyWhen
400{"status":false,"message":"TOTP code is required"}Empty code.
400{"status":false,"message":"No pending MFA bootstrap to confirm. …"}No staged secret — call generateMfa first.
400{"status":false,"message":"TOTP code did not match the staged secret. …"}Code mismatch.
403{"status":false,"message":"Not authorized to modify this user"}Caller acting on another user without sa.
404{"status":false,"message":"User not found"}Unknown userId.

Example

curl -sS -X POST https://APPLIANCE/api/confirmMfa \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"userId":7,"code":"123456"}'

Disable MFA

POST/api/disableMfausers

Disables MFA for the user, clearing the live secret.

Request body

FieldTypeRequiredNotes
userIdintegeryesUser to disable MFA for. Must be the caller unless the caller holds sa.

Response 200

{ "status": true, "message": "MFA disabled successfully" }

Errors

StatusBodyWhen
403{"status":false,"message":"Not authorized to modify this user"}Caller acting on another user without sa.
404{"status":false,"message":"User not found"}Unknown userId.
500{"status":false,"message":"Error disabling MFA"}Unexpected error.

Example

curl -sS -X POST https://APPLIANCE/api/disableMfa \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"userId":7}'

Permissions

List assignable permissions

GET/api/getPermissions

Permission any authenticated user

Returns the full catalogue of permissions, used to populate the permission picker when editing a user. Each row carries the slug used by every permission:<slug> gate across the API.

Response 200

{
  "status": 201,
  "hasError": false,
  "permissions": [
    { "id": 1, "slug": "devices", "name": "Devices" },
    { "id": 15, "slug": "capture", "name": "Capture" }
  ]
}

The full permission catalogue and the scopes that correspond to it are documented in Permissions & Scopes.

Example

curl -sS https://APPLIANCE/api/getPermissions \
  -H "Authorization: Bearer $TOKEN"

Current user

Get the current user

GET/api/me

Permission any authenticated user

Returns the account record for the authenticated caller. This is the canonical way to validate a token and discover who it belongs to. The response is the bare user object; sensitive fields (password, remember_token, and the MFA secret) are never included.

Response 200

{
  "id": 7,
  "first_name": "Ada",
  "last_name": "Lovelace",
  "email": "ada@example.com",
  "username": "ada",
  "active": true,
  "auth_source": "local",
  "created_at": "2026-01-04T09:00:00.000000Z",
  "updated_at": "2026-06-10T12:30:00.000000Z"
}

Example

curl -sS https://APPLIANCE/api/me \
  -H "Authorization: Bearer $TOKEN"