# commands (/docs/reference/api/commands)

> One-shot actions on one node, queued as durable rows in the node's command queue and delivered in order over its session. Every method is decided on `compute-node/{nodeId}`: `run` and `cancel` with `compute:nodes:exec`, `get` and `list` with `compute:nodes:read`. See [Commands](/docs/guides/nodes/commands).



One-shot actions on one node, queued as durable rows in the node's command queue and delivered in order over its session. Every method is decided on `compute-node/{nodeId}`: `run` and `cancel` with `compute:nodes:exec`, `get` and `list` with `compute:nodes:read`. See [Commands](/docs/guides/nodes/commands).

All 4 methods are served by this release.

| Method              | Kind     | Authorization                         | Phase | Status     |
| ------------------- | -------- | ------------------------------------- | ----- | ---------- |
| [`run`](#run)       | mutation | `compute:nodes:exec` @ `compute-node` | v0.1  | registered |
| [`get`](#get)       | read     | `compute:nodes:read` @ `compute-node` | v0.1  | registered |
| [`list`](#list)     | read     | `compute:nodes:read` @ `compute-node` | v0.1  | registered |
| [`cancel`](#cancel) | mutation | `compute:nodes:exec` @ `compute-node` | v0.2  | registered |

## run [#run]

`POST /api/compute/commands/run`

Queues a command of an allowlisted kind (`diag.nvml`, `inventory.refresh`, `logs.collect`, `node.reboot`) on a node the tenant can see; returns the command, `pending` when first queued.

* Idempotent per tenant, caller identity and `idempotencyKey`: a retry with the same key returns the command already queued. The same key with a different `kind` is `CONFLICT`.

* `notAfterSeconds` (10 to 3600, default 600) sets how long the command may wait for the node before it expires.

* Any other kind is `UNSUPPORTED`; a payload that does not match the kind's schema is `INVALID_INPUT`; a node outside the tenant's view is `NOT_FOUND`.

* For `logs.collect`, when the server has `supportBundles` with a presigning blob store, the daemon receives a presigned upload URL and the response carries the bundle's `bundleKey`.

* Emits `node.command.queued` when the command is first queued, not on a replay.

* **Kind:** mutation

* **Authorization:** `compute:nodes:exec` @ `compute-node`

* **Module:** `server`

* **Phase:** v0.1 (registered)

**Input**

| Field             | Type    | Required | Constraints                                                              |
| ----------------- | ------- | -------- | ------------------------------------------------------------------------ |
| `tenantId`        | string  | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`               |
| `nodeId`          | string  | yes      | at most 64 characters; matches `^node_[0-9a-hjkmnp-tv-z]{26,52}$`        |
| `kind`            | string  | yes      | at most 64 characters; matches `^[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)+$` |
| `payload`         | object  |          |                                                                          |
| `idempotencyKey`  | string  | yes      | at most 128 characters; matches `^[A-Za-z0-9._~:/+=-]{1,128}$`           |
| `notAfterSeconds` | integer |          | 10-3600; default `600`                                                   |
| `batchId`         | string  |          | at most 64 characters; matches `^batch_[0-9a-z]{26,52}$`                 |

## get [#get]

`POST /api/compute/commands/get`

Returns one command of a node by id, with its state, deadlines and safety flags.

`NOT_FOUND` when the command is not on that node or the node is outside the tenant's view.

* **Kind:** read
* **Authorization:** `compute:nodes:read` @ `compute-node`
* **Module:** `server`
* **Phase:** v0.1 (registered)

**Input**

| Field       | Type   | Required | Constraints                                                       |
| ----------- | ------ | -------- | ----------------------------------------------------------------- |
| `tenantId`  | string | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`        |
| `nodeId`    | string | yes      | at most 64 characters; matches `^node_[0-9a-hjkmnp-tv-z]{26,52}$` |
| `commandId` | string | yes      | at most 64 characters; matches `^cmd_[0-9a-hjkmnp-tv-z]{26,52}$`  |

## list [#list]

`POST /api/compute/commands/list`

Lists a node's commands newest first (by queue sequence), optionally filtered by `state`; returns a page with a cursor.

`limit` is at most 200 (100 by default). The cursor is the sequence of the last command returned.

* **Kind:** read
* **Authorization:** `compute:nodes:read` @ `compute-node`
* **Module:** `server`
* **Phase:** v0.1 (registered)

**Input**

| Field      | Type                                                                                                          | Required | Constraints                                                       |
| ---------- | ------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------- |
| `tenantId` | string                                                                                                        | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`        |
| `nodeId`   | string                                                                                                        | yes      | at most 64 characters; matches `^node_[0-9a-hjkmnp-tv-z]{26,52}$` |
| `state`    | one of `pending`, `dispatched`, `acked`, `running`, `succeeded`, `failed`, `rejected`, `expired`, `cancelled` |          |                                                                   |
| `limit`    | integer                                                                                                       |          | 1-200; default `100`                                              |
| `cursor`   | string                                                                                                        |          | at most 19 characters; matches `^\d{1,19}$`                       |

## cancel [#cancel]

`POST /api/compute/commands/cancel`

Cancels a command: a `pending` one becomes `cancelled` and never runs, an in-flight one (`dispatched`, `acked`, `running`) is asked to stop through its gateway; returns the command as it stands after the request.

* A command already in a terminal state (`succeeded`, `failed`, `rejected`, `expired`, `cancelled`) is returned unchanged and no event is emitted.

* An in-flight command keeps its state until the node reports; the request is recorded on the row.

* Emits `node.command.cancel-requested`. `NOT_FOUND` when the command is not on that node or the node is outside the tenant's view.

* **Kind:** mutation

* **Authorization:** `compute:nodes:exec` @ `compute-node`

* **Module:** `server`

* **Phase:** v0.2 (registered)

**Input**

| Field       | Type   | Required | Constraints                                                       |
| ----------- | ------ | -------- | ----------------------------------------------------------------- |
| `tenantId`  | string | yes      | at most 128 characters; matches `^[A-Za-z0-9._:-]{1,128}$`        |
| `nodeId`    | string | yes      | at most 64 characters; matches `^node_[0-9a-hjkmnp-tv-z]{26,52}$` |
| `commandId` | string | yes      | at most 64 characters; matches `^cmd_[0-9a-hjkmnp-tv-z]{26,52}$`  |
