Netmon Docs · API Reference

Agentsv7.0.20

Drive the Netmon Windows agent from the API — enumerate a host’s processes, services, and disk usage, control its services, delete files, and mint or adopt the credentials that provision new agents at scale.

The Netmon agent is a lightweight Windows service that enrolls to one or more appliances and reports on the host it runs on. Once a device is agent-backed, these endpoints let you enumerate its running processes and services, walk its disk usage, control its services, delete files and folders, and manage the bootstrap tokens used to provision new agents in bulk.

The endpoints split across two functional areas. The read probes and live identity lookups belong to the devices area (token scope mcp:devices); the privileged file-deletion and enrollment-token endpoints sit in the system/agent-admin area (token scope mcp:system). The Laravel permission enforced on each endpoint is shown in its block — devices for the read probes, agentadmin for the file and token operations — and is enforced regardless of how the bearer token was obtained.

Tag-scoping applies to the device-targeted probes and actions. Every endpoint that names a device runs a live command against that host, so the calling user must be able to see the device under their tag restriction. A tag-restricted user driving a probe or action against a device outside their tags gets a 403/404 denial; a user with no tag restriction can reach any device, and sa (super-admin) bypasses scoping entirely. The enrollment-token endpoints are not device-scoped — they mint and manage provisioning credentials, not device commands.

Two enrollment endpoints are public. POST /api/agent/checkin and POST /api/agent/enroll are called by the agent itself, unauthenticated, and are rate-limited rather than permission-gated. They are documented at the end of this page as agent-facing, not as operator bearer-token calls.

Request field naming

The device-targeted endpoints read their parameters straight from the request body without a strict schema. The process and service endpoints expect device_id; the disk-usage and file endpoints expect deviceid (one word). Use the exact field name shown in each block.

Read probes

These endpoints enumerate the live state of the host without changing anything. They are gated by the devices permission.

List processes

POST/api/getDeviceProcessesdevices

Returns the process list reported by the agent on the target host.

Request body

FieldTypeRequiredNotes
device_idintegeryesTarget device.

Response 200

{ "status": 201, "message": [ { "Name": "explorer.exe", "Id": 4120, "…": "…" } ] }

Errors

StatusBodyWhen
400{"message":"…"}Agent command failed, timed out, or returned an error frame.

Example

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

List services

POST/api/getDeviceServicesdevices

Returns the Windows service inventory (Name, State, DisplayName) reported by the agent.

Request body

FieldTypeRequiredNotes
device_idintegeryesTarget device.

Response 200

{ "status": 201, "message": [ { "Name": "Spooler", "State": "Running", "DisplayName": "Print Spooler" } ] }

Errors

StatusBodyWhen
400{"message":"…"}Agent command failed or returned an error frame.

Look up an agent ID

POST/api/getAgentIDdevices

Permission devices (or write_devices)

Runs a live WMI probe to fetch the agent’s unique identifier from a host. Identify the host by either its device id or its IP address — supply exactly one.

Request body

FieldTypeRequiredNotes
device_idintegerone ofDevice id. Must be numeric.
ip_addressstringone ofHost IP. Must be a valid IP.

Response 200

{ "status": 200, "message": "<agent uuid>" }

Errors

StatusBodyWhen
400{"message":"Either device ID or IP address is required"}Neither identifier supplied.
404{"message":"Device not found"}No matching device in your tag scope.
400{"message":"…"}WMI probe failed.

Example

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

Disk-usage probes

These endpoints walk the host’s file system to report disk consumption. They are gated by the devices permission and expect the deviceid field (one word). A full disk-usage tree is produced in two steps: trigger generation, then fetch the result; the per-path and folder variants read sub-trees on demand.

Generate the disk-usage tree

POST/api/generateDiskUsagedevices

Asks the agent to (re)build its cached disk-usage tree for the host. Returns once the agent acknowledges the request; fetch the result with Get the detailed disk-usage tree.

Request body

FieldTypeRequiredNotes
deviceidintegeryesTarget device.

Response 200

{ "status": 201, "message": "<agent output>" }

Get the detailed disk-usage tree

POST/api/getDetailedDiskUsagedevices

Returns the full disk-usage tree the agent has cached. Newer agents return the tree in one round trip; older agents are transparently served via a legacy chunked pull, so the response shape is the same either way.

Request body

FieldTypeRequiredNotes
deviceidintegeryesTarget device.

Response 200

{ "status": 201, "message": [ { "path": "C:\\Windows", "size": 18273645123, "children": [] } ] }

On a failure the response is {"status": false, "message": "…"} with HTTP 200.

Get folder usage by path

POST/api/getFolderUsageFromPathdevices

Returns the disk usage of one folder (and its immediate contents) by absolute path — used to drill into a sub-tree without regenerating the whole report.

Request body

FieldTypeRequiredNotes
deviceidintegeryesTarget device.
pathstringyesAbsolute path on the host, e.g. C:\Users.

Response 200

{ "status": 201, "message": { "path": "C:\\Users", "size": 4821934, "children": [] } }

