# VM Instances endpoints (Admin API)

> 28 FeatherPanel Admin API endpoints from admin/vm-instances.php: methods, paths, auth, permissions, rate limits, parameters and responses.

Source: https://featherpanel.com/docs/api/reference/admin/vm-instances/

Defined in [`backend/app/routes/admin/vm-instances.php`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php). Authentication used here: **Admin**. Read [Authentication](https://featherpanel.com/docs/api/authentication/) for how to send credentials and [Rate limits and errors](https://featherpanel.com/docs/api/rate-limits-and-errors/) for the response envelope.

Paths, methods, permissions and rate limits come from the route file. Summaries, parameters and response codes come from the OpenAPI annotations on the controllers; endpoints without annotations show only what the route file declares.

## Endpoints

### GET `/api/admin/vm-instances`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-index`
- Controller: [`VmInstancesController::index`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L27)

**List VM instances** Get a paginated list of VM instances with optional search.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `page` | query | integer | no | Page number |
| `limit` | query | integer | no | Records per page |
| `search` | query | string | no | Search term |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `instances` | VmInstance\[\] |  |
| `status_counts` | object |  |
| `pagination` | VmInstancePagination |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` VM instances retrieved successfully · `401` Unauthorized · `403` Forbidden

### PUT `/api/admin/vm-instances`

- Auth: Admin
- Permission: `admin.nodes.create`
- Route name: `admin-vm-instances-create`
- Controller: [`VmInstancesController::create`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L39)

**Create new VM instance** Create a new VM instance (server) on a Proxmox node. Returns 202 with creation\_id. Poll creation-status until active or failed.

Request body: [`VmInstanceCreate`](https://featherpanel.com/docs/api/schemas/#schema-vminstancecreate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `vm_node_id` | integer | yes | VM Node ID |
| `template_id` | integer | yes | Template ID |
| `pve_node` | string | no | Explicit Proxmox cluster node to place the VM on |
| `memory` | integer | no | Memory in MB |
| `cpus` | integer | no | Number of CPU sockets |
| `cores` | integer | no | Number of CPU cores per socket |
| `disk` | integer | no | Disk size in GB |
| `storage` | string | no | Storage name |
| `bridge` | string | no | Network bridge |
| `on_boot` | integer | no | Start on boot |
| `hostname` | string | no | Hostname |
| `vm_ip_id` | integer | no | Specific IP ID to assign |
| `networks` | object\[\] | no | List of network IP assignments for this VM |
| `user_uuid` | string | no | User UUID |
| `notes` | string | no | Notes |
| `ci_user` | string | no | Cloud-init user (required for KVM/QEMU) |
| `ci_password` | string | no | Cloud-init password (required for KVM/QEMU). Not used for LXC. |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `creation_id` | string |  |
| `message` | string |  |

```bash
curl -X PUT "$PANEL_URL/api/admin/vm-instances" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"vm_node_id":0,"template_id":0,"pve_node":"","memory":0,"cpus":0,"cores":0,"disk":0,"storage":"","bridge":"","on_boot":0,"hostname":"","vm_ip_id":0,"networks":[],"user_uuid":"","notes":"","ci_user":"","ci_password":""}'
```

Plugin events: [`featherpanel:vds:created`](https://featherpanel.com/docs/plugins/events/vds/#vds-created)

Responses: `202` VM creation started · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM node or template not found · `500` Internal server error

### GET `/api/admin/vm-instances/creation-status/{creationId}`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-creation-status`
- Controller: [`VmInstancesController::creationStatus`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L51)

**Poll VM creation status** Poll status of an async VM creation. Returns status cloning, active, or failed.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `creationId` | path | string | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `status` | string |  |
| `message` | string |  |
| `error` | string |  |
| `instance` | VmInstance |  |
| `ci_user` | string |  |
| `ci_password` | string |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/creation-status/$CREATION_ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Creation status · `400` Missing creation\_id · `401` Unauthorized · `404` Creation not found or already completed · `500` Internal server error

