# System & Services

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

*Apache mod_status snapshot*

Returns the parsed `/server-status?auto` output (workers, requests/sec, ScoreBoard). Only when Apache is running.

**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/apache-status
```

---

<a id="post-api-v1-system-apache-status-enable"></a>
#### `POST /api/v1/system/apache-status/enable`

*Enable Apache mod_status*

Provisions the `mod_status` module + the `/server-status` endpoint scoped to localhost.

**Responses:**

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

**Response example (200):**

```json
{
  "message": "string",
  "status": "success"
}
```

**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/apache-status/enable
```

---

<a id="post-api-v1-system-backups-bunny-storage-zones"></a>
#### `POST /api/v1/system/backups/bunny-storage/zones`

*List Bunny.net storage zones*

Helper for the create-destination wizard — requires an account API key in the body.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `account_api_key` | string | yes | — |

**Request body example:**

```json
{
  "account_api_key": "string"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/bunny-storage/zones
```

---

<a id="post-api-v1-system-backups-google-drive-auth-url"></a>
#### `POST /api/v1/system/backups/google-drive/auth-url`

*Google Drive — get OAuth URL*

Step 1 of OAuth: returns the consent URL the user should open in a browser.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `client_id` | string | yes | — |
| `client_secret` | string | yes | — |
| `redirect_uri` | string | yes | — |

**Request body example:**

```json
{
  "client_id": "string",
  "client_secret": "string",
  "redirect_uri": "string"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/google-drive/auth-url
```

---

<a id="get-api-v1-system-backups-google-drive-callback"></a>
#### `GET /api/v1/system/backups/google-drive/callback`

*Google Drive Callback*

OAuth2 callback — renders a small HTML page that sends the code back to the opener window via postMessage.

