# 3pm-backend route `nodeHost`

Paths are relative to the backend's origin (https://fleet.edgecr4ft.net, or your own 3pm-backend), not to this site. Index: https://3pm.edgecr4ft.net/docs/backend/api.md

---

tokens:
  claude: 2075
  o200k: 1252
# GET /api/buckets/{clusterId}/nodes/{nodeId}/host (nodeHost)

The node's host as it is now, whole: the gauges and counters with the identity (hostname, OS, totals, interface and mount names) the feed's ticks blank; 404 before its first frame, and for a node that sends no host.

- auth: an account — Authorization: Bearer 3pmu_<token>, or the dashboard's session cookie
- node: also open to a node's own bearer (3pma_…) when its row is granted fleet:read; that node's bucket only, and for the calls it placed itself
- answer: NodeHostView (JSON)

## Types

```ts
/**
 * `GET /api/buckets/{id}/nodes/{node}/host`: the host now — rebuilt from
 * the node's state, whole and current (the feed's `telemetry` blanks
 * the identity on a tick).
 */
interface NodeHostView {
  node_id: NodeId;
  /** The node's last frame, as the feed numbers them (`Telemetry.seq`). */
  seq: number;
  /** The agent's clock on the frame that last moved the host. */
  ts: EpochMs;
  /** Always `patched`: the host is rebuilt from the node's state, whole and current. The field stays for the pages that read it; `full`, `merged` and `tick` went with the streams that produced them. */
  identity: "patched";
  host: HostMetrics;
}

/** `3pmn_…` — a node. */
type NodeId = string;

/** Milliseconds since the Unix epoch. */
type EpochMs = number;

/**
 * Host gauges and counters. Wide and platform-dependent — see
 * `HostMetrics` in `threepm-protocol`; the fields below are the ones
 * every platform fills.
 */
interface HostMetrics {
  hostname: string;
  os_name: string;
  os_version: string;
  kernel_version: string;
  arch: string;
  uptime_s: number;
  cpu_brand: string;
  logical_cpus: number;
  global_cpu_percent: number;
  per_core_percent: number[];
  load_avg: [number, number, number];
  mem_total: number;
  mem_used: number;
  mem_available: number;
  swap_total: number;
  swap_used: number;
  processes_count: number;
  /** 3pm's own footprint, measured by the host agent; absent from an older daemon. */
  "3pmDaemon"?: ThreepmDaemon;
  /** The heaviest processes of the host, managed by 3pm or not: the ten largest by CPU, by memory and by network rate, merged and sorted by pid — sort by the column you want and take your own top. Live only (no series is kept). Absent from a daemon with the option off, or predating the table. */
  top_processes?: HostTopProcess[];
  [field: string]: unknown;
}

/** What 3pm itself costs the node (`HostMetrics.3pmDaemon`). */
interface ThreepmDaemon {
  /** When the agent assembled this part, Unix ms. */
  at_epoch_ms?: number;
  /** One row per 3pm process: the daemon, then the host agent. */
  processes: ThreepmProcess[];
  /** The daemon's counters; absent for a tick the daemon did not answer. */
  runtime?: ThreepmRuntime;
}

/** One row of `HostMetrics.top_processes`. */
interface HostTopProcess {
  pid: number;
  /** The executable's name: never its path, never its arguments. */
  name: string;
  /** The account it runs as; absent when the platform does not say. */
  user?: string;
  /** Share of one core over the last window: 100 is one core busy. */
  cpu_percent: number;
  /** Resident set; shared pages are counted in every process holding them. */
  mem_bytes: number;
  /** Physical footprint (macOS): what Activity Monitor calls Memory, with the compressed pages and graphics memory the RSS misses. Never on Linux; absent on macOS for a process the source did not list. When a table has it, its memory top was ranked on it, not on `mem_bytes`. */
  footprint_bytes?: number;
  /** Bytes per second over the last window. Absent, not zero, when the node has no per-process source or the source cannot see this process. */
  net_rx_bytes_per_s?: number;
  net_tx_bytes_per_s?: number;
}

/** One 3pm process as its host agent sees it from the OS. */
interface ThreepmProcess {
  /** `daemon` or `host-agent` (the set may grow). */
  role: string;
  pid: number;
  cpu_percent: number;
  mem_bytes: number;
  uptime_ms?: number;
  /** Linux only for the daemon row on the OS side; filled from the daemon elsewhere. */
  open_fds?: number;
  /** Linux only. */
  threads?: number;
}

/** The daemon's runtime counters, the health subset of `3pm internals`. */
interface ThreepmRuntime {
  version: string;
  boot_id: number;
  uptime_ms: number;
  apps_total: number;
  online: number;
  launching: number;
  stopping: number;
  stopped: number;
  waiting_restart: number;
  errored: number;
  restarts_total: number;
  unstable_restarts_total: number;
  timers_armed: number;
  bus_subscribers: number;
  log_sinks: number;
  log_rotations_total: number;
  log_bytes_written_total: number;
  daemon_log_bytes: number;
  nofile_soft: number;
  nofile_hard: number;
  handoffs: number;
  host_agent_restarts: number;
}
```
