GPU VM
General conventions
- Base URL:
BASE_API_URL - Path:
/bff/v1/gpu-vm/{orgIdentifier}/workspaces/{workspaceIdentifier}/{action} - Method: All endpoints use POST.
- Service-specific headers:
X-Region: <region> - Common headers (apiClient):
x-scope: workspace,X-Org-Id,X-Workspace-Id,X-User-Id - Response envelope:
{ "code": "", "message": "", "data": ..., "total": 0 }
How to get token and headers
- Log in to the Portal and navigate to the GPU Virtual Machine page.
- Open the Network tab in browser DevTools, select the
gpu-vm.listrequest to get the API path format (includingorgIdentifierandworkspaceIdentifier). - Copy the following request headers:
cookie,x-env,x-org-id,x-region,x-user-id,x-workspace-id.
Endpoints
Flavor / Image / Storage policy
| # | Action | Query params | Body | Purpose |
|---|---|---|---|---|
| 1 | gpu-vm.flavor.list | search, region | {} | List GPU flavors |
| 2 | gpu-vm.image.list | — | {} | List OS images |
| 3 | gpu-vm.storagepolicy.listoption | flavor_id | {} | List storage policies |
Virtual machine
| # | Action | Query params | Body | Purpose |
|---|---|---|---|---|
| 4 | gpu-vm.list | search, region | {} | List VMs |
| 5 | gpu-vm.listoption | region, storage_type | {} | List VMs as options (for attaching storage) |
| 6 | gpu-vm.get | — | { virtual_machine_id } | VM details |
| 7 | gpu-vm.create | — | See below | Create a VM |
| 8 | gpu-vm.start | region | { virtual_machine_id } | Power on |
| 9 | gpu-vm.stop | — | { virtual_machine_id } | Power off |
| 10 | gpu-vm.reboot | — | { virtual_machine_id } | Reboot |
| 11 | gpu-vm.delete | — | { virtual_machine_id } | Delete VM |
| 12 | gpu-vm.monitor | virtual_machine_id | { virtual_machine_id } | Get monitoring URL |
| 13 | gpu-vm.console | — | { virtual_machine_id } | Get console URL |
| 14 | gpu-vm.calculateprice | — | { flavor_id, storage_items[] } | Calculate VM price |
| 15 | gpu-vm.port.edit.exposedports | — | { virtual_machine_id, ports: number[] } | Update exposed ports |
| 16 | gpu-vm.securitygroup.listbyvm | search, region | { virtual_machine_id } | Security groups applied to a VM |
Storage (disk)
| # | Action | Query params | Body | Purpose |
|---|---|---|---|---|
| 17 | gpu-vm.storage.list | search, region, volume_type, storage_tier, status | {} | List storage disks |
| 18 | gpu-vm.storage.listbyvm | search, region | { virtual_machine_id } | Storage disks attached to a VM |
| 19 | gpu-vm.storage.get | — | { storage_id } | Storage disk details |
| 20 | gpu-vm.storage.checkname | name | { name } | Check for duplicate name |
| 21 | gpu-vm.storage.create | — | See below | Create a storage disk |
| 22 | gpu-vm.storage.edit | — | See below | Edit a storage disk |
| 23 | gpu-vm.storage.attach | — | { storage_id, virtual_machine_id } | Attach storage to a VM |
| 24 | gpu-vm.storage.detach | — | { storage_id } | Detach storage from a VM |
| 25 | gpu-vm.storage.delete | — | { storage_id } | Delete a storage disk |
| 26 | gpu-vm.storage.calculateprice | — | { type, quantity } | Calculate storage price |
Security group
| # | Action | Query params | Body | Purpose |
|---|---|---|---|---|
| 27 | gpu-vm.securitygroup.list | search, region | {} | List security groups |
| 28 | gpu-vm.securitygroup.listoption | search, region | {} | List security groups as options |
| 29 | gpu-vm.securitygroup.checkname | sg_name | { sg_name } | Check for duplicate name |
| 30 | gpu-vm.securitygroup.get | security_group_id | { security_group_id } | Security group details (including rules) |
| 31 | gpu-vm.securitygroup.create | — | See below | Create a security group |
| 32 | gpu-vm.securitygroup.rule.edit | — | See below | Edit rules / name / apply_to |
| 33 | gpu-vm.securitygroup.delete | — | { security_group_id } | Delete a security group |
Request bodies
7. gpu-vm.create
All fields are optional depending on type.
{
"name": "my-vm",
"flavor_id": "...",
"image_id": "...",
"expose_ports": [22, 8888],
"security_group_id": "...",
"storage_type": "NVME | BLOCK",
"nvme_storages": [{ "id": "", "name": "", "storage_policy_id": "", "storage_policy_name": "", "disk_size_gb": 100, "description": "", "price": 0, "price_text": "" }],
"block_storages": [{ "id": "", "volume_type": "", "storage_policy_id": "", "storage_policy_name": "", "disk_size_gb": 100, "name": "", "price": 0, "price_text": "", "is_boot": true }],
"boot_volume": { "name": "boot", "storage_policy_id": "...", "disk_size_gb": 100 },
"data_volumes": [{ "name": "data", "storage_policy_id": "...", "disk_size_gb": 500 }],
"authentication_type": "SSH_KEY | PASSWORD",
"ssh_public_key": "ssh-ed25519 AAAA...",
"root_username": "root",
"root_password": "",
"cloud_init_script": "",
"billing_plan": "PAYG"
}
Response: { id, name, gpu_id, gpu_flavor_id, image_id, public_ip, private_ip, status, created_at }.
14. gpu-vm.calculateprice
{ "flavor_id": "...", "storage_items": [{ "storage_type": "BLOCK", "storage_policy_id": "...", "disk_size_gb": 100 }] }
Response: { total_credit, total_currency, total_unit, credit_items: [{ sku, currency, credit, unit }] }.
15. gpu-vm.port.edit.exposedports
Response: { ports_added: number[], ports_deleted: number[] }.
21. gpu-vm.storage.create
{ "name": "disk-1", "virtual_machine_id": null, "storage_type": "...", "storage_policy_id": "...", "disk_size_gb": 100 }
22. gpu-vm.storage.edit
{ "storage_id": "...", "storage_policy_id": "...", "disk_size_gb": 200 }
23 / 24. gpu-vm.storage.attach / gpu-vm.storage.detach
Response: { ports_added, ports_deleted }.
26. gpu-vm.storage.calculateprice
Response: { name, quantity, credit, credit_unit, credit_currency }.
31. gpu-vm.securitygroup.create / 32. gpu-vm.securitygroup.rule.edit
Add security_group_id to the body when editing.
{
"name": "sg-1",
"apply_to": ["<vm_id>"],
"inbound_rules": [{ "id": "", "type": "", "protocol": "TCP", "ip_type": "", "sources": ["0.0.0.0/0"], "port_ranges": ["22"], "action": "", "description": "" }],
"outbound_rules": [{ "id": "", "type": "", "protocol": "TCP", "ip_type": "", "destinations": ["0.0.0.0/0"], "port_ranges": ["All"], "action": "", "description": "" }]
}
Response: { id, name, display_name, status }.
Responses
| Action | Response |
|---|---|
gpu-vm.flavor.list | [{ id, name, description, type, gpu_id, gpu_name, info{cpu, ram, gpu, gpu_ram, storage_policy, volume_capacity, nvme_volume_type}, price_info{currency, value, unit}, display_order, is_nvme, is_nvme_available, is_block_storage_available, supported_storage_types[], is_available, images[{id, display_name}], region }] |
gpu-vm.image.list | [{ id, catalog, template, name, display_name, description, tooltip_data, logo, support_flavor_gpu[], min_boot_size_gb, region }] |
gpu-vm.storagepolicy.listoption | [{ id, name, storage_type, free_storage_size_gb, price_info, setting_data{free_block_storage_size_gb}, region }] |
gpu-vm.list | [{ id, name, os_image, root_disk, disk_type, billing_plan, flavor_type, flavor, status, created_at, created_by, updated_at, public_ip, private_ip, ports[], region }] |
gpu-vm.listoption | [{ id, name, region, vpc_id, status }] |
gpu-vm.get | { id, name, image_name, image_display_name, flavor_id, gpu_flavor_id, flavor, flavor_type, storage_type, storage_capacity, created_at, created_by, updated_at, updated_by, private_ip, public_ip, user_name, ssh_key, status, billing_plan, ports[{port, status}], region } |
gpu-vm.start / stop / reboot | VirtualMachineDetail (same as gpu-vm.get) |
gpu-vm.monitor | { url } |
gpu-vm.console | { console_url } |
gpu-vm.securitygroup.listbyvm | [{ id, name, display_name, status, created_at, updated_at }] |
gpu-vm.storage.list / listbyvm | [{ id, name, volume_type, storage_type, storage_policy_id, storage_policy_name, disk_size_gb, region, vpc_id, attach_to{id, name}, status, created_at, created_by, updated_at, updated_by }] |
gpu-vm.storage.get | { id, user_id, virtual_machine_id, name, volume_type, storage_type, storage_policy_id, disk_size_gb, created_at, created_by, updated_at, updated_by } |
gpu-vm.storage.create / edit | { id, name, virtual_machine_id, storage_type, storage_policy_id, disk_size_gb } |
gpu-vm.storage.checkname, gpu-vm.securitygroup.checkname | { is_duplicate: boolean } |
gpu-vm.securitygroup.list | [{ id, name, display_name, apply_to[{id, name}], is_default, status, created_at, created_by, updated_at, total_of_rule, total_of_virtual_machine, region }] |
gpu-vm.securitygroup.listoption | [{ id, name, display_name, region, is_default }] |
gpu-vm.securitygroup.get | { id, name, region, display_name, apply_to[], is_default, created_at, created_by, inbound_rules[], outbound_rules[], status } |
gpu-vm.delete, gpu-vm.storage.delete | No response body used. |
Error codes
Error format
On error, HTTP status ≠ 2xx and the body has the following shape:
{ "code": "GPU-VM-VM-00001", "message": "...", "params": { "port": 80 }, "role_based": false }
role_based: true— the error message depends on the caller's role (MANAGEMENT/WS_ADMIN/MEMBER).- HTTP 401 — the client logs out and redirects to the login page.
Common error codes (gateway / BFF / billing)
| Code | Meaning |
|---|---|
INSUFFICIENT_BALANCE | Insufficient credits. Role MANAGEMENT auto-opens the top-up modal; other roles are prompted to contact the owner. |
INSUFFICIENT_PERMISSIONS | The caller does not have permission to perform this action. |
EQ-RESOURCE-SYSTEM-LIMIT | Resource quota reached (params.name). |
BFF-CREATING-CONCURRENCY | Another resource is being created in this workspace/service. Wait for it to complete and try again. |
route_not_found | Endpoint does not exist. |
method_not_allowed | Wrong method. Only POST is accepted. |
request_too_large | Body exceeds 64 KB. |
invalid_token | Token is invalid or expired. |
gateway_internal_error | Internal gateway error. |
upstream_unavailable | Backend service is temporarily unavailable. |
gateway_timeout | Backend service timed out. |
GPU VM error codes
Common (GPU-VM-COMMON-*)
| Code | Message |
|---|---|
GPU-VM-COMMON-0001 | Something went wrong. Please try again later. |
GPU-VM-COMMON-0002 | Missing required headers: {{headers}} |
GPU-VM-COMMON-0003 | Invalid UUID format for header {{headerName}}: {{headerValue}} |
GPU-VM-COMMON-0004 | Invalid role value in X-Portal-Roles header: {{role}} |
GPU-VM-COMMON-0005 | Workspace admin access required. |
GPU-VM-COMMON-0006 | Workspace member access required. |
GPU-VM-COMMON-0007 | Request validation error. |
Virtual machine (GPU-VM-VM-*)
| Code | Message |
|---|---|
GPU-VM-VM-00001 | Virtual machine not found. |
GPU-VM-VM-00002 | Virtual machine status is invalid. |
GPU-VM-VM-00003 | No available resources to create this VM. Please try a smaller flavor or contact FPT Support. |
GPU-VM-VM-00004 | The port is being deleted. Please try again later. |
GPU-VM-VM-00005 | Image not found. |
GPU-VM-VM-00006 | Flavor not found. |
GPU-VM-VM-00007 | Image is not supported. |
GPU-VM-VM-00008 | The selected VM no longer exists. Please refresh and try again. |
GPU-VM-VM-00009 | Virtual machine name is required. Please enter a valid name. |
GPU-VM-VM-00010 | Invalid name. Name limits up to 40 characters. Only letters, numbers, and hyphens are allowed. |
GPU-VM-VM-00011 | GPU flavor is required. |
GPU-VM-VM-00012 | OS image is required. |
GPU-VM-VM-00013 | Expose ports is required. |
GPU-VM-VM-00014 | Expose port {{port}} is invalid. |
GPU-VM-VM-00015 | Only one data volume is allowed. |
GPU-VM-VM-00016 | Authentication type is required. |
GPU-VM-VM-00017 | Authentication type is invalid. |
GPU-VM-VM-00018 | SSH public key is required. |
GPU-VM-VM-00019 | SSH public key is invalid format. |
GPU-VM-VM-00020 | Password is required. |
GPU-VM-VM-00021 | cloud_init_script is invalid. |
GPU-VM-VM-00022 | Billing plan is invalid. |
GPU-VM-VM-00023 | Port {{port}} is invalid. |
Security group (GPU-VM-SG-*)
| Code | Message |
|---|---|
GPU-VM-SG-00001 | Security group not found. |
GPU-VM-SG-00002 | The name already exists. Please enter a different one. |
GPU-VM-SG-00003 | Invalid virtual machine ID. |
GPU-VM-SG-00004 | Cannot delete the default security group. |
GPU-VM-SG-00005 | Please detach this security group from any virtual machines before deleting. |
GPU-VM-SG-00006 | Name is required. Please enter a valid name. |
GPU-VM-SG-00007 | Invalid name. Name limits up to 32 characters. Only letters, numbers, and hyphens are allowed. |
GPU-VM-SG-00008 | Duplicate rules. |
GPU-VM-SG-00009 | Rule type is required. |
GPU-VM-SG-00010 | Rule type is invalid. |
GPU-VM-SG-00011 | Rule protocol is required. |
GPU-VM-SG-00012 | Rule protocol is invalid. It must be one of: All, ICMP, TCP, UDP. |
GPU-VM-SG-00013 | Rule IP type is required. |
GPU-VM-SG-00014 | Rule IP type is invalid. Only IPv4 & IPv6 is supported. |
GPU-VM-SG-00015 | Rule IP type is invalid. Only IPv4 & IPv6 is supported for outbound rules. |
GPU-VM-SG-00016 | Rule source is required. |
GPU-VM-SG-00017 | Rule destination is required. |
GPU-VM-SG-00018 | Rule port range is required. |
GPU-VM-SG-00019 | Rule action is required. |
GPU-VM-SG-00020 | Rule action is invalid. |
GPU-VM-SG-00021 | Rule protocol or port range does not match the selected type. Rule type '{{ruleType}}' requires protocol '{{expectedProtocol}}' and port range '{{expectedPortRange}}', but got protocol '{{actualProtocol}}' and port range '{{actualPortRange}}'. |
GPU-VM-SG-00022 | Rule source is invalid: {{source}}. |
GPU-VM-SG-00023 | Rule destination is invalid: {{destination}}. |
GPU-VM-SG-00024 | Rule port range is invalid: {{port}}. |
GPU-VM-SG-00025 | Custom rule port range: cannot be 'All'. |
GPU-VM-SG-00026 | Rule description is invalid: {{description}}. |
Storage (GPU-VM-SR-*)
| Code | Message |
|---|---|
GPU-VM-SR-00001 | Storage disk not found. |
GPU-VM-SR-00002 | Storage policy not found. |
GPU-VM-SR-00003 | Storage policy is invalid. |
GPU-VM-SR-00004 | A volume with this name already exists in the region. |
GPU-VM-SR-00005 | Storage disk has not been detached yet. |
GPU-VM-SR-00006 | Another virtual machine has already been attached to this storage. |
GPU-VM-SR-00007 | Storage disk status is invalid for update. |
GPU-VM-SR-00008 | Storage disk status is invalid for attachment. |
GPU-VM-SR-00009 | Storage disk status is invalid for detachment. |
GPU-VM-SR-00010 | Storage disk status is invalid for deletion. |
GPU-VM-SR-00011 | Only data volume is allowed to update. |
GPU-VM-SR-00012 | Only block storage disks can be resized or changed to another storage tier. |
GPU-VM-SR-00013 | Only data volume is allowed to attach. |
GPU-VM-SR-00014 | Only data volume is allowed to detach. |
GPU-VM-SR-00015 | Only data volume is allowed to delete. |
GPU-VM-SR-00016 | The new capacity must be greater than current size. |
GPU-VM-SR-00017 | Boot storage size must be between {{minSizeGb}} GB and {{maxSizeGb}} GB. |
GPU-VM-SR-00018 | Data storage size must be between {{minSizeGb}} GB and {{maxSizeGb}} GB. |
GPU-VM-SR-00019 | Name is required. Please enter a valid name. |
GPU-VM-SR-00020 | Name limits up to {{maxLength}} characters. |
GPU-VM-SR-00021 | Only lowercase letters, numbers, and hyphens are allowed. Must start with a letter. |
GPU-VM-SR-00022 | Minimum capacity is {{minSizeGb}} GB, Maximum capacity is {{maxSizeGb}} GB. Please enter a valid number. |