KoaVM
Guide pages

Guide · For administrators

API and integrations

API keys

In Settings › API › Create key name the key (e.g. "WHMCS"). The key, kvm_…, is shown only once: copy it right away. Each key acts as the administrator who created it; keep it on the billing server, never in the browser. Revoke it from the same page.

Calls go to https://vm.yourdomain.com/api/v1/… with the header Authorization: Bearer kvm_…. Limit: 600 requests per minute per key.

Resellers have their own keys too: they act only on their customers and VPSs, with their plans and nodes and within their limits.

Customers have another kind of key (the Team & API page of the customer area, since 0.13): it works on the panel API (/api/…), with the permissions of the chosen role, only on the customer's own resources. Customer keys don't work on /api/v1, and the keys of this page don't work on the panel API. See Customers and VPSs.

Main calls

CallWhat it does
GET /pingtests the key
GET /plans, GET /images, GET /locationsplans, systems (with type linux/windows, requirements and plans; ?plan_id= for those of one plan), nodes and zones
GET /appsapps to install on first boot: slug, systems, requirements, fields to fill in
GET /clients?email=…, POST /clientsfind or create a customer (with twofa: true when two-step verification is on)
DELETE /clients/{id}/2faremoves two-step verification from a customer who lost their phone (for support: closes their sessions and emails them; 409 if it is not on). With a reseller's key it works on their customers, not on the reseller
POST /vpscreate a VPS (with "no_ipv4": true and a private network, without public IPv4: see routers)
GET /vps/{id}, GET /vps?external_id=…VPS status
POST /vps/{id}/powerstart, stop, restart
POST /vps/{id}/suspend, /unsuspendsuspend (with a reason) and reactivate
POST /vps/{id}/planplan change (restart: true to apply it now); with extra and extra_disk_gb also extra resources and an additional disk
POST /vps/{id}/resourcescustom resources: vcpu, ram_mb, disk_gb (up only), net_mbit, traffic_gb; since 1.14 also the limits (see below)
GET/POST /vps/{id}/disks, PUT/DELETE /vps/{id}/disks/{disk}extra disks: list, add (size_gb, mount), grow, remove (?confirm=disk1)
PUT /vps/{id}/ipsextra IPs: {"count": 3} makes the VPS have exactly 3 (for billing)
POST /vps/{id}/ips, DELETE /vps/{id}/ips/{ip}adds extra IPs (count or ips), removes one
POST /vps/{id}/ips/{ip}/movemoves an extra IP to another VPS of the same client ({"to": id})
GET/PUT /vps/{id}/firewallVPS firewall: enabled and rules
PUT /vps/{id}/hahigh availability: protect ("" as the plan, "on", "off"), reserve_id (0 = chosen by the panel), priority (0–2); the status is in ha of GET /vps/{id}
POST /vps/{id}/disks/{disk}/detach, GET /volumes, POST /volumes/{id}/attachvolumes: detach a disk, list, attach to a VPS (vps_id, mount)
GET/POST /volumes/{id}/snapshots, POST …/{name}/restore, DELETE …/{name}volume snapshots
GET/POST /private-networks, POST /vps/{id}/private-networksprivate networks: list, create, connect (network_id or default: true)
GET/POST /vps/{id}/rescue, POST /vps/{id}/rescue/exitrescue mode: state, start (optional ssh_key or ssh_key_ids; the response contains the temporary root password), exit
POST /vps/{id}/password, /reinstallnew password (not for Windows), reinstall (image_id, also with app_id and app_options)
GET /vps/{id}/appapp status: step, error, address, user and password
GET /vps/{id}/usagemonthly traffic and disk
GET/POST /load-balancers, GET/PUT/DELETE /load-balancers/{id}load balancers: client_id, name, city, services, targets (VPS ids), external_id
GET/POST /dns/zones, GET/PUT/DELETE /dns/zones/{id}, POST /dns/zones/{id}/records, PUT/DELETE /dns/zones/{id}/records/{rid}, POST …/import, GET …/exportDNS: name, client_id, ttl, records (name, type, content, ttl, priority), external_id; zone file import (text, replace)
GET/POST /routers, GET/PUT/DELETE /routers/{id}routers: client_id, name, city, network_id, forwards (protocol, public_port, vps_id, target_port, note), external_id
GET/PUT/DELETE /clients/{id}/quota, GET /usagethe customer's self-service package and the month's hourly usage
POST /vps/{id}/login-linksign-in link for the customer
DELETE /vps/{id}delete

