Computers

Create a computer

Builds a computer and, unless you pass start: false, starts it. The response carries the desktop credentials, so creating and connecting is one call. Every field has a default, so {} creates a computer from the default template; a request with no body at all is a 400.

A create that wants a running computer may be answered from the warm pool, in which case it returns in about the time the HTTP round trip takes. The pool stocks the shapes in GET /sizes, so naming a size is the likeliest way to get that answer. A cold create is slower (the guest is booted before the answer) and comes back running, or as {computer, start_error} with the computer stopped. On a host that is low on disk space, a create the warm pool would have answered is refused with 503 and nothing is created, while the pool there holds a ready computer of that shape the host has not paused, or holds only stock being held for disk-space recovery (that create answers the recovery 503); it does not fall back to a cold create then. The host confirms it built nothing, so the attempt is not counted against your plan; a host that cannot confirm it, one running older software, leaves it counted (see the paragraph on a create whose outcome was not heard, below). Otherwise — the host has paused that stock, as it pauses all of it when space is critically low, or holds none — the create is built cold and its start is refused for the same lack of space: the answer is 201 with {computer, start_error}, and that computer exists, is stopped and counts against your plan. Either way no computer starts on that host until space there has been freed, so wait before sending it again rather than retrying it in a loop.

A custom image whose verified holders have no capacity is copied on demand. During preparation, 409 with code: template_image_preparing guarantees no computer was created. Progress and errors are in preparation; repeat this request after Retry-After seconds with the returned template_transfer token to preserve the exact template and build across retries. Each retry rechecks quota and capacity. While the copy is under way it also carries reason: "contention"; a preparation that failed carries none, and preparation.error says why, unless what stopped it clears by itself (its source busy sending another image, no hypervisor yet with room for the image and the computer, or the destination already receiving it, full or not answering), when it carries contention too.

A CREATE WHOSE OUTCOME WAS NOT HEARD STILL COUNTS AGAINST YOUR PLAN. A create, or a clone, that reached a host and whose answer never arrived, or was a 5xx that cannot rule out a computer was built, is counted toward your plan’s limits from then on, with no time limit, until a listing of its host shows the computer it built. If it built nothing, it stays counted until that host is taken out of service or registered again. A host that refuses a create before building anything (a 503 from a host with no room left, for example) confirms it, and that attempt is not counted; one running older software cannot, and its 5xx is counted like any other. GET /account does not include these, so a later 402 can name more than that read shows.

The computer goes in the workspace named by workspace_id, or, without it, in the API key’s: a key scoped to a workspace creates in that workspace, and an account-wide key or a dashboard session in none.

A create’s response carries a Server-Timing header for diagnostics: name;dur=<ms> entries, the control plane’s first (cp-total, cp-lane, cp-admit, cp-place, cp-forward, and for a create bound to secrets cp-start and cp-readback), then the compute node’s (total, decode, create, copy, start, admit, prepare, qemu, load, cont, identity, with identity split into id-thaw, id-clock, id-nic, id-script, id-password, id-link and id-screen, and deliver). For a create bound to secrets the node’s start and the phases inside it come from the start that follows the create. A phase the create did not reach is left out. It is for diagnostics only: the set of names may change, so do not build logic on it.

Requires the member role or higher.

post/computers

Request

  • Base URL: https://app.mandala.computer/api/v1
  • URL: https://app.mandala.computer/api/v1/computers
  • Auth: HTTP bearer

Headers

Idempotency-Keystring

Optional: a key of your choosing, 1 to 255 printable ASCII characters with no spaces (a UUID is ideal), that makes this call safe to send again after a lost answer. The call and its operation are recorded BEFORE it is carried out, so GET /operations?idempotency_key= finds it however the connection ended. For 24 hours, the same key with the byte-identical request (method, path, query and body, from a credential of the same scope) is not carried out again: it answers 409 idempotency_in_progress while the first is running, and the original answer — status and body, with Idempotent-Replayed: true — once it has finished. An answer too large to keep (over 1 MiB) is replayed instead as a 200 carrying {operation_id, operation}, also with Idempotent-Replayed: true: operation is the call’s operation, or null when there is none to show. Keys are kept per scope: a key used by a workspace's credential and the same key used by another workspace's, or by an account-wide one, are different keys, and neither is refused because of the other. A replayed body omits the desktop credentials the original carried (vnc, with its tokens and URLs): read the computer (GET /computers/{id}) for them. The same key on a different request is a 422 with code: "idempotency_key_reused", and a malformed key (empty, too long, outside printable ASCII, or the header sent twice) a 400 with code: "idempotency_key_invalid"; neither does anything. A call refused with a 4xx that did nothing releases its key, so it may be sent again under the same one. The exception is a delete whose 4xx says the computer was deleted — computer_deleted: true, or a purge result beside computer_deleted: false (it was deleted, then listed again): it happened, so its key keeps that answer and its operation is succeeded. Except a 409 with reason: "contention" whose purge deleted, queued and left in doubt nothing (the computer was already gone and copies in use refused the purge): nothing happened, so its key is released and the same request may be sent again under it. With computer_deleted: null, or false where the platform cannot confirm the computer was left in place, it is an unknown outcome: its key answers 409 idempotency_in_progress until the platform gives up on it, then 409 idempotency_outcome_unknown. A 5xx answer that names an operation_id is an unknown outcome too: that is the operation reserved for it. From then on the same key answers 409 idempotency_outcome_unknown, naming that operation (not idempotency_in_progress): read the computer, or the operation. The operation stays pending until the platform gives up on it; if it never learns how the call ended, it becomes failed with error.code: "lost". Some 5xx answers are refusals given before the call was sent anywhere — the platform could not check the account’s usage, or find a host for the call, for example — and some are a create or clone the host confirms it refused before building anything, such as a 503 from a host with no room left, and some are a start, restore or suspend the host confirms it refused before changing anything (a sealed session whose key could not be opened or whose transport failed first; on a suspend, suspend_outcome: "not_started"). Those name no operation_id: nothing was done, so the key is released as a 4xx refusal’s is, and the same call may be sent again under the same key. A host running older software cannot confirm such a refusal, so its 5xx is an unknown outcome like any other. A 5xx without an operation_id is not proof that nothing was done on its own: a call that records no operation (a PATCH that does not resize) names none, and neither does one whose operation could not be recorded. Sending the same call again under the same key is safe after any 5xx: it is carried out if its key was released, and answered 409 idempotency_outcome_unknown if not.

