Resources
Every resource of the platform API has an idiomatic client on ukc: ukc.instances, ukc.volumes, ukc.services, ukc.certificates, and ukc.users.
This page covers what they have in common.
Refs
Every operation on an existing resource takes a ref: { name } or { uuid }, never both.
Code
The API validates each identifier, so a name in the uuid filter fails with Invalid uuid '<name>'.
The ref makes you state which kind you hold, and the SDK sends only that field.
Handles
A single-resource operation returns a handle: a lazy reference to one resource in one metro. Await the handle to get the resource. Call an operation on the handle to get another handle.
Code
A handle sends nothing until you await it or chain onto it. Each step runs at most once, even when you await it many times.
What a chain costs
The number of requests depends on the ref and on the scope.
For get(ref).suspend():
| Ref and scope | Requests |
|---|---|
{ name, metro }, any scope | One: the suspend. The ref says where. |
{ name }, one metro in scope | One: the suspend. The scope says where. |
{ name }, many metros in scope | One concurrent read per metro to locate the resource, then the suspend in the metro that holds it. If more than one metro matches, the handle throws AmbiguousRefError. |
Where a handle landed
A handle reports where it landed.
A mutating step returns what the endpoint reports, so suspend() resolves to { uuid, name, state, previous_state }, not to a full instance.
Code
The direct form
Every method is also available directly, with a ref as the first argument.
ukc.instances.logs({ name: "web" }, { offset: -4096 }) is shorthand for ukc.instances.get({ name: "web" }).logs({ offset: -4096 }).
Update a resource
Write a patch object, and the SDK works out the operation for each property.
A value sets the property, null removes it, and an omitted or undefined property stays unchanged.
This follows JSON Merge Patch.
Code
Every property has a type, so memory_mb: "512" doesn't compile.
image takes the same string shorthand as create.
Merge and remove members
When a plain set isn't enough, stage the operations with edit() and send them as one request.
set replaces a property, add merges into it, and del removes members of it.
Code
null in del() removes the whole property: ukc.services.edit({ name: "web" }).del({ domains: null }).apply().
apply() returns a handle, so the chain continues:
Code
Both forms are one request.
Both also take a ref instead of a handle: ukc.instances.update({ name: "web" }, { memory_mb: 512 }) and ukc.instances.edit({ name: "web" }).
The API models an update as a list of { prop, op, value } triples, and the raw triples still work: update({ name: "web" }, [{ prop: "memory_mb", op: "set", value: 512 }]).
Methods
| Resource | Methods |
|---|---|
ukc.instances | create, get, each, list, update, edit, delete, start, stop, suspend, wait, metrics, history, logs |
ukc.volumes | create, get, each, list, update, edit, delete, attach, detach |
ukc.services | create, get, each, list, update, edit, delete |
ukc.certificates | create, get, each, list, update, delete |
ukc.users | quotas, quotasByUuid |
ukc.metro("fra").sandboxes | create, get, list. See Sandboxes. |
A handle adds the operations of its resource:
| Handle | Operations |
|---|---|
| Instance | refresh, start, stop, suspend, delete, update, edit, wait, logs, metrics, history |
| Volume | attach, detach, update, edit, delete |
| Service group | update, edit, delete |
The raw API
The idiomatic layer holds a raw client, and the raw client is one property away.
The raw layer mirrors the OpenAPI specification: one method per operationId, the response envelope untouched, and one metro per call.
The SDK covers both Unikraft Cloud APIs:
- Platform, per metro: instances, volumes, services, certificates, autoscale, and images.
Idiomatic at the top level, and raw under
ukc.api.platformand@unikraft/cloud/api/platform. - Control plane, global: the account, the metros, images, and self-hosted nodes.
Raw only, under
ukc.api.controlplaneand@unikraft/cloud/api/controlplane.
Code
Everything that the idiomatic layer doesn't cover is reachable this way: autoscale, the image registry, node information, and the whole control plane.
Code
Standalone raw clients
A raw client also works on its own, without the idiomatic layer:
Code
A raw client belongs to one metro.
It talks to its baseUrl, and one call can go elsewhere with { baseUrl }.
The fan-out across metros is the job of the idiomatic layer.