**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/backups/google-drive/callback
```

---

<a id="post-api-v1-system-backups-google-drive-exchange"></a>
#### `POST /api/v1/system/backups/google-drive/exchange`

*Google Drive — exchange OAuth code*

Step 3 of OAuth: trades the authorization code for an access + refresh token pair.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `client_id` | string | yes | — |
| `client_secret` | string | yes | — |
| `code` | string | yes | — |
| `redirect_uri` | string | yes | — |
| `state` | string | no | default `` |

**Request body example:**

```json
{
  "client_id": "string",
  "client_secret": "string",
  "code": "string",
  "redirect_uri": "string",
  "state": ""
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/google-drive/exchange
```

---

<a id="post-api-v1-system-backups-onedrive-auth-url"></a>
#### `POST /api/v1/system/backups/onedrive/auth-url`

*OneDrive — get OAuth URL*

Step 1 of OAuth for Microsoft OneDrive.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `client_id` | string | yes | — |
| `client_secret` | string | yes | — |
| `redirect_uri` | string | yes | — |

**Request body example:**

```json
{
  "client_id": "string",
  "client_secret": "string",
  "redirect_uri": "string"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/onedrive/auth-url
```

---

<a id="get-api-v1-system-backups-onedrive-callback"></a>
#### `GET /api/v1/system/backups/onedrive/callback`

*Onedrive Callback*

OneDrive OAuth2 redirect landing page — posts message to opener.

**Query parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `code` | string | no | — |
| `state` | string | no | — |
| `error` | string | no | — |
| `error_description` | string | no | — |

**Responses:**

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

**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/backups/onedrive/callback
```

---

<a id="post-api-v1-system-backups-onedrive-exchange"></a>
#### `POST /api/v1/system/backups/onedrive/exchange`

*OneDrive — exchange OAuth code*

Step 3 of OAuth for Microsoft OneDrive.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `client_id` | string | yes | — |
| `client_secret` | string | yes | — |
| `code` | string | yes | — |
| `redirect_uri` | string | yes | — |
| `state` | string | no | default `` |

**Request body example:**

```json
{
  "client_id": "string",
  "client_secret": "string",
  "code": "string",
  "redirect_uri": "string",
  "state": ""
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/onedrive/exchange
```

---

<a id="get-api-v1-system-backups-remote-destinations"></a>
#### `GET /api/v1/system/backups/remote-destinations`

*List remote backup destinations*

Server-wide destinations (FTP / SFTP / Google Drive / Bunny Storage / Yandex Disk / OneDrive) available for off-host copies; secrets are masked.

**Responses:**

| Status | Schema | Description |
|--------|--------|-------------|
| `200` | `ApiSuccess_list_` | 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/backups/remote-destinations
```

---

<a id="post-api-v1-system-backups-remote-destinations"></a>
#### `POST /api/v1/system/backups/remote-destinations`

*Add remote backup destination*

Register a new cloud target. For OAuth-based providers complete `/auth-url` → `/exchange` first and pass the returned tokens here.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `api_key` | string | no | — |
| `base_path` | string | no | — |
| `credentials_file` | string | no | — |
| `credentials_json` | string | no | — |
| `dest_id` | string | no | — |
| `folder_id` | string | no | — |
| `google_client_id` | string | no | — |
| `google_client_secret` | string | no | — |
| `google_email` | string | no | — |
| `google_refresh_token` | string | no | — |
| `host` | string | no | — |
| `name` | string | yes | minLength=1; maxLength=100 |
| `oauth_token` | string | no | — |
| `onedrive_client_id` | string | no | — |
| `onedrive_client_secret` | string | no | — |
| `onedrive_email` | string | no | — |
| `onedrive_folder_path` | string | no | — |
| `onedrive_refresh_token` | string | no | — |
| `password` | string | no | — |
| `port` | integer | no | — |
| `region` | string | no | — |
| `remote_dir` | string | no | — |
| `reset_server_identity` | boolean | no | — |
| `storage_zone` | string | no | — |
| `tls_accept_unverified` | boolean | no | — |
| `type` | string | yes | enum: `ftp`, `sftp`, `google_drive`, `bunny_storage`, `yandex_disk`, `onedrive` |
| `use_sftp` | boolean | no | — |
| `username` | string | no | — |
| `validated` | boolean | no | — |
| `yandex_client_id` | string | no | — |
| `yandex_client_secret` | string | no | — |
| `yandex_login` | string | no | — |
| `yandex_refresh_token` | string | no | — |

**Request body example:**

```json
{
  "api_key": "string",
  "base_path": "string",
  "credentials_file": "string",
  "credentials_json": "string",
  "dest_id": "string",
  "folder_id": "string",
  "google_client_id": "string",
  "google_client_secret": "string",
  "google_email": "string",
  "google_refresh_token": "string",
  "host": "string",
  "name": "string",
  "oauth_token": "string",
  "onedrive_client_id": "string",
  "onedrive_client_secret": "string",
  "onedrive_email": "string",
  "onedrive_folder_path": "string",
  "onedrive_refresh_token": "string",
  "password": "string",
  "port": 1.0,
  "region": "string",
  "remote_dir": "string",
  "reset_server_identity": false,
  "storage_zone": "string",
  "tls_accept_unverified": false,
  "type": "ftp",
  "use_sftp": false,
  "username": "string",
  "validated": false,
  "yandex_client_id": "string",
  "yandex_client_secret": "string",
  "yandex_login": "string",
  "yandex_refresh_token": "string"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/remote-destinations
```

---

<a id="post-api-v1-system-backups-remote-destinations-test"></a>
#### `POST /api/v1/system/backups/remote-destinations/test`

*Test ad-hoc remote destination credentials*

Validate a destination definition **before** saving — body carries the same payload as the POST create call.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `api_key` | string | no | — |
| `base_path` | string | no | — |
| `credentials_file` | string | no | — |
| `credentials_json` | string | no | — |
| `dest_id` | string | no | — |
| `folder_id` | string | no | — |
| `google_client_id` | string | no | — |
| `google_client_secret` | string | no | — |
| `google_email` | string | no | — |
| `google_refresh_token` | string | no | — |
| `host` | string | no | — |
| `name` | string | yes | minLength=1; maxLength=100 |
| `oauth_token` | string | no | — |
| `onedrive_client_id` | string | no | — |
| `onedrive_client_secret` | string | no | — |
| `onedrive_email` | string | no | — |
| `onedrive_folder_path` | string | no | — |
| `onedrive_refresh_token` | string | no | — |
| `password` | string | no | — |
| `port` | integer | no | — |
| `region` | string | no | — |
| `remote_dir` | string | no | — |
| `reset_server_identity` | boolean | no | — |
| `storage_zone` | string | no | — |
| `tls_accept_unverified` | boolean | no | — |
| `type` | string | yes | enum: `ftp`, `sftp`, `google_drive`, `bunny_storage`, `yandex_disk`, `onedrive` |
| `use_sftp` | boolean | no | — |
| `username` | string | no | — |
| `validated` | boolean | no | — |
| `yandex_client_id` | string | no | — |
| `yandex_client_secret` | string | no | — |
| `yandex_login` | string | no | — |
| `yandex_refresh_token` | string | no | — |

**Request body example:**

```json
{
  "api_key": "string",
  "base_path": "string",
  "credentials_file": "string",
  "credentials_json": "string",
  "dest_id": "string",
  "folder_id": "string",
  "google_client_id": "string",
  "google_client_secret": "string",
  "google_email": "string",
  "google_refresh_token": "string",
  "host": "string",
  "name": "string",
  "oauth_token": "string",
  "onedrive_client_id": "string",
  "onedrive_client_secret": "string",
  "onedrive_email": "string",
  "onedrive_folder_path": "string",
  "onedrive_refresh_token": "string",
  "password": "string",
  "port": 1.0,
  "region": "string",
  "remote_dir": "string",
  "reset_server_identity": false,
  "storage_zone": "string",
  "tls_accept_unverified": false,
  "type": "ftp",
  "use_sftp": false,
  "username": "string",
  "validated": false,
  "yandex_client_id": "string",
  "yandex_client_secret": "string",
  "yandex_login": "string",
  "yandex_refresh_token": "string"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/remote-destinations/test
```

---

<a id="delete-api-v1-system-backups-remote-destinations-dest-id"></a>
#### `DELETE /api/v1/system/backups/remote-destinations/{dest_id}`

*Delete remote backup destination*

Removes the destination definition. Already-uploaded tarballs at the cloud target are left untouched.

**Path parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `dest_id` | string | yes | — |

**Responses:**

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

**Response example (200):**

```json
{
  "message": "string",
  "status": "success"
}
```

**cURL example:**

```bash
curl -X DELETE \
  -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/backups/remote-destinations/{dest_id}
```

---

<a id="put-api-v1-system-backups-remote-destinations-dest-id"></a>
#### `PUT /api/v1/system/backups/remote-destinations/{dest_id}`

*Update remote backup destination*

Patch credentials / endpoint / path of an existing destination.

**Path parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `dest_id` | string | yes | — |

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `api_key` | string | no | — |
| `base_path` | string | no | — |
| `credentials_file` | string | no | — |
| `credentials_json` | string | no | — |
| `dest_id` | string | no | — |
| `folder_id` | string | no | — |
| `google_client_id` | string | no | — |
| `google_client_secret` | string | no | — |
| `google_email` | string | no | — |
| `google_refresh_token` | string | no | — |
| `host` | string | no | — |
| `name` | string | yes | minLength=1; maxLength=100 |
| `oauth_token` | string | no | — |
| `onedrive_client_id` | string | no | — |
| `onedrive_client_secret` | string | no | — |
| `onedrive_email` | string | no | — |
| `onedrive_folder_path` | string | no | — |
| `onedrive_refresh_token` | string | no | — |
| `password` | string | no | — |
| `port` | integer | no | — |
| `region` | string | no | — |
| `remote_dir` | string | no | — |
| `reset_server_identity` | boolean | no | — |
| `storage_zone` | string | no | — |
| `tls_accept_unverified` | boolean | no | — |
| `type` | string | yes | enum: `ftp`, `sftp`, `google_drive`, `bunny_storage`, `yandex_disk`, `onedrive` |
| `use_sftp` | boolean | no | — |
| `username` | string | no | — |
| `validated` | boolean | no | — |
| `yandex_client_id` | string | no | — |
| `yandex_client_secret` | string | no | — |
| `yandex_login` | string | no | — |
| `yandex_refresh_token` | string | no | — |

**Request body example:**

```json
{
  "api_key": "string",
  "base_path": "string",
  "credentials_file": "string",
  "credentials_json": "string",
  "dest_id": "string",
  "folder_id": "string",
  "google_client_id": "string",
  "google_client_secret": "string",
  "google_email": "string",
  "google_refresh_token": "string",
  "host": "string",
  "name": "string",
  "oauth_token": "string",
  "onedrive_client_id": "string",
  "onedrive_client_secret": "string",
  "onedrive_email": "string",
  "onedrive_folder_path": "string",
  "onedrive_refresh_token": "string",
  "password": "string",
  "port": 1.0,
  "region": "string",
  "remote_dir": "string",
  "reset_server_identity": false,
  "storage_zone": "string",
  "tls_accept_unverified": false,
  "type": "ftp",
  "use_sftp": false,
  "username": "string",
  "validated": false,
  "yandex_client_id": "string",
  "yandex_client_secret": "string",
  "yandex_login": "string",
  "yandex_refresh_token": "string"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {},
  "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/backups/remote-destinations/{dest_id}
```

---

<a id="post-api-v1-system-backups-remote-destinations-dest-id-test"></a>
#### `POST /api/v1/system/backups/remote-destinations/{dest_id}/test`

*Test stored remote destination credentials*

Live connectivity probe against a saved destination: a login and directory check for FTP/SFTP, the provider's account call for the cloud providers; nothing is uploaded. A passing test marks the destination validated.

**Path parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `dest_id` | string | yes | — |

**Responses:**

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

**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/backups/remote-destinations/{dest_id}/test
```

---

<a id="patch-api-v1-system-backups-remote-destinations-dest-id-toggle"></a>
#### `PATCH /api/v1/system/backups/remote-destinations/{dest_id}/toggle`

*Toggle remote destination enabled flag*

Disable a destination without removing it. A disabled destination is refused as a copy target: a manual backup naming it is refused (409); a scheduled one keeps its local archive and records why the copy was not made.

**Path parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `dest_id` | string | yes | — |

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `enabled` | boolean | no | default `True` |

**Request body example:**

```json
{
  "enabled": true
}
```

**Responses:**

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

**Response example (200):**

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

**cURL example:**

```bash
curl -X PATCH \
  -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/backups/remote-destinations/{dest_id}/toggle
```

---

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

*Get server-wide backup settings*

Default destination, retention, schedule defaults for new accounts.

**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/backups/settings
```

---

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

*Update server-wide backup settings*

Patches default destination, retention policy, schedule defaults.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `enabled` | boolean | no | — |
| `retention_days` | integer | no | — |
| `schedule_enabled` | boolean | no | — |
| `schedule_max_per_account` | integer | no | — |

**Request body example:**

```json
{
  "enabled": false,
  "retention_days": 1.0,
  "schedule_enabled": false,
  "schedule_max_per_account": 1.0
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {},
  "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/backups/settings
```

---

<a id="post-api-v1-system-backups-yandex-disk-auth-url"></a>
#### `POST /api/v1/system/backups/yandex-disk/auth-url`

*Yandex Disk — get OAuth URL*

Step 1 of OAuth for Yandex.Disk.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `client_id` | string | yes | — |
| `client_secret` | string | yes | — |
| `redirect_uri` | string | yes | — |

**Request body example:**

```json
{
  "client_id": "string",
  "client_secret": "string",
  "redirect_uri": "string"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/yandex-disk/auth-url
```

---

<a id="get-api-v1-system-backups-yandex-disk-callback"></a>
#### `GET /api/v1/system/backups/yandex-disk/callback`

*Yandex Disk Callback*

Yandex OAuth2 callback — sends code back to opener via postMessage.

**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/backups/yandex-disk/callback
```

---

<a id="post-api-v1-system-backups-yandex-disk-exchange"></a>
#### `POST /api/v1/system/backups/yandex-disk/exchange`

*Yandex Disk — exchange OAuth code*

Step 3 of OAuth for Yandex.Disk.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `client_id` | string | yes | — |
| `client_secret` | string | yes | — |
| `code` | string | yes | — |
| `state` | string | no | default `` |

**Request body example:**

```json
{
  "client_id": "string",
  "client_secret": "string",
  "code": "string",
  "state": ""
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/backups/yandex-disk/exchange
```

---

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

*Change server hostname*

Updates `/etc/hostname`, sysctl, and re-renders the panel certificate. Reboot recommended for full effect.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `hostname` | string | yes | — |

**Request body example:**

```json
{
  "hostname": "string"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {},
  "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/hostname
```

---

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

*Server info snapshot*

OS, kernel, hostname, IP, uptime, CPU/RAM/disk/bandwidth, top processes, webserver, PHP default.

**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/info
```

---

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

*List server IP addresses*

Returns every IPv4 address bound on the host (IPv6 is not managed here), merged with the stored classification; a stored record the kernel no longer carries is listed with `bound: false`. Response data shape: `{ips: SystemIPResponse[], total: int}`.

**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/ips
```

---

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

*Register a new IP*

Bind a new IPv4 to a host network interface (ip addr add) and make it persistent (netplan on Debian / nmcli on RHEL). Reserved/loopback/link-local/multicast addresses are refused.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `interface` | string | no | — |
| `ip` | string | yes | minLength=7; maxLength=45 |
| `netmask` | string | no | default `255.255.255.0`; maxLength=45 |
| `type` | string | no | default `shared`; enum: `shared`, `dedicated` |

**Request body example:**

```json
{
  "interface": "string",
  "ip": "string",
  "netmask": "255.255.255.0",
  "type": "shared"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {
    "account_count": 0,
    "accounts": [
      "..."
    ],
    "bound": true,
    "cidr": 24,
    "interface": "",
    "ip": "string",
    "is_primary": false,
    "netmask": "",
    "type": "shared"
  },
  "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/ips
```

---

<a id="delete-api-v1-system-ips-ip"></a>
#### `DELETE /api/v1/system/ips/{ip}`

*Unregister IP*

Unbind the IPv4 from its interface (ip addr del) and remove it from persistent config (netplan/nmcli). The primary server IP, the default route's address, the default interface's first address and IPs still assigned to accounts are refused (422); an unknown address answers 404 NOT_FOUND.

**Path parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `ip` | string | yes | — |

**Responses:**

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

**Response example (200):**

```json
{
  "message": "string",
  "status": "success"
}
```

**cURL example:**

```bash
curl -X DELETE \
  -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/ips/{ip}
```

---

<a id="put-api-v1-system-ips-ip"></a>
#### `PUT /api/v1/system/ips/{ip}`

*Update IP metadata*

Change the classification (shared/dedicated) of a registered IP. Metadata only — the OS-level address binding is not altered. An address the host does not carry and the store does not know answers 404 NOT_FOUND.

**Path parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `ip` | string | yes | — |

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `type` | string | yes | enum: `shared`, `dedicated` |

**Request body example:**

```json
{
  "type": "shared"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {
    "account_count": 0,
    "accounts": [
      "..."
    ],
    "bound": true,
    "cidr": 24,
    "interface": "",
    "ip": "string",
    "is_primary": false,
    "netmask": "",
    "type": "shared"
  },
  "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/ips/{ip}
```

---

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

*Install phpMyAdmin*

Provisions the panel-embedded phpMyAdmin (writes vhost, SSO bridge script).

**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/phpmyadmin/install
```

---

<a id="post-api-v1-system-phpmyadmin-sso"></a>
#### `POST /api/v1/system/phpmyadmin/sso`

*Mint phpMyAdmin SSO token*

Internal endpoint — returns the short-lived SSO redirect URL for the panel's phpMyAdmin button. `db_host` is limited to the panel's own MariaDB host (`localhost`, `127.0.0.1`, `::1` or the configured `mysql.host`); any other host answers 422.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `db_host` | string | no | default `localhost`; maxLength=255; pattern=`^(?:[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*\|\d{1,3}(?:\.\d{1,3}){3})$` |
| `db_password` | string | yes | — |
| `db_user` | string | yes | minLength=1; maxLength=64; pattern=`^[A-Za-z0-9_][A-Za-z0-9_.-]*$` |

**Request body example:**

```json
{
  "db_host": "localhost",
  "db_password": "REPLACE_ME",
  "db_user": "string"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/phpmyadmin/sso
```

---

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

*phpMyAdmin install status*

Reports whether phpMyAdmin is installed + the installed version.

**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/phpmyadmin/status
```

---

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

*Reboot server*

Schedules a host reboot via systemd. Returns the message before the box actually goes down.

**Responses:**

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

**Response example (200):**

```json
{
  "message": "string",
  "status": "success"
}
```

**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/reboot
```

---

<a id="get-api-v1-system-resource-consumers"></a>
#### `GET /api/v1/system/resource-consumers`

*Top resource consumer processes*

Snapshot of top CPU + memory consumers — used by the dashboard live monitor. `resource=disk` answers from the last disk walk (system directories and account homes); `refreshing: true` means that answer is older than 30 seconds and a new walk is running — ask again shortly for the fresh numbers.

**Query parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `resource` | string | no | — |

**Responses:**

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

**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/resource-consumers
```

---

<a id="post-api-v1-system-root-password"></a>
#### `POST /api/v1/system/root-password`

*Change Linux root password*

Sets a new password for the Linux root system account. **Session-cookie auth required** — HMAC API keys are rejected with 403 `HMAC_FORBIDDEN_FOR_CREDENTIAL_MUTATION`, as for every credential mutation.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `new_password` | string | yes | — |

**Request body example:**

```json
{
  "new_password": "REPLACE_ME"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "message": "string",
  "status": "success"
}
```

**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/root-password
```

---

<a id="put-api-v1-system-server-ip"></a>
#### `PUT /api/v1/system/server-ip`

*Change advertised server IP*

Updates the IP advertised in DNS A records + vhost defaults. Existing account DNS zones are rewritten.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `ip` | string | yes | — |

**Request body example:**

```json
{
  "ip": "string"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {},
  "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/server-ip
```

---

<a id="post-api-v1-system-service-name"></a>
#### `POST /api/v1/system/service/{name}`

*Service action (start/stop/restart/reload)*

Runs the systemd action against the named managed service. Returns the new state snapshot.

**Path parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `name` | string | yes | — |

**Query parameters:**

| Name | Type | Required | Notes |
|------|------|----------|-------|
| `action` | string | no | — |

**Responses:**

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

**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/service/{name}
```

---

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

*List managed services + status*

Returns every service WHost knows about (web, mail, DNS, FTP, fail2ban, agent) with running state, uptime, memory.

**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/services
```

---

<a id="get-api-v1-system-services-flat"></a>
#### `GET /api/v1/system/services/flat`

*Flat services list (compact)*

Same data as `/services` but as a flat name→status map — used by the dashboard sidebar.

**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/services/flat
```

---

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

*Get general server settings*

Server label, timezone, default language, default webserver, billing/notification email defaults.

**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/settings/general
```

---

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

*Update general server settings*

Patch label / timezone / language / webserver default / notification defaults.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `auto_ssl` | boolean | no | — |
| `available_timezones` | array<string> | no | — |
| `client_features` | object | no | — |
| `db_buffer_pool_size` | integer | no | — |
| `db_connect_timeout` | integer | no | — |
| `db_interactive_timeout` | integer | no | — |
| `db_max_allowed_packet` | string | no | — |
| `db_max_connections` | integer | no | — |
| `db_read_buffer_size` | string | no | — |
| `db_sort_buffer_size` | string | no | — |
| `db_wait_timeout` | integer | no | — |
| `default_email_limit` | integer | no | — |
| `default_language` | string | no | — |
| `default_php_version` | string | no | — |
| `default_webserver` | string | no | — |
| `force_ssl` | boolean | no | — |
| `ftp_bandwidth_limit` | integer | no | — |
| `ftp_max_clients` | integer | no | — |
| `ftp_max_per_ip` | integer | no | — |
| `ftp_passive_mode` | boolean | no | — |
| `ftp_passive_ports` | string | no | — |
| `hostname` | string | no | — |
| `installed_php_versions` | array<string> | no | — |
| `keepalive_timeout` | integer | no | — |
| `max_clients` | integer | no | — |
| `max_email_size` | integer | no | — |
| `ns1` | string | no | — |
| `ns2` | string | no | — |
| `ns3` | string | no | — |
| `ns4` | string | no | — |
| `server_ip` | string | no | — |
| `server_time` | string | no | — |
| `server_timezone` | string | no | — |
| `ssl_email` | string | no | — |

**Request body example:**

```json
{
  "auto_ssl": false,
  "available_timezones": [
    "string"
  ],
  "client_features": {},
  "db_buffer_pool_size": 0,
  "db_connect_timeout": 0,
  "db_interactive_timeout": 0,
  "db_max_allowed_packet": "string",
  "db_max_connections": 0,
  "db_read_buffer_size": "string",
  "db_sort_buffer_size": "string",
  "db_wait_timeout": 0,
  "default_email_limit": 0,
  "default_language": "string",
  "default_php_version": "string",
  "default_webserver": "string",
  "force_ssl": false,
  "ftp_bandwidth_limit": 0,
  "ftp_max_clients": 0,
  "ftp_max_per_ip": 0,
  "ftp_passive_mode": false,
  "ftp_passive_ports": "string",
  "hostname": "string",
  "installed_php_versions": [
    "string"
  ],
  "keepalive_timeout": 0,
  "max_clients": 0,
  "max_email_size": 0,
  "ns1": "string",
  "ns2": "string",
  "ns3": "string",
  "ns4": "string",
  "server_ip": "string",
  "server_time": "string",
  "server_timezone": "string",
  "ssl_email": "string"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {},
  "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/settings/general
```

---

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

*Get security settings*

Returns the security config block (HMAC nonce TTL, session timeout, IP allowlist, captcha provider).

**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/settings/security
```

---

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

*Update security settings*

Patch security config. Secrets sent as the masked sentinel are kept untouched.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `admin_allowed_ips` | string | no | — |
| `auto_configure_dkim` | boolean | no | — |
| `auto_configure_dmarc` | boolean | no | — |
| `auto_configure_spf` | boolean | no | — |
| `captcha_enabled` | boolean | no | — |
| `captcha_hcaptcha_secret_key` | string | no | — |
| `captcha_hcaptcha_site_key` | string | no | — |
| `captcha_provider` | string | no | — |
| `captcha_recaptcha_secret_key` | string | no | — |
| `captcha_recaptcha_site_key` | string | no | — |
| `captcha_threshold` | number | no | — |
| `captcha_turnstile_secret_key` | string | no | — |
| `captcha_turnstile_site_key` | string | no | — |
| `client_ip` | string | no | — |
| `dmarc_policy` | string | no | — |
| `force` | boolean | no | default `False` |
| `session_timeout_minutes` | integer | no | — |
| `ssh_allowed_ips` | string | no | — |
| `ssh_key_auth` | boolean | no | — |
| `ssh_password_auth` | boolean | no | — |
| `ssh_port` | integer | no | — |
| `ssh_root_login` | boolean | no | — |
| `two_factor_enforcement` | boolean | no | — |
| `two_factor_method` | string | no | — |

**Request body example:**

```json
{
  "admin_allowed_ips": "string",
  "auto_configure_dkim": false,
  "auto_configure_dmarc": false,
  "auto_configure_spf": false,
  "captcha_enabled": false,
  "captcha_hcaptcha_secret_key": "string",
  "captcha_hcaptcha_site_key": "string",
  "captcha_provider": "string",
  "captcha_recaptcha_secret_key": "string",
  "captcha_recaptcha_site_key": "string",
  "captcha_threshold": 0.0,
  "captcha_turnstile_secret_key": "string",
  "captcha_turnstile_site_key": "string",
  "client_ip": "string",
  "dmarc_policy": "string",
  "force": false,
  "session_timeout_minutes": 0,
  "ssh_allowed_ips": "string",
  "ssh_key_auth": false,
  "ssh_password_auth": false,
  "ssh_port": 0,
  "ssh_root_login": false,
  "two_factor_enforcement": false,
  "two_factor_method": "string"
}
```

**Responses:**

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

**Response example (200):**

```json
{
  "data": {},
  "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/settings/security
```

---

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

*Aggregate server stats*

Account / domain / database / email counts + resource totals — backs the dashboard top cards.

**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/stats
```

---

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

*Install Roundcube webmail*

Provisions Roundcube and the Dovecot master-user SSO bridge (a no-op answer when Roundcube is already installed).

**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/webmail/install
```

---

<a id="post-api-v1-system-webmail-sso"></a>
#### `POST /api/v1/system/webmail/sso`

*Mint webmail SSO token*

Internal — returns the short-lived SSO redirect URL for the panel's Roundcube button. The mailbox must exist (404 `EMAIL_NOT_FOUND`) and be active (409 `EMAIL_INACTIVE`); 503 `WEBMAIL_NOT_INSTALLED` / `WEBMAIL_SSO_NOT_CONFIGURED` when the bridge is absent. The mint is audited.

**Body fields:**

| Field | Type | Required | Notes |
|-------|------|----------|-------|
| `email` | string | yes | minLength=3; maxLength=254 |

**Request body example:**

```json
{
  "email": "user@example.com"
}
```

**Responses:**

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

**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)" \
  -H "Content-Type: application/json" \
  -d @body.json \
  https://your-server:2000/api/v1/system/webmail/sso
```

---

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

*Webmail (Roundcube) install status*

Reports whether Roundcube is installed + version.

**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/webmail/status
```

---
