Devicesv7.0.20
Every endpoint anchored to the device record, from creating and editing devices through tags, profiles, credentials, pending-device import, per-user dashboards, network-discovery helpers, and Hyper-V inventory.
Devices are the core inventory of the appliance: every monitored host, switch, server, or virtual machine the system tracks. Each device carries an IP address, a display label, a profile (which determines the widgets and trackers shown on its dashboard), and optional SNMP, agent, NetFlow, and port-monitoring settings. The device record is the anchor for ping latency, interface counters, SNMP/agent walks, disk and port history, alerts, and tags.
These endpoints belong to the devices functional area; an MCP or OAuth token needs the mcp:devices scope, and the calling user needs the Laravel permission shown on each endpoint. The two device permissions are devices (read and dashboard interaction) and write_devices (create, edit, delete, credentials, and pending-device import); a few list endpoints also accept overwatch. The permission is enforced regardless of how the bearer token was obtained.
Tag-scoping applies across this chapter. Most list and read endpoints filter their results to the tags the calling user is restricted to: a tag-restricted user sees only devices (and ARP rows, bandwidth, pending rows, Hyper-V cross-references) that fall inside their tags, while a user with no tag restriction sees everything. The sa (super-admin) role bypasses tag-scoping entirely. Where an endpoint takes a device id, requesting a device outside your tag scope returns 404 (it is indistinguishable from a non-existent device, by design — this prevents enumeration of devices you cannot see).
Reserved local device. Device id 1 is the appliance’s own loopback device (127.0.0.1). It always exists and cannot be deleted.
The device inventory
List devices
GET/api/devicesdevices
Permission devices (or overwatch)
Returns every device visible to the caller. Optional relations are loaded only when you ask for them, which keeps the default payload light. SNMP credentials are never included in the list payload — read a single device to retrieve its (masked) SNMP config.
Query parameters
| Name | Type | Notes |
|---|---|---|
tag | string | Filter to devices carrying this tag slug. |
status | string | up (latency ≥ 0) or down (latency -1). |
search | string | Case-insensitive match on label or ip_address. |
alerts, ping, oids, walks, interfaces, ports, disks | boolean | Set any to true to eager-load that relation onto each device. |
Response 200
{
"status": 200,
"devices": [
{
"id": 1,
"label": "Netmon Appliance",
"ip_address": "127.0.0.1",
"profile": "linux",
"enable_snmp": false,
"enable_agent": false,
"tags": [ { "slug": "core", "name": "Core", "type": "device" } ]
}
]
}
Example
curl -sS "https://APPLIANCE/api/devices?status=down&ping=true" \
-H "Authorization: Bearer $TOKEN"
Get one device
GET/api/device/{device}devices
Returns a single device with its tags, alerts, masked SNMP config, syslog severity, recent NetFlow summary, and time-series logs for ping, OIDs, interfaces, ports, and disks. The time window defaults to the last 8 hours; pass hours, or an explicit start_time/end_time pair, to change it.
Path parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Device id. Out-of-scope or unknown ids return 404. |
Query parameters
| Name | Type | Notes |
|---|---|---|
hours | integer | Look-back window in hours (default 8). Ignored when start_time/end_time are given. |
start_time | datetime | Window start (any parseable date/time). Requires end_time. |
end_time | datetime | Window end. |
The returned snmpconfig masks the SNMP community and v3 auth/priv passwords as {"__encrypted__": true}. The plaintext secret never leaves the appliance. To preserve a secret on a later save, replay the same sentinel; to change it, send the new plaintext (see Add or edit a device).
Response 200
{
"status": 200,
"device": {
"id": 42,
"label": "core-switch",
"ip_address": "10.0.0.1",
"profile": "cisco",
"tags": [ "…" ],
"snmpconfig": { "snmp_version": 2, "snmp_community": { "__encrypted__": true } },
"syslogconfig": { "severity": 7 },
"netflow": { "bytes": 10485760, "count": 1432, "top_partners": [ "…" ] }
}
}
Example
curl -sS "https://APPLIANCE/api/device/42?hours=24" \
-H "Authorization: Bearer $TOKEN"
Get device storage stats
GET/api/device/{device}/statsdevices
Returns the row counts and on-disk size of every per-device log category (syslog, event log, trackers, interfaces, disks, walks, ports, ping), plus a Total row. Useful for understanding how much history a device is accumulating.
Path parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Device id. |
Response 200
[
{ "log_name": "Syslog", "total_rows": 12044, "size": 5242880, "formatted": "5120 kB" },
{ "log_name": "Interfaces", "total_rows": 8800, "size": 2097152, "formatted": "2048 kB" },
{ "log_name": "Total", "total_rows": 20844, "size": 7340032, "formatted": "7168 kB" }
]
Errors
| Status | Body | When |
|---|---|---|
400 | {"message":"Invalid device ID"} | Non-numeric id. |
404 | {"message":"Device not found"} | Out-of-scope or unknown device. |
500 | {"message":"An error occurred while fetching stats"} | Query failure. |
Adding and editing devices
Add or edit a device
POST/api/device/setwrite_devices
Creates a new device, or updates an existing one when id is supplied. The same endpoint configures SNMP and replaces the device’s tag set. On create, any matching pending-device row for the same IP is removed.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | no | Omit to create; include to update. |
ip_address | string (IP) | yes | Must be a valid IP. Unique across devices. |
label | string | yes | Max 255. |
profile | string | yes | Dashboard profile slug (see List device profiles). |
enable_snmp | boolean | no | Defaults to false when absent. |
enable_agent | boolean | no | Windows-agent monitoring. |
enable_netflow | boolean | no | NetFlow association. |
enable_port_monitor | boolean | no | TCP/UDP port monitoring. Not clobbered on partial update if omitted. |
agent_uuid | string | no | Internal agent identity; only written when present, never cleared by omission. |
snmpconfig | object | no | Read when enable_snmp is true (see below). |
tags | array | no | Each item {slug, name, type:"device"}. Replaces the device’s existing tags. |
snmpconfig fields: snmp_version (1, 2, or 3; default 2), snmp_port (default 161); for v1/v2 snmp_community; for v3 snmp_v3_security, authuser, authpass, authprot, privpass, privprot.
For snmp_community, authpass, and privpass, send the {"__encrypted__": true} sentinel (or an empty value) to keep the stored secret unchanged; send fresh plaintext to replace it. This mirrors the masking returned by Get one device.
Response 200
{ "status": 200, "message": "Device created successfully", "device": { "id": 43, "tags": [ "…" ] } }
Errors
| Status | Body | When |
|---|---|---|
422 | {"status":422,"errors":{...}} | Validation failed. |
409 | {"status":409,"message":"A device with IP address … already exists…"} | Duplicate IP. |
500 | {"status":500,"message":"An error occurred while saving the device: …"} | Save error. |
Example
curl -sS -X POST https://APPLIANCE/api/device/set \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"ip_address":"10.0.0.5","label":"edge-fw","profile":"fortigate",
"enable_snmp":true,
"snmpconfig":{"snmp_version":2,"snmp_port":161,"snmp_community":"public"},
"tags":[{"slug":"edge","name":"Edge","type":"device"}]}'
Delete a device (RESTful)
DELETE/api/device/{device}write_devices
Permission devices and write_devices (both required)
Detaches the device’s tags and deletes the device row, cascading to its monitoring history.
This permanently removes the device and all of its associated monitoring data (ping, interface, SNMP, disk, port, and log history). It cannot be undone.
Path parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Device id. Out-of-scope/unknown returns a 500 with a not-found message. |
Response 200
{ "status": 200, "message": "Device deleted successfully" }
Delete a device (legacy form)
POST/api/deleteDevicewrite_devices
Older delete entry point that takes the device id in the body. Prefer the RESTful DELETE /api/device/{device} above for new automation.
Permanently deletes the device and its monitoring history.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
device | integer | yes | Device id (must be > 0). |
Response
{ "status": 201, "hasError": false, "message": true }
On a missing id the response carries {"status": false, "hasError": true, "message": "Device ID requried"}.
Re-crawl a device
POST/api/device/{device}/recrawlwrite_devices
Permission devices and write_devices (both required)
Queues a fresh discovery crawl of the device. The appliance re-examines the device on its next polling tick — useful after changing credentials or expecting new interfaces.
Path parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Device id. |
Response 200
{ "status": 200, "message": "Re-crawl queued" }
Test SNMP reachability
POST/api/testSnmpwrite_devices
Runs a live SNMP probe against a target IP using the supplied SNMP config, without saving anything. Use it to validate credentials before creating or editing a device.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
ip | string | yes | Target IP to probe. |
snmpconfig | object | yes | Same shape as on Add or edit a device. |
device_id | integer | no | When given, masked/blank secrets resolve from this device’s stored credential. |
A masked secret ({"__encrypted__": true}) or blank value is resolved from the device named by device_id; literal plaintext is used as-is. This lets the appliance validate a credential the caller never sees in plaintext.
Response 200
{ "status": 200, "message": "SNMP responded: …" }
A failed probe returns {"status": 301, "message": "…"}; an internal error returns {"status": false, "message": "…"}.
Device tags
Tags group devices and drive tag-scoping. The device-level endpoints add or remove tags on a single device; the catalog endpoint lists all tags in the system.
List all tags
GET/api/tagsdevices
Permission devices (or overwatch, or write_devices)
Returns every tag defined on the appliance (device tags and any other types).
Response 200
{ "status": 200, "tags": [ { "id": 3, "slug": "edge", "name": "Edge", "type": "device" } ] }
List a device’s tags
GET/api/device/{device}/tagsdevices
Returns the device-type tags attached to one device.
Path parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Device id. |
Response 200
{ "status": 200, "tags": [ { "name": "Edge", "slug": "edge", "type": "device" } ] }
Add tags to a device
POST/api/device/{device}/tagswrite_devices
Permission devices and write_devices (both required)
Attaches one or more device tags, creating any tag that does not yet exist (matched by slug + type).
Path parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Device id. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
tags | array | yes | One or more tag objects. |
tags.*.slug | string | yes | Tag slug. |
tags.*.name | string | yes | Max 255. |
tags.*.type | string | yes | Must be device. |
Response 201
{ "status": 201, "message": "Tags added successfully" }
A validation failure returns 400 with {"status": false, "errors": {...}}.
Remove tags from a device
DELETE/api/device/{device}/tagswrite_devices
Permission devices and write_devices (both required)
Detaches the named tags from the device.
Path parameters
| Name | Type | Notes |
|---|---|---|
device | integer | Device id. |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
tags | array | yes | One or more {slug} objects. |
tags.*.slug | string | yes | Must reference an existing tag. |
Response 200
{ "status": 200, "message": "Tags removed successfully" }
Device profiles and credentials
List device profiles
GET/api/device/profilesdevices
Permission devices (or overwatch, or write_devices)
Returns the catalog of device profiles. A profile defines the default dashboard layout and trackers used when a device of that type is added.
Response 200
{ "status": 200, "profiles": [ { "id": 1, "profile": "linux", "layout": [ "…" ] } ] }
List autodiscovery credentials
GET/api/getCredentialswrite_devices
Returns the saved SNMP credential sets used by network autodiscovery.
Response 200
{ "status": 201, "hasError": false, "data": [ { "id": 1, "label": "Default v2", "authuser": null } ] }
Add, edit, or delete a credential
POST/api/addEditCredentialwrite_devices
Creates or updates a credential set (action: "addedit"), or deletes one (action: "delete"). On add/edit, omit id to create; include it to update.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
action | string | yes | addedit or delete. |
id | integer | conditional | Required for delete; optional for addedit (omit to create). |
label | string | for addedit | Display label. |
authuser | string | for addedit | SNMP v3 username. |
snmp_authprot | string | for addedit | v3 auth protocol. |
snmp_privprot | string | for addedit | v3 privacy protocol. |
snmp_community | string | no | Encrypted at rest when present. |
authpass | string | no | Encrypted at rest when present. |
snmp_privpass | string | no | Encrypted at rest when present. |
snmp_community, authpass, and snmp_privpass are encrypted on save and not returned in plaintext. Omit a secret to leave it unchanged.
Response 201 (addedit)
{ "status": 201, "hasError": false, "credential": { "id": 4, "label": "Edge v3" } }
Response 201 (delete)
{ "status": 201, "hasError": false, "message": "Delete Success" }
Unknown or missing action returns {"status": false, "hasError": true, "message": "…"}.
Agent installer download
Download the Windows agent installer
GET/api/agent/download
Permission any authenticated user or a valid signed URL
Streams the latest Windows agent installer for the requested architecture. Covered more fully in the Agents chapter.
This route accepts either a Passport bearer token or a valid, unexpired URL signature (query parameters) in place of a token. The signed form is minted inside an authenticated agent check-in response and is honored without a bearer token. The endpoint is not behind a permission: gate — access is the bearer token or the signature itself.
Query parameters
| Name | Type | Notes |
|---|---|---|
arch | string | amd64 (default) or arm64. |
Response 200 — binary file (Content-Type: application/octet-stream); the filename is the staged installer name, e.g. netmon-agent-installer-<version>-<arch>.exe.
Errors
| Status | Body | When |
|---|---|---|
400 | {"status":false,"message":"Unsupported arch (expected amd64 or arm64)."} | Bad arch. |
404 | {"status":false,"message":"Agent installer not present on this server."} | No installer staged. |
Example
curl -sS "https://APPLIANCE/api/agent/download?arch=amd64" \
-H "Authorization: Bearer $TOKEN" -o netmon-agent.exe
Pending devices (import)
Devices discovered by network scans or self-reported by Windows agents land in a pending queue for operator review before they become monitored devices. All pending-device endpoints require write_devices and are tag-scoped: tag-restricted operators see and act on only pending rows whose tags overlap their slice.
List pending devices
POST/api/getDevicesPendingwrite_devices
Returns pending (un-imported) devices plus the discovery-scan status for each local network. Takes no body.
Response
{
"status": 201,
"hasError": false,
"devices": [
{
"id": 7, "label": "host-7", "ip_address": "10.0.0.7",
"profile": "windows", "enable_agent": true, "agent_uuid": "…",
"last_checkin_at": "2026-06-15T12:00:00Z", "agent_version": "1.4.0",
"os_version": "Windows 11", "tags": [],
"snmpconfig": { "snmp_version": 2, "snmp_community": "…" }
}
],
"discovery_status": [ { "id": 1, "net_id": 1, "start_time": "…", "end_time": "…" } ]
}
Import (adopt) a pending device
POST/api/importPendingwrite_devices
Promotes a pending device to a monitored device, copying its IP, label, profile, agent/SNMP settings, and applying the supplied tags. The pending row is removed on success. Rejected if a device with the same IP already exists.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | yes | Pending-device id. |
tags | array | no | {slug, name, type:"device"} items applied to the adopted device. |
Response 201
{ "status": 201, "hasError": false, "message": "Import Successful" }
A duplicate IP returns {"status": false, "hasError": true, "message": "A device with the IP address … already exists."}.
Hide a pending device
POST/api/hidePendingDevicewrite_devices
Hides a pending row from the default import list without deleting it.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | yes | Pending-device id. |
Response 201
{ "status": 201, "hasError": false, "message": "Device hidden successfully" }
Remove a pending device
POST/api/removePendingDevicewrite_devices
Permanently deletes a pending row from the import queue.
Deletes the pending-device record. The device may reappear if discovery or an agent check-in detects it again.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | yes | Pending-device id. |
Response 201
{ "status": 201, "hasError": false, "message": "Device removed successfully" }
Update a pending device field
POST/api/updatePendingDeviceFieldwrite_devices
Edits a single field on a pending device before import (for example, correcting the profile or supplying SNMP credentials).
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | yes | Pending-device id. |
field | string | yes | One of label, profile, enable_snmp, enable_agent, snmp_community, snmp_port, snmp_version, snmp_v3_security, authuser, authpass, authprot, privpass, privprot. |
value | mixed | yes | New value. Secret fields (snmp_community, authpass, privpass) are encrypted on save. |
Response 201
{ "status": 201, "hasError": false, "message": "Device updated successfully" }
Validation failures return 422 with {"status": false, "hasError": true, "message": {...}}.
Update a pending device’s tags
POST/api/updatePendingDeviceTagswrite_devices
Replaces the tag set on a pending device. Tags carried into import via importPending come from here.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
id | integer | yes | Pending-device id. |
tags | array | yes | One or more {slug, name, type:"device"} objects. |
Response 201
{ "status": 201, "hasError": false, "message": "Tags updated successfully" }
Dashboards, layouts, and trackers
These endpoints persist per-user dashboard state — the home dashboard, per-device widget layouts, pinned widgets, and the trackers shown on a device page. Layout/pinned-widget writes are tag-scoped to the device id.
Get the user’s dashboards
GET/api/getDashboards
Permission any authenticated user
Returns the calling user’s saved home dashboards and their layouts. New users with no saved state get empty objects.
Response 200
{ "dashboards": {}, "layouts": {} }
Save the user’s dashboards
POST/api/setDashboards
Permission any authenticated user
Upserts the calling user’s home dashboards and layouts.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
dashboards | object | no | Dashboard definition map. |
layouts | object | no | Layout map. |
Response 201
{ "message": "Updated layouts" }
Add a widget to a dashboard
POST/api/addWidgetToDashdevices
Appends a single widget to a named dashboard of the calling user, creating the dashboard if it does not yet exist.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
dashboardName | string | yes | Target dashboard name. |
widget | object | yes | Must contain a positive widgetId. |
Response 201
{ "status": "success" }
Invalid input returns 400 with {"error": "Invalid parameter"}.
Get a device’s trackers and layout
GET/api/getDeviceTrackersdevices
Returns the available tracker widgets for a device (ping, ports, OIDs, interfaces, disks, and Hyper-V VM trackers), merged with the profile’s default layout, plus the calling user’s saved layout and pinned widgets for that device.
Query parameters
| Name | Type | Notes |
|---|---|---|
deviceId | integer | Required. Must reference an existing device. |
Response 200
{
"hasError": false,
"trackers": [ { "trackerId": "12", "trackerTable": "oids", "widgetId": 4, "w": 4, "h": 3 } ],
"layouts": null,
"pinnedWidgets": []
}
When the device has no trackers at all the endpoint returns 204 with {"message": "no trackers"}; a missing/invalid deviceId returns 422.
Save a device layout
POST/api/setDeviceLayoutsdevices
Upserts the calling user’s saved widget layout for one device.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
deviceId | integer | yes | Device id (tag-scoped). |
layouts | array/object | yes | Grid layout payload. |
Response 201
{ "hasError": false, "message": "Device trackers set successfully." }
Missing parameters return 400; an out-of-scope deviceId returns 404.
Save device pinned widgets
POST/api/setDevicePinnedWidgetsdevices
Upserts the calling user’s pinned-widget set for one device.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
deviceId | integer | yes | Device id (tag-scoped). |
pinnedWidgets | array/object | yes | Pinned-widget payload. |
Response 201
{ "hasError": false, "message": "Pinned widgets set successfully." }
Delete a device layout
POST/api/deleteDeviceLayoutsdevices
Deletes the calling user’s saved layout for one device, reverting that device’s dashboard to the profile default.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
deviceId | integer | yes | Device id (tag-scoped). |
Response 201
{ "hasError": false, "message": "Device layouts deleted successfully." }
Returns 404 when no saved layout exists for that device and user, 400 when deviceId is missing.
Latency tracker history
POST/api/getLatencyTrackerdevices
Returns the ping latency/loss time series for a device’s ICMP probe over the requested window.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
deviceId | integer | yes | Device id (tag-scoped). |
hours | integer | no | Look-back window in hours (default 4). |
Response 200
{
"status": 200, "hasError": false,
"message": {
"dev_label": "core-switch", "dev_ip": "10.0.0.1",
"logs": [ { "icmping_id": 5, "latency": 1.2, "loss": 0, "timestamp": 1718450000 } ]
}
}
When the device has no ping probe the endpoint returns {"status": 204, "hasError": false, "message": {}}.
TCP/port tracker history
POST/api/getTCPTrackerdevices
Returns the latency time series for one monitored TCP/UDP port on a device.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
deviceId | integer | yes | Device id (tag-scoped). |
id | integer | yes | Port (tracker) id. |
hours | integer | no | Look-back window in hours (default 4). |
Response 200
{
"status": 200, "hasError": false,
"message": {
"dev_label": "edge-fw", "port": 443,
"logs": [ { "port_id": 9, "latency": 4.1, "timestamp": 1718450000 } ]
}
}
Missing deviceId/id, or no matching port, returns {"status": 204, "hasError": false, "message": {}}.
Network discovery helpers
These endpoints surface ARP and NetFlow data used by the network-overview dashboard. All are tag-scoped to the calling user’s device IPs.
Recently seen hosts
POST/api/getRecentHostdevices
Returns the most recent ARP sighting per IP (unicast addresses only) within the look-back window, joined to a hostname where one is known.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
hours | integer | no | Look-back window in hours (default 1). |
Response 200
{
"status": 200, "hasError": false,
"hosts": [ { "ip": "10.0.0.7", "mac": "aa:bb:cc:00:11:22", "hostname": "host-7", "device_id": 7 } ]
}
ARP table
POST/api/getArpTabledevices
Returns the latest ARP entry per IP over a window, with optional search across IP, MAC, and hostname.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
hours | integer | no | Look-back window in hours (default 24). |
search | string | no | Case-insensitive match on IP, MAC, or hostname. |
Response 200
{
"status": 200, "hasError": false,
"hosts": [ { "ip": "10.0.0.7", "mac": "aa:bb:cc:00:11:22", "hostname": "host-7", "device_id": 7 } ],
"total": 1
}
ARP scan status
GET/api/getArpScanStatusdevices
Returns the timestamp of the most recent ARP entry and the total host count in scope. Takes no body.
Response 200
{ "status": 200, "hasError": false, "last_scan": "2026-06-15T12:00:00Z", "total_hosts": 42 }
Top bandwidth talkers
GET/api/getTopBandwidth/{mins}devices
Returns the top 20 source/destination conversations by bytes over the last {mins} minutes, with hostnames where known.
Path parameters
| Name | Type | Notes |
|---|---|---|
mins | integer | Look-back window in minutes. |
Response 200
{
"status": 200, "hasError": false, "mins": 15,
"data": [
{ "src_host": "host-a", "src_ip": "10.0.0.5", "dst_host": "host-b",
"dst_ip": "10.0.0.9", "bytes": 10485760, "bps": 93206 }
]
}
Set a custom hostname
POST/api/setCustomHostnamewrite_devices
Pins a custom hostname to an IP address, overriding any auto-resolved name. Tag-restricted operators may only set hostnames for IPs inside their scope.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
hostname | string | yes | Max 255. |
ip_address | string (IP) | yes | Target IP. |
Response 201
{ "status": 201, "hasError": false, "message": "Custom hostname set successfully", "host": { "ip": "10.0.0.7", "hostname": "edge-fw" } }
An out-of-scope IP returns 403; validation/save errors return 500.
Navigation counts
Get navigation counts
GET/api/getNavData
Permission any authenticated user
Returns the badge counts shown in the navigation bar — total devices, active alerts, pending devices — and the calling user’s permission slugs. All counts are tag-scoped for tag-restricted users.
Response 201
{
"status": 201, "hasError": false,
"data": { "devices": 42, "alerts": 3, "pending": 5, "perms": ["devices","write_devices","alerts"] }
}
Hyper-V
These endpoints expose Hyper-V virtualization inventory collected from a Windows host running the agent. They are read-only and tag-scoped to the host device.
Get Hyper-V inventory
GET/api/devices/{deviceId}/hypervdevices
Returns the latest Hyper-V inventory for a host: its virtual machines, each VM’s virtual NICs, and a monitored_device cross-reference on any NIC whose MAC matches a separately-monitored device in your scope.
Path parameters
| Name | Type | Notes |
|---|---|---|
deviceId | integer | The Hyper-V host’s device id. |
Response 200
{
"device_id": 42, "device_label": "hyperv-01",
"walk_id": 880, "collected_at": "2026-06-15T12:00:00Z",
"envelope": {
"vms": [
{ "guid": "ABC-123", "name": "vm-web",
"nics": [ { "mac": "00:15:5d:01:02:03",
"monitored_device": { "device_id": 51, "label": "vm-web" } } ] }
]
}
}
Errors
| Status | Body | When |
|---|---|---|
404 | {"error":"No Hyper-V inventory available for this device."} | No inventory collected (role absent or not yet polled). |
404 | {"error":"Device not found."} | Out-of-scope or unknown device. |
500 | {"error":"Hyper-V inventory blob is malformed."} | Stored inventory could not be parsed. |
Get VM CPU history
GET/api/devices/{deviceId}/hyperv/vm/{vmGuid}/cpudevices
Returns the CPU-usage sparkline series for one VM on a Hyper-V host. GUID matching is case-insensitive.
Path parameters
| Name | Type | Notes |
|---|---|---|
deviceId | integer | The Hyper-V host’s device id. |
vmGuid | string | VM GUID. |
Query parameters
| Name | Type | Notes |
|---|---|---|
hours | integer | Look-back window, clamped to 1–168 (default 4). |
Response 200
{
"vm_guid": "ABC-123", "hours": 4,
"series": [ { "ts": 1718450000, "usage_pct": 12.5 }, { "ts": 1718451800, "usage_pct": null } ]
}
Returns 404 with {"error":"No Hyper-V walk on this device."} when the host has no Hyper-V inventory.