### GET `/api/admin/vm-instances/task-status/{taskId}`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-task-status`
- Controller: [`VmInstancesController::taskStatus`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L65)

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `taskId` | path | \- | yes |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/task-status/$TASK_ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

### GET `/api/admin/vm-instances/{id}`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-show`
- Controller: [`VmInstancesController::show`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L79)

**Get VM instance** Get a single VM instance by ID.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `instance` | VmInstance |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` VM instance retrieved successfully · `401` Unauthorized · `403` Forbidden · `404` VM instance not found

### PATCH `/api/admin/vm-instances/{id}`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-update`
- Controller: [`VmInstancesController::update`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L96)

**Update VM instance** Update instance: hostname, notes, user\_uuid, vm\_ip\_id, memory, cpus, cores, on\_boot, networks.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

Request body: [`VmInstanceUpdate`](https://featherpanel.com/docs/api/schemas/#schema-vminstanceupdate) (application/json)

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `hostname` | string | no | Hostname |
| `notes` | string | no | Notes |
| `user_uuid` | string | no | User UUID |
| `vm_ip_id` | integer | no | VM IP ID |
| `memory` | integer | no | Memory in MB |
| `cpus` | integer | no | Number of CPUs |
| `cores` | integer | no | Number of Cores |
| `on_boot` | boolean | no | Start on boot |
| `networks` | object\[\] | no | List of networks (LXC) |
| `nameserver` | string | no | Nameserver (LXC) |
| `searchdomain` | string | no | Search domain (LXC) |
| `bios` | string | no | QEMU BIOS mode: seabios or ovmf (EFI) |
| `efi_enabled` | boolean | no | Enable EFI disk (QEMU only) |
| `efi_storage` | string | no | Storage for EFI disk (QEMU only) |
| `tpm_enabled` | boolean | no | Enable TPM state disk (QEMU only) |
| `tpm_storage` | string | no | Storage for TPM state disk (QEMU only) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `instance` | VmInstance |  |

```bash
curl -X PATCH "$PANEL_URL/api/admin/vm-instances/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"hostname":"","notes":"","user_uuid":"","vm_ip_id":0,"memory":0,"cpus":0,"cores":0,"on_boot":false,"networks":[],"nameserver":"","searchdomain":"","bios":"","efi_enabled":false,"efi_storage":"","tpm_enabled":false,"tpm_storage":""}'
```

Plugin events: [`featherpanel:vds:updated`](https://featherpanel.com/docs/plugins/events/vds/#vds-updated)

Responses: `200` VM instance updated successfully · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error · `503` Proxmox update failed

### GET `/api/admin/vm-instances/{id}/activities`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-activities`
- Controller: [`VmInstancesController::activities`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L113)

**Get VM instance activities** GET activity/task history for this VM instance.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |
| `limit` | query | integer | no |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `activities` | object\[\] |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/$ID/activities" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Activities fetched successfully · `401` Unauthorized · `403` Forbidden · `404` VM instance not found

### GET `/api/admin/vm-instances/{id}/config`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-config`
- Controller: [`VmInstancesController::getConfig`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L130)

**Get VM instance config** GET Proxmox config for this instance.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `config` | object |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/$ID/config" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Config fetched successfully · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error · `503` Proxmox error

### GET `/api/admin/vm-instances/{id}/status`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-status`
- Controller: [`VmInstancesController::getStatus`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L147)

**Get VM instance status** GET current VM/container status and resource usage from Proxmox.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `status` | object |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/$ID/status" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Status fetched successfully · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error · `503` Proxmox error

### GET `/api/admin/vm-instances/{id}/vnc-ticket`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-vnc-ticket`
- Controller: [`VmInstancesController::vncTicket`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L164)

**Get VNC ticket** GET VNC console ticket for QEMU VMs and LXC containers.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `ticket` | string |  |
| `port` | integer |  |
| `node` | string |  |
| `vmid` | integer |  |
| `host` | string |  |
| `port_api` | integer |  |
| `wss_url` | string |  |
| `pve_redirect_url` | string |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/$ID/vnc-ticket" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:vds:console:access`](https://featherpanel.com/docs/plugins/events/vds/#vds-console-accessed)

Responses: `200` VNC ticket created · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error · `503` VNC proxy failed

### POST `/api/admin/vm-instances/{id}/resize-disk`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-resize-disk`
- Controller: [`VmInstancesController::resizeDisk`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L181)

**Resize VM/container disk** Resize a disk on an LXC container or QEMU VM. Body must include "disk" and "size".

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `disk` | string | no | Disk name e.g. rootfs or mp0 |
| `size` | string | no | Size to add or absolute e.g. +5G or 20G |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string |  |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/resize-disk" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"disk":"","size":""}'
```

Responses: `200` Disk resized successfully · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error · `503` Resize failed

### POST `/api/admin/vm-instances/{id}/disks`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-create-disk`
- Controller: [`VmInstancesController::createDisk`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L198)

**Create VM/container disk** Create an additional disk: LXC mount point or QEMU disk.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `storage` | string | no | Storage name e.g. local-lvm |
| `size_gb` | integer | no | Size in GB |
| `path` | string | no | Mount point path e.g. /mnt/data |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `disk` | string |  |
| `config_key` | string |  |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/disks" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"storage":"","size_gb":0,"path":""}'
```

Responses: `200` Disk added successfully · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error · `503` Proxmox update failed

### DELETE `/api/admin/vm-instances/{id}/disks/{key}`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-delete-disk`
- Controller: [`VmInstancesController::deleteDisk`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L215)

**Delete VM/container disk** DELETE LXC mount point or QEMU disk.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |
| `key` | path | string | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `deleted` | string |  |

```bash
curl -X DELETE "$PANEL_URL/api/admin/vm-instances/$ID/disks/$KEY" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Disk removed successfully · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error · `503` Proxmox update failed

### POST `/api/admin/vm-instances/{id}/power`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-power`
- Controller: [`VmInstancesController::power`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L233)

**Power action** Power action: start | stop | reboot.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `action` | string | no |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `instance` | VmInstance |  |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/power" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"action":""}'
```

Plugin events: [`featherpanel:vds:power:action`](https://featherpanel.com/docs/plugins/events/vds/#vds-power-action)

Responses: `200` Power action completed · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance not found · `500` Internal server error / Power failed

### POST `/api/admin/vm-instances/{id}/reinstall`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-reinstall`
- Controller: [`VmInstancesController::reinstall`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L250)

**Start async VM reinstall** Kicks off a full reinstall by cloning a fresh VM from the original template. Returns 202 with a reinstall\_id immediately. Poll reinstall-status/{reinstallId} until status is active or failed.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `reinstall_id` | string |  |
| `message` | string |  |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/reinstall" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:vds:reinstall`](https://featherpanel.com/docs/plugins/events/vds/#vds-reinstalled)

Responses: `202` Reinstall clone started · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance or template not found · `500` Internal server error

### GET `/api/admin/vm-instances/reinstall-status/{reinstallId}`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-reinstall-status`
- Controller: [`VmInstancesController::reinstallStatus`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L267)

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `reinstallId` | path | \- | yes |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/reinstall-status/$REINSTALL_ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

### GET `/api/admin/vm-instances/{id}/backups`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-backups-list`
- Controller: [`VmInstancesController::listBackups`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L284)

**List VM backups** List vzdump backups for a specific VM or container on its Proxmox node.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `backups` | object\[\] |  |
| `backup_limit` | integer |  |
| `storages` | string\[\] | Available backup storages from Proxmox |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/$ID/backups" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Backups listed · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance or node not found · `500` Proxmox error

### POST `/api/admin/vm-instances/{id}/backups/{backupId}/recover`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-backup-recover`
- Controller: [`VmInstancesController::recoverBackup`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L300)

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | \- | yes |  |
| `backupId` | path | \- | yes |  |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/backups/$BACKUP_ID/recover" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

### POST `/api/admin/vm-instances/{id}/backups`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-backup-create`
- Controller: [`VmInstancesController::createBackup`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L312)

**Create VM backup** Start an async vzdump backup for a VM or container. Returns 202 with backup\_id; poll backup-status until done or failed.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `storage` | string | no | Proxmox storage for the backup (optional, defaults to first backup-capable storage) |
| `compress` | string | no | Compression method (zstd, lzo, gzip, 0) |
| `mode` | string | no | Backup mode (snapshot, suspend, stop) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `backup_id` | string |  |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/backups" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"storage":"","compress":"","mode":""}'
```

Plugin events: [`featherpanel:vds:backup:create`](https://featherpanel.com/docs/plugins/events/vds/#vds-backup-created)

Responses: `202` Backup started · `400` Bad request · `401` Unauthorized · `403` Forbidden · `404` VM instance or node not found · `422` Backup limit reached · `500` Proxmox error

### GET `/api/admin/vm-instances/backup-status/{backupId}`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-backup-status`
- Controller: [`VmInstancesController::backupStatus`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L329)

**Poll VM backup status** Poll status of an async vzdump backup. Returns running, done, or failed.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `backupId` | path | string | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `status` | string |  |
| `error` | string |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/backup-status/$BACKUP_ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Backup status · `400` Missing or invalid backupId · `401` Unauthorized · `404` Backup task or instance not found · `500` Internal server error

### DELETE `/api/admin/vm-instances/{id}/backups`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-backup-delete`
- Controller: [`VmInstancesController::deleteBackupVolume`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L346)

**Delete VM backup** Delete a single vzdump backup volume belonging to a VM or container.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `volid` | string | no | Proxmox backup volume ID |
| `storage` | string | no | Proxmox storage name |

```bash
curl -X DELETE "$PANEL_URL/api/admin/vm-instances/$ID/backups" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"volid":"","storage":""}'
```

Plugin events: [`featherpanel:vds:backup:delete`](https://featherpanel.com/docs/plugins/events/vds/#vds-backup-deleted)

Responses: `200` Backup deleted · `400` Missing volid or storage · `401` Unauthorized · `403` Backup does not belong to this VM · `404` VM instance or node not found · `500` Proxmox error

### POST `/api/admin/vm-instances/{id}/backups/restore`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-restore-backup`
- Controller: [`VmInstancesController::restoreBackup`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L363)

**Restore VM from backup** Start an async restore of a VM or container from a vzdump backup. Returns 202 with restore\_id; poll restore-status until active or failed.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `volid` | string | no | Proxmox backup volume ID |
| `storage` | string | no | Proxmox storage name |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `restore_id` | string |  |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/backups/restore" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"volid":"","storage":""}'
```

Plugin events: [`featherpanel:vds:backup:restore`](https://featherpanel.com/docs/plugins/events/vds/#vds-backup-restored)

Responses: `202` Restore started · `400` Missing volid or storage · `401` Unauthorized · `403` Forbidden · `404` VM instance or node not found · `500` Proxmox error

### GET `/api/admin/vm-instances/restore-status/{restoreId}`

- Auth: Admin
- Permission: `admin.nodes.view`
- Route name: `admin-vm-instances-restore-status`
- Controller: [`VmInstancesController::restoreBackupStatus`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L380)

**Poll VM restore status** Poll status of an async restore from backup. Returns restoring, active, or failed.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `restoreId` | path | string | yes |  |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `status` | string |  |
| `instance` | VmInstance |  |
| `error` | string |  |

```bash
curl -X GET "$PANEL_URL/api/admin/vm-instances/restore-status/$RESTORE_ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Responses: `200` Restore status · `400` Missing or invalid restoreId · `401` Unauthorized · `404` Restore task or instance not found · `500` Internal server error

### PATCH `/api/admin/vm-instances/{id}/backup-limit`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-backup-limit`
- Controller: [`VmInstancesController::setBackupLimit`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L397)

**Set VM backup limit** Update the maximum number of backups allowed for a VM instance.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

| Body field | Type | Required | Description |
| --- | --- | --- | --- |
| `limit` | integer | no | Maximum number of backups (0 to 100) |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `backup_limit` | integer |  |

```bash
curl -X PATCH "$PANEL_URL/api/admin/vm-instances/$ID/backup-limit" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"limit":0}'
```

Plugin events: [`featherpanel:vds:updated`](https://featherpanel.com/docs/plugins/events/vds/#vds-updated)

Responses: `200` Backup limit updated · `400` Invalid limit · `401` Unauthorized · `404` VM instance not found · `500` Internal server error

### POST `/api/admin/vm-instances/{id}/suspend`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-suspend`
- Controller: [`VmInstancesController::suspend`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L414)

**Suspend VM instance** Suspend a VM instance by stopping it in Proxmox and updating the suspended status. Sends notification email to the VM owner.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | VM Instance ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/suspend" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:vds:suspended`](https://featherpanel.com/docs/plugins/events/vds/#vds-suspended)

Responses: `200` VM instance suspended successfully · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` VM instance not found · `500` Internal server error - Failed to suspend VM

### POST `/api/admin/vm-instances/{id}/unsuspend`

- Auth: Admin
- Permission: `admin.nodes.edit`
- Route name: `admin-vm-instances-unsuspend`
- Controller: [`VmInstancesController::unsuspend`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L431)

**Unsuspend VM instance** Unsuspend a VM instance by updating the suspended status. Sends notification email to the VM owner.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes | VM Instance ID |

| Response `data` field | Type | Description |
| --- | --- | --- |
| `message` | string | Success message |

```bash
curl -X POST "$PANEL_URL/api/admin/vm-instances/$ID/unsuspend" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:vds:unsuspended`](https://featherpanel.com/docs/plugins/events/vds/#vds-unsuspended)

Responses: `200` VM instance unsuspended successfully · `401` Unauthorized · `403` Forbidden - Insufficient permissions · `404` VM instance not found · `500` Internal server error - Failed to unsuspend VM

### DELETE `/api/admin/vm-instances/{id}`

- Auth: Admin
- Permission: `admin.nodes.delete`
- Route name: `admin-vm-instances-delete`
- Controller: [`VmInstancesController::delete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L448)

**Delete VM instance** Delete VM instance: stop on Proxmox (if running), delete from Proxmox, then remove from DB.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

```bash
curl -X DELETE "$PANEL_URL/api/admin/vm-instances/$ID" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:vds:deleted`](https://featherpanel.com/docs/plugins/events/vds/#vds-deleted)

Responses: `200` VM instance deleted successfully · `401` Unauthorized · `403` Forbidden · `404` VM instance not found

### DELETE `/api/admin/vm-instances/{id}/hard`

- Auth: Admin
- Permission: `admin.nodes.delete`
- Route name: `admin-vm-instances-hard-delete`
- Controller: [`VmInstancesController::hardDelete`](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/Controllers/Admin/VmInstancesController.php)
- [route source](https://github.com/MythicalLTD/FeatherPanel/blob/15b94e9fc9df233123706b47c42728b81e48cb3d/backend/app/routes/admin/vm-instances.php#L464)

**Hard delete VM instance** Remove the VM instance and panel records without contacting Proxmox. The VM and its files remain on the Proxmox host.

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | integer | yes |  |

```bash
curl -X DELETE "$PANEL_URL/api/admin/vm-instances/$ID/hard" \
  -H "Authorization: Bearer $FEATHERPANEL_API_KEY" \
  -H "Accept: application/json"
```

Plugin events: [`featherpanel:vds:deleted`](https://featherpanel.com/docs/plugins/events/vds/#vds-deleted)

Responses: `200` VM instance hard deleted successfully · `404` VM instance not found
