# Terminal: System Monitoring

**Page:** api/terminal/monitoring

[Download Raw Markdown](./api/terminal/monitoring.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



The Terminal System Monitoring API exposes system-level operations on a Hoody node. Use these endpoints to inspect running processes, audit network listeners, query resource utilization, manage connected displays, and control system power. All endpoints require an authenticated Hoody session except `/api/v1/terminal/health`, which is unauthenticated and always returns 200 when the service is running.

## Service Health

### `GET /api/v1/terminal/health`

Returns the standardized 9-field health response. Always returns HTTP 200 with `application/json` when the terminal service is up. Unauthenticated.

This endpoint takes no parameters.



```bash
curl -X GET https://api.hoody.com/api/v1/terminal/health
```


```typescript
const health = await client.terminal.health.check();
```


```json
{
  "status": "healthy",
  "service": "terminal",
  "version": "1.4.2",
  "uptime_seconds": 86400,
  "timestamp": "2025-01-15T10:30:00Z",
  "database": { "status": "ok", "latency_ms": 2 },
  "daemon": { "status": "ok" },
  "memory": { "used": 134217728, "total": 268435456 },
  "goroutines": 42
}
```



## System Resources

### `GET /api/v1/system/resources`

Returns comprehensive system statistics including CPU usage, memory, network interfaces, uptime, and disk usage.

This endpoint takes no parameters.



```bash
curl -X GET https://api.hoody.com/api/v1/system/resources \
  -H "Authorization: Bearer <token>"
```


```typescript
const stats = await client.terminal.system.getResources();
```


```json
{
  "cpu": {
    "usage_percent": 12.5,
    "cores": 8,
    "load_average": [0.5, 0.7, 0.9]
  },
  "memory": {
    "total": 16777216000,
    "used": 8589934592,
    "free": 8187281408,
    "usage_percent": 51.2
  },
  "disk": {
    "total": 500107862016,
    "used": 250053931008,
    "free": 250053931008,
    "usage_percent": 50.0
  },
  "network": [
    {
      "name": "eth0",
      "bytes_sent": 1234567890,
      "bytes_received": 9876543210,
      "packets_sent": 8765432,
      "packets_received": 12345678
    }
  ],
  "uptime_seconds": 86400
}
```



## Daemon Programs

### `GET /api/v1/system/daemon`

Returns the JSON array of daemon programs from the `hoody-daemon` configuration.

This endpoint takes no parameters.



```bash
curl -X GET https://api.hoody.com/api/v1/system/daemon \
  -H "Authorization: Bearer <token>"
```


```typescript
const daemons = await client.terminal.system.getDaemonConfig();
```


```json
[
  {
    "name": "hoody-daemon",
    "command": "/usr/local/bin/hoody-daemon",
    "autostart": true,
    "restart": "on-failure"
  },
  {
    "name": "kit-watchdog",
    "command": "/usr/local/bin/kit-watchdog",
    "autostart": true,
    "restart": "always"
  }
]
```



## Displays

### `GET /api/v1/system/displays`

Returns information about connected displays from the external display script.

This endpoint takes no parameters.



```bash
curl -X GET https://api.hoody.com/api/v1/system/displays \
  -H "Authorization: Bearer <token>"
```


```typescript
const displays = await client.terminal.system.getDisplayInfo();
```


```json
[
  {
    "name": "DisplayPort-0",
    "resolution": "3840x2160",
    "position": [0, 0],
    "primary": true,
    "scale": 1.0,
    "refresh_rate": 60
  },
  {
    "name": "HDMI-A-1",
    "resolution": "1920x1080",
    "position": [3840, 0],
    "primary": false,
    "scale": 1.0,
    "refresh_rate": 60
  }
]
```



## Processes

### `GET /api/v1/system/processes`

Returns a JSON array of all processes with CPU, memory, and state information. Supports filtering, sorting, and limiting the result set.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `sort` | query | string | No | Sort by field. Allowed values: `cpu`, `memory`, `pid`, `name`. Default: `pid` |
| `limit` | query | integer | No | Maximum number of processes to return. Default: returns all |
| `filter` | query | string | No | Filter by process name (substring match, case-insensitive) |



```bash
curl -X GET "https://api.hoody.com/api/v1/system/processes?sort=cpu&limit=10&filter=nginx" \
  -H "Authorization: Bearer <token>"
```


```typescript
for await (const process of client.terminal.system.listProcessesIterator({
  sort: "cpu",
  limit: 10,
  filter: "nginx"
})) {
  console.log(process);
}
```


```json
[
  {
    "pid": 1234,
    "name": "nginx",
    "cpu_percent": 2.5,
    "memory_percent": 1.2,
    "state": "S",
    "command": "nginx: master process /usr/sbin/nginx"
  },
  {
    "pid": 1235,
    "name": "nginx",
    "cpu_percent": 0.8,
    "memory_percent": 0.6,
    "state": "S",
    "command": "nginx: worker process"
  }
]
```



### `GET /api/v1/system/processes/{pid}`

Returns detailed information about a specific process, including all stats, `cmdline`, environment, and open files.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `pid` | path | integer | Yes | Process ID |



```bash
curl -X GET https://api.hoody.com/api/v1/system/processes/1234 \
  -H "Authorization: Bearer <token>"
```


```typescript
const proc = await client.terminal.system.getProcess({ pid: 1234 });
```


```json
{
  "pid": 1234,
  "name": "nginx",
  "cmdline": "nginx: master process /usr/sbin/nginx -g daemon off;",
  "state": "S",
  "ppid": 1,
  "username": "root",
  "cpu_percent": 2.5,
  "memory_percent": 1.2,
  "memory_rss": 12582912,
  "memory_vms": 134217728,
  "create_time": "2025-01-15T08:00:00Z",
  "num_threads": 4
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Process 99999 not found",
  "code": "PROCESS_NOT_FOUND"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PROCESS_NOT_FOUND` | Process does not exist | The requested PID is not running or has terminated | Check PID is valid and process is running |



## Network Ports

### `GET /api/v1/system/ports`

Returns a JSON array of all TCP/UDP listening ports, including process information. Supports extensive filtering to narrow the result set.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `protocol` | query | string | No | Filter by protocol: `tcp`, `udp`, or comma-separated list |
| `user` | query | string | No | Filter by user (exact match) |
| `port` | query | integer | No | Filter by specific port number |
| `ip` | query | string | No | Filter by IP address (comma-separated list) |
| `skip_program` | query | string | No | Exclude specific programs (comma-separated list) |
| `http_only` | query | boolean | No | Only return HTTP services |
| `hoody_only` | query | boolean | No | Only return Hoody Kit services |



```bash
curl -X GET "https://api.hoody.com/api/v1/system/ports?protocol=tcp&http_only=true&limit=50" \
  -H "Authorization: Bearer <token>"
```


```typescript
for await (const port of client.terminal.system.listPortsIterator({
  protocol: "tcp",
  http_only: true
})) {
  console.log(port);
}
```


```json
[
  {
    "protocol": "tcp",
    "port": 22,
    "address": "0.0.0.0",
    "state": "LISTEN",
    "pid": 890,
    "process": "sshd",
    "user": "root"
  },
  {
    "protocol": "tcp",
    "port": 80,
    "address": "0.0.0.0",
    "state": "LISTEN",
    "pid": 1234,
    "process": "nginx",
    "user": "www-data"
  },
  {
    "protocol": "tcp",
    "port": 443,
    "address": "0.0.0.0",
    "state": "LISTEN",
    "pid": 1234,
    "process": "nginx",
    "user": "www-data"
  }
]
```



## Process Signals

### `POST /api/v1/system/process/signal`

Send a Unix signal to one or more processes by PID or name. Supports all standard signals (`SIGTERM`, `SIGKILL`, `SIGSTOP`, `SIGCONT`, etc.). When targeting by `name`, the signal is sent to **all** matching processes.

This endpoint takes no path or query parameters.

### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `pid` | integer | No | Process ID to signal (mutually exclusive with `name`) |
| `name` | string | No | Process name to signal &mdash; signals ALL matching processes (mutually exclusive with `pid`) |
| `signal` | string \| integer | No | Signal to send. String form accepts `SIGTERM`, `TERM`, `15`, etc. (with or without `SIG` prefix). Integer form accepts any value in `[0, NSIG)` including realtime signals `SIGRTMIN`..`SIGRTMAX` (typically 34..64 on Linux), which have no portable string names. |
| `force` | boolean | No | Shorthand for `SIGKILL` (`true`) or `SIGTERM` (`false`) &mdash; overrides the `signal` parameter |

```json
{
  "pid": 1234,
  "signal": "SIGTERM"
}
```


At least one of `pid` or `name` must be provided. Omitting both returns `MISSING_TARGET`. When both are provided, `pid` takes precedence.




```bash
curl -X POST https://api.hoody.com/api/v1/system/process/signal \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"pid": 1234, "signal": "SIGTERM"}'
```


```typescript
const result = await client.terminal.system.sendSignal({
  data: {
    pid: 1234,
    signal: "SIGTERM"
  }
});
```


```json
{
  "success": true,
  "signal": "SIGTERM",
  "pid": 1234,
  "timestamp": "2025-01-15T10:30:00Z"
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Must specify pid or name",
  "code": "MISSING_TARGET"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MISSING_TARGET` | Must specify pid or name | Neither `pid` nor `name` was provided in the request body | Provide either `pid` or `name` parameter |
| `INVALID_SIGNAL` | Invalid signal name | The signal value is not a recognized signal name or valid integer | Use valid signal (`SIGTERM`, `SIGKILL`, etc.) |


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "No permission to signal process",
  "code": "PERMISSION_DENIED"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `PERMISSION_DENIED` | No permission to signal process | The Hoody process does not have permission to signal the target process | Check process ownership |


```json
{
  "statusCode": 405,
  "error": "Method Not Allowed",
  "message": "Method GET not allowed",
  "allow": "POST"
}
```


```json
{
  "statusCode": 500,
  "error": "Internal Server Error",
  "message": "Failed to send signal",
  "code": "SIGNAL_FAILED"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SIGNAL_FAILED` | Failed to send signal | The signal could not be delivered to the target process | Check process exists |



## System Power

### `POST /api/v1/system/reboot`

Initiate a system reboot with optional delay. Requires root or sudo privileges &mdash; the Linux kernel enforces the permission check. Because `shutdown(8)` schedules in whole minutes, the server rounds the delay **up** to the nearest minute and reports the actual scheduled value as `effective_minutes` in the response.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `delay` | query | integer | No | Delay in seconds before reboot, range `0..86400`. Default: `0` (immediate) |



```bash
curl -X POST "https://api.hoody.com/api/v1/system/reboot?delay=60" \
  -H "Authorization: Bearer <token>"
```


```typescript
const result = await client.terminal.system.reboot({ delay: 60 });
```


```json
{
  "success": true,
  "effective_minutes": 1,
  "scheduled_at": "2025-01-15T10:31:00Z"
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Delay out of range (> 86400)",
  "code": "INVALID_DELAY"
}
```


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Reboot requires root privileges",
  "code": "ROOT_REQUIRED"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `ROOT_REQUIRED` | Reboot requires root privileges | The Hoody process is not running as root or with sudo | Run with sudo or as root user |


```json
{
  "statusCode": 405,
  "error": "Method Not Allowed",
  "message": "Method GET not allowed",
  "allow": "POST"
}
```


```json
{
  "statusCode": 500,
  "error": "Internal Server Error",
  "message": "Failed to execute reboot",
  "code": "REBOOT_FAILED"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `REBOOT_FAILED` | Failed to execute reboot | The `shutdown` command could not start the reboot sequence | Check system logs |



### `POST /api/v1/system/shutdown`

Initiate a system shutdown with optional delay. Requires root or sudo privileges &mdash; the Linux kernel enforces the permission check. The delay is rounded up to the nearest minute by `shutdown(8)`, and the actual scheduled value is reported as `effective_minutes` in the response.

### Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `delay` | query | integer | No | Delay in seconds before shutdown, range `0..86400`. Default: `0` (immediate) |



```bash
curl -X POST "https://api.hoody.com/api/v1/system/shutdown?delay=300" \
  -H "Authorization: Bearer <token>"
```


```typescript
const result = await client.terminal.system.shutdown({ delay: 300 });
```


```json
{
  "success": true,
  "effective_minutes": 5,
  "scheduled_at": "2025-01-15T10:35:00Z"
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Delay out of range (> 86400)",
  "code": "INVALID_DELAY"
}
```


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Shutdown requires root privileges",
  "code": "ROOT_REQUIRED"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `ROOT_REQUIRED` | Shutdown requires root privileges | The Hoody process is not running as root or with sudo | Run with sudo or as root user |


```json
{
  "statusCode": 405,
  "error": "Method Not Allowed",
  "message": "Method GET not allowed",
  "allow": "POST"
}
```


```json
{
  "statusCode": 500,
  "error": "Internal Server Error",
  "message": "Failed to execute shutdown",
  "code": "SHUTDOWN_FAILED"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SHUTDOWN_FAILED` | Failed to execute shutdown | The `shutdown` command could not start the shutdown sequence | Check system logs |