# inventory (/docs/reference/api/inventory)

> A node's hardware and software inventory as the daemon reports it, kept as an append-only history of snapshots: a new snapshot is stored each time the node's reported section set changes. Every method decides `compute:nodes:read` on `compute-node/{nodeId}` and only answers for nodes the calling tenant owns. See [Inventory and health](/docs/guides/nodes/inventory-and-health).



A node's hardware and software inventory as the daemon reports it, kept as an append-only history of snapshots: a new snapshot is stored each time the node's reported section set changes. Every method decides `compute:nodes:read` on `compute-node/{nodeId}` and only answers for nodes the calling tenant owns. See [Inventory and health](/docs/guides/nodes/inventory-and-health).

All 3 methods are served by this release.

| Method                | Kind | Authorization                         | Phase | Status     |
| --------------------- | ---- | ------------------------------------- | ----- | ---------- |
| [`get`](#get)         | read | `compute:nodes:read` @ `compute-node` | v0.1  | registered |
| [`history`](#history) | read | `compute:nodes:read` @ `compute-node` | v0.2  | registered |
| [`diff`](#diff)       | read | `compute:nodes:read` @ `compute-node` | v0.2  | registered |

## get [#get]

`POST /api/compute/inventory/get`

Returns the node's latest inventory snapshot: its hash, its sections and when it was collected.

`NOT_FOUND` when the node has no inventory yet or is not owned by the tenant.

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

**Input**

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

## history [#history]

`POST /api/compute/inventory/history`

Lists the node's inventory snapshots newest first; returns a page with a cursor.

`limit` is at most 100 (20 by default). The cursor is the id of the last snapshot returned. `NOT_FOUND` when the node is not owned by the tenant.

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

**Input**

| Field      | Type    | Required | Constraints                                |
| ---------- | ------- | -------- | ------------------------------------------ |
| `tenantId` | string  | yes      | matches `^[A-Za-z0-9._:-]{1,128}$`         |
| `nodeId`   | string  | yes      | matches `^node_[0-9a-hjkmnp-tv-z]{26,52}$` |
| `limit`    | integer |          | 1-100                                      |
| `cursor`   | string  |          | matches `^inv_[0-9a-hjkmnp-tv-z]{26,52}$`  |

## diff [#diff]

`POST /api/compute/inventory/diff`

Compares two of the node's snapshots, named by snapshot id or hash, and returns the changes between them with their stable device ids (GPU UUID, disk WWN or MAC).

* Without `to`, the latest snapshot is used; without `from`, the snapshot before `to`. A node with a single snapshot diffs against nothing: `from` is empty and there are no changes.

* Change types are `gpu.missing`, `gpu.added`, `disk.replaced`, `driver.changed` and `mig.layout.changed`, each with `before` and `after` values where they apply.

* `NOT_FOUND` when the node has no inventory, a named snapshot does not exist for the node, or the node is not owned by the tenant.

* **Kind:** read

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

* **Module:** `inventory`

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

**Input**

| Field      | Type   | Required | Constraints                                               |
| ---------- | ------ | -------- | --------------------------------------------------------- |
| `tenantId` | string | yes      | matches `^[A-Za-z0-9._:-]{1,128}$`                        |
| `nodeId`   | string | yes      | matches `^node_[0-9a-hjkmnp-tv-z]{26,52}$`                |
| `from`     | string |          | matches `^(inv_[0-9a-hjkmnp-tv-z]{26,52}\|[0-9a-f]{64})$` |
| `to`       | string |          | matches `^(inv_[0-9a-hjkmnp-tv-z]{26,52}\|[0-9a-f]{64})$` |
