---
title: "Virtual desktop (VDI) sessions"
slug: "vdi-sessions-provisioning"
source: "https://app.cloudpe.com/help/vdi-sessions-provisioning"
updated: "2026-08-27T05:22:14.372Z"
---

# Virtual desktop (VDI) sessions

## Overview

VDI sessions give a user a full virtual desktop — a Windows or Linux instance provisioned from a VDI-enabled image and reached from the browser, without an SSH key or an RDP gateway of your own. Each session is a first-class resource: it has a region, a flavor, a root volume, a network, an optional expiry, and its own detail page with volumes, metrics and logs.

Sessions live under **VDI** in the **COMPUTE** section of the dashboard. They are organization-scoped and provision into the regional VDI service project, so you do not pick a CMP project for them. Sessions can optionally be grouped so that lifecycle actions (extend, shelve, delete) apply to a whole classroom or team at once.

VDI is in beta. Behaviour and available regions can change, and you should not place a production-critical desktop on it without a fallback.

## Before you start

- Identity verification: your organization must have completed KYC. Without it, resource creation is refused with `Complete identity verification to create cloud resources.`
- Permissions: you need `vdi_sessions:read` to see the list, `vdi_sessions:create` to provision, `vdi_sessions:extend` to push an expiry out, `vdi_sessions:update` for power actions, rename, resize, snapshots and schedules, and `vdi_sessions:delete` to remove a session.
- A VDI-enabled region: not every region serves VDI. If the region you pick is not enabled, or the platform has no VDI credentials configured for it, creation fails — see Troubleshooting.
- A VDI-shared image: only images published for VDI appear in the **Image** picker. Custom images have to be enabled for VDI sharing first.
- One active organization: if your user belongs to more than one organization, select the active one before creating; the API requires the `X-Organization-Id` header in that case.
- Wallet and billing standing: session creation runs the same billable-create gate as other compute resources, so the account must be in good standing.

## Steps

1. In the dashboard sidebar, open **VDI**. The **Sessions** tab lists every session in the organization; **Groups** lists session groups.

   ![](/kb/vdi/vdi-sessions-provisioning-01-list.png)

2. Click **Create Session**. To provision several desktops from one form instead, click **Bulk Create Sessions**.

3. On **Create VDI Session**, fill in the form:

   - **Session Name** — the display name; it is also used to generate the session's access slug.
   - **Group** — attach the session to an existing group, or name a new one. Leave empty for a standalone session.
   - **Region** — a VDI-enabled region.
   - **VM Configuration** — the flavor that sets vCPU and RAM.
   - **Image** — the desktop image to boot.
   - **Storage (GB)** — the root volume size.
   - **Network** — a VDI network in the region; leave it unset to use the region default.
   - **Session Expiry** — when the session is auto-deleted. If you set nothing, the session expires after 24. You can also mark the session as having no expiry.

   ![](/kb/vdi/vdi-sessions-provisioning-02-create.png)

4. Click **Create Session** (or **Cancel** to discard). The session is queued for provisioning on the workspace server.

5. Use **Refresh** on the list, or **Refresh status** on the session page, until the session reports ready.

6. Open the session to reach its detail page. The **Overview**, **Volumes**, **Networking**, **Metrics**, **Logs** and **Settings** tabs cover the rest of its lifecycle. Use **Open Desktop** to connect, or **Copy Link** to hand the access URL to the person who will use it.

   ![](/kb/vdi/vdi-sessions-provisioning-03-detail.png)

## API

All calls use a Bearer API key. If you belong to more than one organization, send `X-Organization-Id` as well.

| Operation | Method + path |
|---|---|
| Price estimate | `POST /api/v1/vdi/estimate` |
| List VDI images | `GET /api/v1/vdi/images` |
| List VDI networks | `GET /api/v1/vdi/networks` |
| List sessions | `GET /api/v1/vdi/sessions` |
| Create session | `POST /api/v1/vdi/sessions` |
| Bulk create sessions | `POST /api/v1/vdi/sessions/bulk` |
| Get session | `GET /api/v1/vdi/sessions/{session_id}` |
| Launch session | `POST /api/v1/vdi/sessions/{session_id}/launch` |
| Extend session | `POST /api/v1/vdi/sessions/{session_id}/extend` |
| Power action (start, stop, reboot, hard_reboot, shelve, unshelve) | `POST /api/v1/vdi/sessions/{session_id}/actions` |
| Rename session | `PATCH /api/v1/vdi/sessions/{session_id}/rename` |
| Resize session | `POST /api/v1/vdi/sessions/{session_id}/resize` |
| Rebuild session | `POST /api/v1/vdi/sessions/{session_id}/rebuild` |
| Change desktop password | `POST /api/v1/vdi/sessions/{session_id}/password` |
| Delete session | `DELETE /api/v1/vdi/sessions/{session_id}` |

Create a session:

```bash
curl -X POST https://app.cloudpe.com/api/v1/vdi/sessions \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "design-desk-01",
    "region": "<region-slug>",
    "flavor": "<flavor-slug>",
    "image": "<image-slug>"
  }'
```

`region`, `flavor` and `image` each accept a slug or the provider `openstack_id`. Optional body fields include `group_id` or `group_name`, `network_id`, `storage_gb`, `expires_at`, `expiry_hours`, `no_expiry` and `user_data` (cloud-init cloud-config YAML applied on first boot).

