# Updates

<a id="get-api-v1-system-packages-summary"></a>
#### `GET /api/v1/system/packages/summary`

*OS package summary (counts only)*

Cheap cached summary (no apt subprocess). Used by the topbar update badge.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_OsPackagesSummary_` | Successful Response |

**Response example (200):**

```json
{
  "data": {
    "last_checked": "...",
    "reboot_required": false,
    "security_count": 0,
    "total": 0,
    "updates": [
      "..."
    ]
  },
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/packages/summary
```

---

<a id="get-api-v1-system-packages-updates"></a>
#### `GET /api/v1/system/packages/updates`

*List available OS package updates*

Returns the apt/dnf update list (live or cached when an apply is in flight). Each entry: name, current_version, candidate_version, security flag.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_list_OsPackageUpdate__` | Successful Response |

**Response example (200):**

```json
{
  "data": [
    {
      "category": "...",
      "current_version": "...",
      "name": "...",
      "new_version": "..."
    }
  ],
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/packages/updates
```

---

<a id="post-api-v1-system-packages-upgrade"></a>
#### `POST /api/v1/system/packages/upgrade`

*Trigger OS package upgrade*

Schedules an apt/dnf upgrade as a background job. Returns the initial status immediately — poll `/upgrade/status` for progress. Already-running jobs are surfaced without restart.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `package_names` | array<string> | no | Package names to upgrade. Each must match [a-z0-9][a-z0-9.+\-]* |
| `security_only` | boolean | no | default `True` |

**Request body example:**

```json
{
  "package_names": [
    "string"
  ],
  "security_only": true
}
```

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_OsPackageApplyStatus_` | Successful Response |
| `422` | `HTTPValidationError` | Validation Error |

**Response example (200):**

```json
{
  "data": {
    "completed_at": "...",
    "error": "...",
    "message": "...",
    "output_tail": "",
    "progress": 0,
    "security_only": false,
    "stage": "idle",
    "started_at": "...",
    "target_packages": [
      "..."
    ],
    "upgraded": [
      "..."
    ]
  },
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X POST \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/packages/upgrade
```

---

<a id="get-api-v1-system-packages-upgrade-history"></a>
#### `GET /api/v1/system/packages/upgrade/history`

*OS upgrade history*

Last N OS package upgrade attempts (`limit` 1–100, default 20; the file keeps at most 100).

**Query parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `limit` | integer | no | minimum=1; maximum=100 |

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_list_OsPackageApplyHistoryEntry__` | Successful Response |
| `422` | `HTTPValidationError` | Validation Error |

**Response example (200):**

```json
{
  "data": [
    {
      "completed_at": "...",
      "error_message": "...",
      "id": "...",
      "security_only": "...",
      "started_at": "...",
      "status": "...",
      "target_packages": "...",
      "upgraded": "..."
    }
  ],
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/packages/upgrade/history
```

---

<a id="get-api-v1-system-packages-upgrade-status"></a>
#### `GET /api/v1/system/packages/upgrade/status`

*Get OS upgrade job status*

Poll-friendly endpoint. Survives page navigation — the job runs server-side even if the client disconnects.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_OsPackageApplyStatus_` | Successful Response |

**Response example (200):**

```json
{
  "data": {
    "completed_at": "...",
    "error": "...",
    "message": "...",
    "output_tail": "",
    "progress": 0,
    "security_only": false,
    "stage": "idle",
    "started_at": "...",
    "target_packages": [
      "..."
    ],
    "upgraded": [
      "..."
    ]
  },
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/packages/upgrade/status
```

---

<a id="get-api-v1-system-update-changelog"></a>
#### `GET /api/v1/system/update/changelog`

*Get cached changelog*

Returns the changelog the last update check answered — the same text `/check` returns in its `changelog` field. Null before any check and for a host already on the latest version (the vendor sends no changelog then); a `message` accompanies the former. Response data: `{changelog}`.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_dict_str__Any__` | Successful Response |

**Response example (200):**

```json
{
  "data": {},
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/update/changelog
```

---

<a id="get-api-v1-system-update-check"></a>
#### `GET /api/v1/system/update/check`

*Check for WHost agent updates*

Check whether a newer WHost agent release is available and return the changelog. Result is cached server-side until the next check.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_UpdateCheckResult_` | Successful Response |

**Response example (200):**

```json
{
  "data": {
    "beta_denied": false,
    "changelog": "...",
    "channel": "string",
    "current_version": "string",
    "error": "...",
    "is_mandatory": false,
    "last_checked": "...",
    "latest_version": "string",
    "min_version": "...",
    "requires_restart": true,
    "size_bytes": "...",
    "update_available": false
  },
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/update/check
```

---

<a id="get-api-v1-system-update-history"></a>
#### `GET /api/v1/system/update/history`

*List past update operations*

Returns every update install attempt (newest first), including stage outcome + duration.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_list_UpdateHistoryEntry__` | Successful Response |

**Response example (200):**

```json
{
  "data": [
    {
      "backup_path": "...",
      "completed_at": "...",
      "error_message": "...",
      "from_version": "...",
      "id": "...",
      "recipes_delivered": "...",
      "started_at": "...",
      "status": "...",
      "to_version": "...",
      "type": "..."
    }
  ],
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/update/history
```

---

<a id="post-api-v1-system-update-install"></a>
#### `POST /api/v1/system/update/install`

*Trigger WHost update install*

Starts the install pipeline in the background. Returns immediately (`{started: true}`); poll `/status` or open `/status/stream` (SSE) to follow progress. Refused 409 `UPDATE_IN_PROGRESS` while a run is going, 409 `BACKUP_IN_PROGRESS` while a backup, a restore or a scheduled backup runs in the agent (the run ends in a restart that would cut it; the message names the work and when it started), 400 `UPDATE_CHECK_REQUIRED` before any `/check` has run in this agent process, 400 `UPDATE_ALREADY_LATEST` when the last check found no newer version, 400 `UPDATE_DOWNGRADE_REJECTED` when the offered release orders before the installed one, 400 `UPDATE_INVALID_VERSION` when the offered version is not a version. All six are answered before anything starts; backup work that starts between this answer and the run's first step ends the run as `failed` with the same message.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_dict_str__Any__` | Successful Response |

**Response example (200):**

```json
{
  "data": {},
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X POST \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/update/install
```

---

<a id="get-api-v1-system-update-settings"></a>
#### `GET /api/v1/system/update/settings`

*Get update settings*

Auto-update channel, backup-before-update flag, notify toggles, OS package update prefs.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_UpdateSettings_` | Successful Response |

**Response example (200):**

```json
{
  "data": {
    "allow_vendor_critical_override": true,
    "auto_update": true,
    "auto_update_type": "security",
    "backup_before_update": true,
    "channel": "stable",
    "notify_available": true,
    "notify_installed": true,
    "os_packages_check_enabled": true,
    "os_packages_notify_security": true
  },
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/update/settings
```

---

<a id="put-api-v1-system-update-settings"></a>
#### `PUT /api/v1/system/update/settings`

*Update settings*

Patch any subset of update preferences. Only fields present in the body are mutated; a switch must be a JSON boolean and an unknown field is refused 422. A save that changes nothing writes neither the file nor an audit row; the audit row of a real change names only the fields whose value changed.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `allow_vendor_critical_override` | boolean | no | — |
| `auto_update` | boolean | no | — |
| `auto_update_type` | string | no | — |
| `backup_before_update` | boolean | no | — |
| `channel` | string | no | — |
| `notify_available` | boolean | no | — |
| `notify_installed` | boolean | no | — |
| `os_packages_check_enabled` | boolean | no | — |
| `os_packages_notify_security` | boolean | no | — |

**Request body example:**

```json
{
  "allow_vendor_critical_override": false,
  "auto_update": false,
  "auto_update_type": "all",
  "backup_before_update": false,
  "channel": "stable",
  "notify_available": false,
  "notify_installed": false,
  "os_packages_check_enabled": false,
  "os_packages_notify_security": false
}
```

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_UpdateSettings_` | Successful Response |
| `422` | `HTTPValidationError` | Validation Error |

**Response example (200):**

```json
{
  "data": {
    "allow_vendor_critical_override": true,
    "auto_update": true,
    "auto_update_type": "security",
    "backup_before_update": true,
    "channel": "stable",
    "notify_available": true,
    "notify_installed": true,
    "os_packages_check_enabled": true,
    "os_packages_notify_security": true
  },
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X PUT \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/update/settings
```

---

<a id="get-api-v1-system-update-status"></a>
#### `GET /api/v1/system/update/status`

*Get update install status*

Snapshot of the install pipeline — stage, progress 0-100, message, started_at, completed_at, error.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_UpdateStatus_` | Successful Response |

**Response example (200):**

```json
{
  "data": {
    "channel": "stable",
    "completed_at": "...",
    "current_version": "string",
    "error": "...",
    "last_checked": "...",
    "latest_version": "...",
    "message": "...",
    "progress": 0,
    "stage": "idle",
    "started_at": "...",
    "update_available": false
  },
  "message": "",
  "status": "success",
  "warnings": [
    "string"
  ]
}
```

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/update/status
```

---

<a id="get-api-v1-system-update-status-stream"></a>
#### `GET /api/v1/system/update/status/stream`

*SSE — install progress stream*

Server-Sent Events feed of install progress. Closes when stage reaches `completed`, `failed` or `rolled_back`. Binary `text/event-stream` — no JSON envelope.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | — | Successful Response |

**cURL example:**

```bash
curl -X GET \
  -H "X-WHost-Key: $WHOST_API_KEY" \
  -H "X-WHost-Timestamp: $(date +%s)" \
  -H "X-WHost-Nonce: $(openssl rand -hex 16)" \
  -H "X-WHost-Signature: $(compute_hmac)" \
  https://your-server:2000/api/v1/system/update/status/stream
```

---
