# 3pm-backend route `nodeActions`

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: 763
  o200k: 456
# GET /api/buckets/{clusterId}/nodes/{nodeId}/actions (nodeActions)

The custom actions the apps of the node declare (`io.action`), per instance and source, with descriptions and timeouts — what `nodeAction` may run; none of the metrics, so a page may poll it all the time.

- 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: NodeActionsView (JSON)

## Types

```ts
/** `GET /api/buckets/{id}/nodes/{node}/actions`: the actions the node's apps declare, nothing of their metrics. */
interface NodeActionsView {
  node_id: NodeId;
  /** Every instance with at least one action, in the hub's order. */
  instances: ActionInstanceView[];
}

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

/** One instance of `NodeActionsView`: its identity and the sources that declare an action (a source without one is left out). */
interface ActionInstanceView {
  /** The daemon's process id. */
  id: number;
  /** Incarnation: a restart starts a new one. */
  gen: number;
  name: string;
  instance: number;
  ns?: string;
  sources: AppSourceView[];
}

interface AppSourceView {
  source: string;
  pid?: number;
  /** The actions this source exposes to the backend (`nodeAction`); absent when none. */
  actions?: AppActionView[];
}

interface AppActionView {
  name: string;
  description?: string;
  /** The declared timeout, ms (30 s when absent). */
  timeout_ms?: number;
  /** The declared `output.max_bytes`: what a call asking for the file reserves of its caller's blob quota (256 MiB when absent). */
  output_max_bytes?: number;
}
```