Creation example:

curl -X POST https://vm.yourdomain.com/api/v1/vps \
  -H "Authorization: Bearer kvm_…" -H "Content-Type: application/json" \
  -d '{"client":{"email":"mario@example.com","name":"Mario Rossi"},"plan_id":1,
       "image":"debian/12/cloud","hostname":"web1.example.com","external_id":"order-1001"}'

To sell extra resources add "extra": {"vcpu": 1, "ram_mb": 2048, "disk_gb": 20} (added to the plan), "extra_disk_gb": 100 for an additional disk mounted on /mnt/disco1 and "extra_ips": 2 for two extra IPs taken from the node's routed blocks (listed in the VPS's extra_ips).

Disk and CPU limits (1.14). The plans of GET /plans and the VPSs of GET /vps/{id} have disk_read_mbs, disk_write_mbs (MB/s), disk_read_iops, disk_write_iops (operations per second), cpu_max_pct (maximum use of each vCPU in %) and cpu_priority (normal, low, high); 0 = no limit. MB/s and operations per second of the same direction apply together, for every disk. On VPSs they are the limits in force and limits_custom says whether they are custom. With POST /vps/{id}/resources you change them for one VPS (-1 = as in the plan: on either field of a direction it puts the whole direction back as in the plan; the fields you do not send stay as they are) or put them all back as in the plan with "limits_as_plan": true. Example: {"disk_write_iops": 2000, "cpu_max_pct": 50}. A plan change with POST /vps/{id}/plan puts back the limits of the new plan. Provider VPSs have no limits.

For a preinstalled app add "app": "wordpress" (the slug from GET /apps) and, for cPanel, Plesk and DirectAdmin, "app_options": {"accept": "1", "license": "…"}. For Windows VPSs the login user is Administrator (the VPS login_user field).

With external_id (or the Idempotency-Key header) the same request repeated does not create duplicates: it returns the VPS already created. The response contains the root password and, for a new customer, their password.

One-click sign-in

POST /vps/{id}/login-link returns a single-use link, valid for 2 minutes, that opens the VPS page already signed in. Once used it expires: the customer sees the sign-in page with a notice.

The link doesn't ask for two-step verification, even when it is on or required: billing, which creates it with the API key, has already authenticated the customer. API keys don't use two-step verification.

With a reseller's key, sign-in links (/clients/{id}/login-link, /vps/{id}/login-link) and packages (/clients/{id}/quota) work for their customers and their VPSs, never for the reseller themselves (since 1.13): a person in their team may have created the key.

WHMCS

Download the module from Settings › API › Download the WHMCS module and copy modules/servers/koavm into the WHMCS folder. Then:

  1. Setup › Products/Services › Servers › Add New Server: panel hostname, module KoaVM, the kvm_… key as password, Secure on. Test Connection must answer "successful".
  2. In the product (Server/VPS type), Module Settings tab: KoaVM module, plan, default operating system, location (empty = automatic).
  3. Optional: configurable options Operating System and Location, custom field SSH Key.
  4. To sell extra resources: configurable options Extra RAM (GB), Extra vCPU, Extra disk space (GB), Additional disk (GB) and Additional IPs (they go in the service's assigned IPs).
  5. For the private network: Yes/No option Private network (module 1.3.0): the VPS goes on the customer's default private network.
  6. For preinstalled apps: the product's Applicazione setting or the configurable option Application with values like wordpress|WordPress (module 1.4.0); for Windows VPSs the service user is Administrator.
  7. To sell a self-service package instead of a VPS: Tipo = pacchetto and the package limits in the product settings (module 1.5.0); see Self-service and hourly usage.

The module handles creation, suspension, reactivation, termination, package change, password, start and stop, one-click sign-in to the panel and disk and traffic usage. The README in the zip explains everything in detail.

The disk and CPU limits (1.14) come from the product's KoaVM plan: to sell them a plan with limits is enough, the module has no new settings.

KoaBilling

In KoaBilling add the KoaVM provider with the panel address and the API key. In the product: plan = KoaVM plan id, region = node or zone id (empty = automatic), image = system (e.g. debian/12/cloud).

For self-service packages and hourly billing KoaBilling uses PUT /clients/{id}/quota and GET /usage?month=YYYY-MM: see Self-service and hourly usage.