NetStacksNetStacks

Administration API

Enterprise

Manage NetStacks Controller users, roles, organizations, settings, and license, and read the audit log through the API.

Overview

Administrative endpoints live under /api/admin. They back the Administration and Settings areas of the Admin Console. Most need users.manage, system.manage, or platform.admin, as shown in each table. Everything is scoped to the organization in your token, except organizations themselves.

Users

MethodPathPurposePermission
GET/api/admin/usersList users: {"users":[…],"total":n}. Query: search, limit, offsetusers.manage
POST/api/admin/usersCreate a local userusers.manage
GET/api/admin/users/:idGet a user with their rolesusers.manage
PUT/api/admin/users/:idUpdate a userusers.manage
DELETE/api/admin/users/:idDelete a userusers.manage
GET/api/admin/users/:id/rolesList the user's rolesusers.manage
POST/api/admin/users/:id/rolesAdd one role. Body: {"role_id"}users.manage
PUT/api/admin/users/:id/rolesReplace all roles. Body: {"role_ids":[…]}users.manage
DELETE/api/admin/users/:id/roles/:role_idRemove one roleusers.manage

Create a user and give it a role:

NS=https://controller.example.com:3000
USER_ID=$(curl -s --cacert netstacks-ca.pem -X POST $NS/api/admin/users \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"username":"automation","display_name":"Automation","email":"[email protected]","password":"<at least 12 characters>"}' \
  | jq -r .id)

curl -s --cacert netstacks-ca.pem -X PUT $NS/api/admin/users/$USER_ID/roles \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"role_ids":["<operator role id>"]}'
FieldTypeNotes
usernamestringRequired. Unique.
passwordstringRequired. At least 12 characters and not a common password.
email, display_namestringOptional.
org_idUUIDOptional. Platform administrators only: create the user in another organization.

PUT /api/admin/users/:id accepts email, display_name (send null to clear), and password to set a new password. You can't delete your own account.

Roles

MethodPathPurposePermission
GET/api/admin/rolesList rolesusers.manage
POST/api/admin/rolesCreate a role. Body: {"name","description","permissions":[…]}users.manage
GET/api/admin/roles/permissionsThe permission catalog, grouped by categoryusers.manage
GET/api/admin/roles/:idGet a roleusers.manage
PUT/api/admin/roles/:idUpdate name, description, or permissionsusers.manage
DELETE/api/admin/roles/:idDelete a role. Built-in protected roles return 400users.manage
POST /api/admin/rolesjson
{
  "name": "automation",
  "description": "Service account for config backup scripts",
  "permissions": ["devices.access"]
}

Role names must be unique within the organization. See Roles and permissions for what each permission covers.

Organizations

MethodPathPurposePermission
GET/api/admin/organizationsList organizationsplatform.admin
POST/api/admin/organizationsCreate an organization. Body: {"name"}platform.admin
GET / PUT/api/admin/organizations/:idGet or rename an organizationplatform.admin
DELETE/api/admin/organizations/:idDelete an empty organization (409 if it still has users or devices)platform.admin

A new organization starts with no users and no roles. To work inside it, switch to it with POST /api/auth/switch-org and create roles and users there.

Audit log

MethodPathPurpose
GET/api/admin/auditPage through audit events
GET/api/admin/audit/event-typesAll event types that have been recorded (array of strings)
FieldTypeNotes
page / limitintegerPage number (from 1) and page size (default 10, maximum 100)
event_typestringFor example auth.login.success, auth.login.failed, or auth.logout
actor_idUUIDEvents by one user
from_date / to_dateISO datetimeTime range
searchstringFree-text search
curl -s --cacert netstacks-ca.pem \
  "https://controller.example.com:3000/api/admin/audit?event_type=auth.login.success&from_date=2026-10-01T00:00:00Z&limit=100" \
  -H "Authorization: Bearer $TOKEN"
{
  "data": [
    {
      "id": "b19c...",
      "event_type": "auth.login.success",
      "actor_id": "3f6c...",
      "actor_email": "[email protected]",
      "resource_type": "auth",
      "resource_id": null,
      "details": { "username": "automation", "method": "local" },
      "ip_address": "10.20.0.15",
      "created_at": "2026-10-12T13:58:41Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 100,
  "total_pages": 1
}

resource_type is the part of event_type before the first dot. To export the log, page through it and write the results to a file. See also Audit log.

Settings

Settings are key/value pairs that apply to the whole Controller (all organizations). Secret values are masked when you read them.

MethodPathPurposePermission
GET/api/admin/settingsList all settingsSigned in
GET/api/admin/settings/:keyGet one settingSigned in
PUT/api/admin/settings/:keyChange one setting. Body: {"value": …}system.manage
curl -s --cacert netstacks-ca.pem -X PUT \
  https://controller.example.com:3000/api/admin/settings/session.access_token_hours \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d '{"value": 8}'

Some settings are read only when the API starts (for example the login rate limits and LDAP/OIDC configuration). The Settings page notes which ones need a restart.

License, health, and system

MethodPathPurposePermission
GET/api/admin/license/statusLicense tier, seats used and total, expiry, statusSigned in
POST/api/admin/license/activateActivate a license key. Body: {"license_key"}system.manage
GET/api/admin/healthComponent health (database, scheduler, vault, Valkey) and uptimeSigned in
GET/api/admin/ha-statusSingle-instance or active-active mode and the running instancesSigned in
GET/api/admin/system/infoDeployment informationsystem.manage
POST/api/admin/system/backupDownload a full database backup (.sql)system.manage
POST/api/admin/system/restoreRestore from an uploaded backup (multipart)system.manage
GET/api/admin/sessionsLive terminal sessionsusers.manage
POST/api/admin/sessions/:id/terminateEnd a live sessionusers.manage