Request body

namestring

Defaults to computer. Cut to 64 characters, with control characters turned into spaces and the ends trimmed. A name left empty by that gets the default too.

workspace_idstring

The workspace to create the computer in — an id from GET /workspaces. Its secrets and an egress_proxy’s credentials_secret_id are then named from that workspace’s scope: its own secrets and the account-wide ones. Left out or null, the computer goes in the key’s workspace, or in none for an account-wide key. A workspace this key cannot reach — another account’s, one that does not exist, or any but its own for a key scoped to a workspace — is a 404, and nothing is created.

template_transferstring

Token returned by a template_image_preparing 409. Retry the same create with this token after Retry-After seconds to preserve its template version and exact image. Progress and errors are returned in preparation. This is not a create idempotency key; stop retrying after success. A token that matches no preparation for this account and template is a 404.

sizestring

A named size from GET /sizes — the fast path, since these are the shapes hosts keep pre-booted. Sets the template and the three numbers together, so it cannot be combined with template, cpu, ram_mb or disk_gb.

templatestring

From GET /templates — either the short name or the pinned ref (system/base@1.2.0). Defaults to base.

The two differ in what happens when the name is wrong. A short name that is none of the templates we publish falls back to the default template — except while a host is missing from the catalogue, as X-GC-Incomplete on GET /templates shows. The name may then be one only that host has, so rather than build the default in its place the create is refused with a 503 before it is sent anywhere: nothing is done, no operation_id is named, and its Idempotency-Key is released. Send it again shortly. A size counts as the short name of its template here. A ref, a short name of one of the templates we publish that GET /templates still lists, and a create with neither template nor size are not affected by this. A ref that names nothing is refused with a 400: one that is not a well-formed ref, or a version you retired, says so and lists nothing; a version that does not exist, of a name with versions your plan can launch, lists those versions; and any other lists the templates your plan can launch. The one exception is a system/ ref while a host is missing from the catalogue: it may be one only that host has, so it is answered with a 503 instead, and is worth sending again shortly. If you would rather be told than guessed at, send the ref.

A TEMPLATE YOU PUBLISHED IS NAMED BY ITS REF AND ONLY BY ITS REF. The short form belongs to the templates we publish, so POST /templates cannot change what an existing create builds. namespace/name without a version means the newest published version, resolved once — the computer is pinned to it, and publishing again afterwards does not reach back into a machine that is already building.

cpuinteger

Cores. Defaults to the template’s. A whole number of at least 1, or the request is a 400 — except beside size, where 0 counts as left out.

ram_mbinteger

Defaults to the template’s. A whole number of at least 1, or the request is a 400 — except beside size, where 0 counts as left out.

disk_gbinteger

The template’s disk is a FLOOR, not a default: a smaller number is raised to it silently, and it is the raised figure your plan is charged for — so asking for less than the template needs can be refused 402 against a pool you did not think you were spending. A computer’s disk is an overlay over the template’s image and cannot be smaller than it. Read disk_gb on GET /templates to know the floor before you send one. A whole number of at least 1, or the request is a 400 — except beside size, where 0 counts as left out.

startboolean

Start it once built. Defaults to true.

resolutionstring

WIDTHxHEIGHTxDEPTH or WIDTHxHEIGHT, e.g. 1920x1080x24: 640x480 to 3840x2160, both even, depth 16, 24 or 32 (24 when left out); anything else is a 400. Defaults to 1280x800x24. Create-time only — there is no route that changes it later.

Response

The computer, with its desktop credentials.

OR

Changes

No recorded changes to this operation across all 1 revision of this API.