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
| Call | What it does |
|---|---|
GET /ping | tests the key |
GET /plans, GET /images, GET /locations | plans, systems (with type linux/windows, requirements and plans; ?plan_id= for those of one plan), nodes and zones |
GET /apps | apps to install on first boot: slug, systems, requirements, fields to fill in |
GET /clients?email=…, POST /clients | find or create a customer (with twofa: true when two-step verification is on) |
DELETE /clients/{id}/2fa | removes 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 /vps | create 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}/power | start, stop, restart |
POST /vps/{id}/suspend, /unsuspend | suspend (with a reason) and reactivate |
POST /vps/{id}/plan | plan change (restart: true to apply it now); with extra and extra_disk_gb also extra resources and an additional disk |
POST /vps/{id}/resources | custom 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}/ips | extra 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}/move | moves an extra IP to another VPS of the same client ({"to": id}) |
GET/PUT /vps/{id}/firewall | VPS firewall: enabled and rules |
PUT /vps/{id}/ha | high 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}/attach | volumes: 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-networks | private networks: list, create, connect (network_id or default: true) |
GET/POST /vps/{id}/rescue, POST /vps/{id}/rescue/exit | rescue mode: state, start (optional ssh_key or ssh_key_ids; the response contains the temporary root password), exit |
POST /vps/{id}/password, /reinstall | new password (not for Windows), reinstall (image_id, also with app_id and app_options) |
GET /vps/{id}/app | app status: step, error, address, user and password |
GET /vps/{id}/usage | monthly 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 …/export | DNS: 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 /usage | the customer's self-service package and the month's hourly usage |
POST /vps/{id}/login-link | sign-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:
- Setup › Products/Services › Servers › Add New Server: panel hostname, module KoaVM, the
kvm_…key as password, Secure on. Test Connection must answer "successful". - In the product (Server/VPS type), Module Settings tab: KoaVM module, plan, default operating system, location (empty = automatic).
- Optional: configurable options
Operating SystemandLocation, custom fieldSSH Key. - To sell extra resources: configurable options
Extra RAM (GB),Extra vCPU,Extra disk space (GB),Additional disk (GB)andAdditional IPs(they go in the service's assigned IPs). - For the private network: Yes/No option
Private network(module 1.3.0): the VPS goes on the customer's default private network. - For preinstalled apps: the product's Applicazione setting or the configurable option
Applicationwith values likewordpress|WordPress(module 1.4.0); for Windows VPSs the service user isAdministrator. - To sell a self-service package instead of a VPS: Tipo =
pacchettoand 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.