File operations

These endpoints delete files and folders on the monitored host. They are gated by the agentadmin permission and expect the deviceid field (one word).

Destructive

Deletion is immediate and permanent on the target host — there is no recycle-bin step and no undo. Verify the path before calling.

Delete a file

POST/api/tryDeleteFileagentadmin

Deletes a single file on the host by absolute path.

Request body

FieldTypeRequiredNotes
deviceidintegeryesTarget device.
pathstringyesAbsolute path to the file.

Response 200

{ "status": 201, "message": "<agent output>" }

If the agent reports it could not delete the file, the response is {"status": false, "message": "Failed to process request"} with HTTP 200.

Delete a folder

POST/api/tryDeleteFolderagentadmin

Deletes a folder (and its contents) on the host by absolute path. Same request and response shape as Delete a file.

Request body

FieldTypeRequiredNotes
deviceidintegeryesTarget device.
pathstringyesAbsolute path to the folder.

Response 200

{ "status": 201, "message": "<agent output>" }

Enrollment tokens

Enrollment tokens are one-shot or reusable bootstrap credentials for provisioning agents at scale (batch or MDM deploys). An operator mints a token, hands the plaintext to the host’s agent CLI (--add-server <url> --token <plaintext>), and the agent enrolls itself without waiting for manual adoption under Device Import. These endpoints are gated by agentadmin.

Plaintext shown once

The token plaintext is returned only in the create response. The appliance stores only its SHA-256 hash, so the plaintext cannot be retrieved later — copy it when you mint it. If lost, revoke the token and mint a new one.

List active tokens

GET/api/agent-tokensagentadmin

Returns the tokens an operator can still hand out: non-consumed, non-revoked, and not yet expired, newest first. Consumed and revoked rows survive for the audit trail but are not listed here.

Response 200

[
  {
    "id": 7,
    "label": "branch-rollout",
    "tags": ["windows"],
    "ttl_seconds": 86400,
    "single_use": true,
    "expires_at": "2026-06-16T12:00:00Z",
    "consumed_at": null,
    "revoked_at": null,
    "created_by_user_id": 3
  }
]
Response shape

This endpoint returns a bare array of token rows, not an object envelope.

Mint a token

POST/api/agent-tokensagentadmin

Issues a new enrollment token. The response carries the persisted row plus the one-time plaintext in a token field.

Request body

FieldTypeRequiredNotes
labelstringnoFree-text label, max 255.
tagsarray of stringnoDevice tag slugs (max 64 each) applied to devices enrolled with this token.
ttl_secondsintegernoLifetime in seconds. Min 60, max 2592000 (30 days). Default 86400 (1 day).
single_usebooleannotrue (default) consumes the token on first use; false allows reuse until expiry.

Response 201

{
  "id": 7,
  "label": "branch-rollout",
  "tags": ["windows"],
  "ttl_seconds": 86400,
  "single_use": true,
  "expires_at": "2026-06-16T12:00:00Z",
  "token": "9fK2pL7mXq4RtY8wZ1nB3vC6dH0sJ5aG2eU4oI7kM1xP"
}

Errors

StatusBodyWhen
400{"errors":{...}}Validation failed.
500{"error":"Failed to create token"}Server error while minting.

Example

curl -sS -X POST https://APPLIANCE/api/agent-tokens \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"label":"branch-rollout","tags":["windows"],"ttl_seconds":86400,"single_use":true}'

Get a token

GET/api/agent-tokens/{id}agentadmin

Returns a single token row by id (including consumed/revoked rows). The plaintext is never returned here — only the create response carries it.

Path parameters

NameTypeNotes
idintegerToken id.

Response 200

{ "id": 7, "label": "branch-rollout", "single_use": true, "consumed_at": null, "revoked_at": null }

Errors

StatusBodyWhen
404{"error":"Token not found"}No such token.

Revoke a token

DELETE/api/agent-tokens/{id}agentadmin

Revokes a token so it can no longer enroll an agent. The row is not hard-deleted — revocation preserves the audit lineage of any device the token already provisioned.

Destructive

Revocation immediately invalidates the token. Any host that has not yet enrolled with it will fail enrollment and must be re-issued a fresh token.

Path parameters

NameTypeNotes
idintegerToken id.

Response 200

{ "revoked": true }

Errors

StatusBodyWhen
409{"error":"Token already revoked"}Token was already revoked.
404{"error":"Token not found"}No such token.

Operator-driven adoption

Adopt a host by minted key

POST/api/agent/adopt-by-tokenwrite_devices

Permission devices and write_devices (both required)

Adopts a host that minted its own adoption key (the host ran NetmonAgent.exe --mint-key and printed a short token). The appliance dials the host directly over UDP/489 with the token, reads back the agent’s identity, creates or updates the device record, and then pushes its server key bundle to the host so the agent can answer polls — the whole enrollment completes in this one call, and the adoption key is consumed by it (one key adopts one host, once). Use this for hosts that cannot or should not reach out to the appliance themselves (for example, many Windows hosts behind one NAT address). The IP address you supply is authoritative — it is never overwritten by anything the agent reports. Throttled to 15 requests/minute.