Quote the cost before you commit:

```bash
curl -X POST https://app.cloudpe.com/api/v1/vdi/estimate \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "region": "<region-slug>",
    "flavor": "<flavor-slug>",
    "image": "<image-slug>"
  }'
```

Fetch a session's state:

```bash
curl https://app.cloudpe.com/api/v1/vdi/sessions/<session_id> \
  -H "Authorization: Bearer <API_KEY>"
```

## Limits & billing

- A session that reaches its expiry is deleted, not stopped. Extend it before then, or create it with no expiry.
- Default expiry when you specify neither `expires_at` nor `expiry_hours`: 24. Maximum session lifetime: 720. An extension that would push the total past that maximum is rejected.
- Concurrent sessions per user are capped at 30.
- Session creation is rate limited to 60 per hour; a bulk request counts every session it asks for.
- A running session bills like the equivalent compute instance plus its root volume. Shelving a session (through the session's power action or a shelve schedule) is the way to stop compute charges while keeping the desktop's disk.
- Use `POST /api/v1/vdi/estimate` for a price before creating.

## Troubleshooting

| Error | What it means | What to do |
|---|---|---|
| `VDI is not enabled for this region` | The selected region does not serve VDI. | Choose a VDI-enabled region in **Region**. |
| `VDI credentials not configured for region {…}. Contact administrator.` | The region is marked VDI-enabled but has no workspace credential. | Raise a support ticket; this needs a platform administrator. |
| `Region not visible to your organization` | The region is not in your organization's allowed set. | Pick another region, or ask support to enable it. |
| `Image '{…}' not found` | The image slug or ID is wrong, or that image is not shared to VDI. | List candidates with `GET /api/v1/vdi/images` and retry with one of those. |
| `You belong to multiple organizations. Specify the active organization (X-Organization-Id) before creating a VDI session.` | The request is ambiguous across your memberships. | Select the active organization in the dashboard, or send the `X-Organization-Id` header. |
| `Concurrent VDI session limit reached ({…}/{…}); requested {…}.` | The per-user session cap is full. | Delete or let expire sessions you no longer need, then retry. |
| `VDI create rate limit reached ({…}/{…} in the last hour); requested {…}.` | Too many creates in the trailing hour, usually from a bulk request. | Wait and submit a smaller batch. |
| `Session lifetime exceeds the configured maximum of {…}h (requested {…}h).` | The requested expiry is beyond the maximum lifetime. | Request a shorter lifetime and extend later. |
| `Extension would exceed max session lifetime ({…}h). Current total would be {…}h.` | The extension pushes past the maximum lifetime. | Extend by less, or create a fresh session. |
| `Session has no expiry; there is nothing to extend.` | The session was created with no expiry. | No action needed — it will not auto-delete. |
| `Session cannot be launched in '{…}' status. Must be 'ready' or 'active'.` | The session is still building, shelved or errored. | Use **Refresh status**, or unshelve/start it, then launch again. |
| `Session is not yet provisioned on the workspace server.` | Provisioning has not finished. | Wait and refresh. |
| `Session is not ready for connection (status: {…})` | The desktop is not in a connectable state. | Check the **Overview** tab for the current status before clicking **Open Desktop**. |
| `Session IP not yet assigned` | Networking has not completed. | Retry shortly; check the **Networking** tab. |
| `Session has expired.` | The expiry passed and the session is gone. | Create a new session; extend earlier next time. |
| `VDI provisioning queue is unavailable. Please retry shortly.` | The provisioning worker could not accept the request. | Retry in a few minutes. |
| `Workspace server is temporarily unavailable. Please try again.` | The regional workspace service did not respond. | Retry; if it persists, contact support. |
| `Cannot delete session in '{…}' state` | The session is mid-transition. | Wait for the current operation to finish, then delete. |
| `Complete identity verification to create cloud resources.` | KYC is not complete for the organization. | Finish identity verification, then retry. |

## FAQ

**What happens when a session expires?**
It is auto-deleted. Extend it before the expiry with **Extend** or `POST /api/v1/vdi/sessions/{session_id}/extend`, or create it with no expiry.

**Can I create many desktops at once?**
Yes — use **Bulk Create Sessions** in the dashboard or `POST /api/v1/vdi/sessions/bulk`. All sessions in a bulk request share the region, flavor, image, storage and expiry settings, and can be attached to one group.

**Do I choose a project for a VDI session?**
No. VDI sessions are organization-scoped and provision into the regional VDI service project.

**Can I use my own custom image?**
Only if it has been enabled for VDI sharing (`POST /api/v1/images/{image_id}/enable-vdi`); that call itself requires completed identity verification. Use `POST /api/v1/images/{image_id}/disable-vdi` to withdraw it.

**How do I stop paying for a desktop I still need later?**
Shelve it — either the `shelve` power action, or a shelve schedule on the session or its group. Unshelve when it is needed again.

**Can I change the flavor after creation?**
Yes: `POST /api/v1/vdi/sessions/{session_id}/resize`, then confirm with `/resize/confirm` or roll back with `/resize/revert`.

**Can I pass startup configuration?**
Yes — the `user_data` field takes cloud-init cloud-config YAML, applied on first boot.

## Related

- [VDI desktop groups](/help/vdi-desktop-groups)
- [Connecting to virtual desktops](/help/connecting-to-virtual-desktops)