Request body

FieldTypeRequiredNotes
ip_addressstringyesThe host IP the appliance dials. Must be a valid IP.
tokenstringyesThe adoption key minted on the host. 10–64 chars, [A-Za-z0-9_-].
labelstringnoFriendly device label. Defaults to the host’s reported hostname, then the IP.
profilestringnoDevice profile slug. Defaults to dash_windows_wmi.
tagsarray of stringnoDevice tag slugs (max 64 each). Tag-restricted operators may only apply slugs they already hold; out-of-scope slugs are silently dropped.

Response 200

{ "device_id": 88, "agent_uuid": "5f2c1e9a-...", "enrolled": true }

enrolled: false is a partial success: the device record was created, but the agent did not acknowledge the key-bundle push (typically a dropped UDP reply). Repeat the same call to resend the bundle — both legs of the exchange are idempotent on the agent, so retrying is always safe, even after the key has been consumed.

Errors

StatusBodyWhen
400{"errors":{...}}Validation failed.
404{"error":"Agent did not respond. …"}Host silent: wrong IP, agent not running, wrong token, or UDP/489 unreachable. The same message is returned for every failure so a bad token cannot be fingerprinted.
500{"error":"Adoption failed"}Server error during adoption.

Example

curl -sS -X POST https://APPLIANCE/api/agent/adopt-by-token \
  -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  -d '{"ip_address":"10.0.4.15","token":"4K7M-2P9Q-RST3-UVW4-XY5Z","label":"sales-pc-01"}'

Agent check-in & enrollment (public)

These two endpoints are called by the agent on the host, not by an operator. They take no bearer token and are rate-limited per source IP. They are documented here for completeness — you would not normally call them from a script.

Agent check-in

POST/api/agent/checkin

Permission none (public endpoint, throttled to 60 requests/minute per IP)

The agent’s polling heartbeat. On each call the appliance does one of three things: if the agent is already adopted, it refreshes the host’s IP and returns the key bundle; if a valid enrollment token is present, it fast-tracks the device into the inventory and returns the key bundle; otherwise it parks the agent in the pending-devices list for an operator to adopt under Device Import.

Request body

FieldTypeRequiredNotes
agent_uuidstringyesAgent’s unique id. 8–64 chars, [A-Za-z0-9_-:].
hostnamestringyesWindows hostname. Printable ASCII, no angle brackets. Max 255.
agent_versionstringnoAgent semver. Max 64.
os_versionstringnoHost OS version string. Max 128.
archstringnoamd64 (default) or arm64.
tokenstringnoEnrollment token plaintext for the fast-track path. 32–128 chars.

Response 200 (adopted / fast-tracked) — key bundle

{
  "server_id": "9b1f…",
  "server_url": "https://APPLIANCE",
  "public_key": "MIIBIjANBgkq…",
  "allowed_source_ips": ["10.0.0.10"],
  "device_id": 88,
  "update": { "version": "7.0.21", "url": "https://APPLIANCE/api/agent/download?…", "sha256": "…", "signature": "…" }
}

The update block is present only when an installer for the agent’s architecture is staged on the appliance; otherwise it is omitted.

Response 202 (awaiting adoption)

{ "status": "pending", "message": "Awaiting operator adoption under Device Import → Pending Devices" }

Errors

StatusBodyWhen
400{"errors":{...}}Validation failed.
409{"error":"Source IP … already claimed …"}The source IP is already held by another device (NAT collision); the agent CLI retries with --override-ip.
500{"error":"Check-in failed"}Server error.

Agent enroll

POST/api/agent/enroll

Permission none (public endpoint, throttled to 30 requests/minute per IP)

The fast-track enrollment path for batch and pre-authorized deploys. Functionally equivalent to Agent check-in with a token, but the token is required at the route boundary. On success the device row is created immediately (skipping the pending-review step) and the key bundle is returned.

Request body

FieldTypeRequiredNotes
tokenstringyesEnrollment token plaintext. 32–128 chars.
agent_uuidstringyesAgent’s unique id. 8–64 chars, [A-Za-z0-9_-:].
hostnamestringyesWindows hostname. Printable ASCII, no angle brackets. Max 255.
agent_versionstringnoAgent semver. Max 64.
os_versionstringnoHost OS version string. Max 128.

Response 200 — the same key bundle as Agent check-in (adopted path).

{
  "server_id": "9b1f…",
  "server_url": "https://APPLIANCE",
  "public_key": "MIIBIjANBgkq…",
  "allowed_source_ips": ["10.0.0.10"],
  "device_id": 88
}

Errors

StatusBodyWhen
400{"errors":{...}}Validation failed.
401{"error":"Invalid token"} (or Token revoked / Token expired / Token already consumed)Token rejected.
409{"error":"Source IP … already claimed …"}NAT collision on the source IP.
500{"error":"Enrollment failed"}Server error.