Resources
Get Service Instance FiveM Live Info
A FiveM service's live info: hostname, gametype, map, players connected and the slot count, and the player list (id, name, ping only; never an IP or identifier). Read server-side from the FXServer's own dynamic.json and players.json on the service's primary allocation. Always answers 200; status carries every reason there is nothing to show (not_configured when the product does not offer the panel, no_address, offline, parse_error, error) and the panel renders each as a state. ^N colour codes are stripped. 404 for an instance with no external access, or belonging to somebody else.
path Parameters
idGet Service Instance FiveM Live Info › Responses
The live info, or a degraded status when it could not be read
Empty unless status is ok.
Present only when status is ok.
Get Service Instance Minecraft Players
The Minecraft player roster: who is online, who is an operator, and who is banned, fused server-side from RCON list and the two files a Minecraft server itself keeps (ops.json, banned-players.json) -- never a client-side join of three payloads. Always answers 200; status carries every reason the roster could not be produced (not_configured for a service that is not Minecraft or predates the RCON password this needs, server_offline, auth_failed, unreachable, timeout, protocol_error, parse_error), and the panel should render each as a state rather than an error banner. ops_unavailable and banned_unavailable degrade independently: a roster missing its ban list is still a roster, one missing its online list is not (that case is the status field instead). ?include=gamemode,position opts the online players into their current game mode and their dimension and coordinates (one RCON round trip per player each, so the slow path stays opt-in); a player the server will not answer for simply has the field absent, and an unknown include value is a 400. 404 for an instance with no console at all, or belonging to somebody else.
path Parameters
idquery Parameters
includeComma-separated opt-in enrichments of the online players:
gamemode (each player's current game mode) and position
(dimension and coordinates). Each costs one RCON round trip per
online player, so ask only for what the panel shows.
Comma-separated opt-in enrichments of the online players:
gamemode (each player's current game mode) and position
(dimension and coordinates). Each costs one RCON round trip per
online player, so ask only for what the panel shows.
Get Service Instance Minecraft Players › Responses
The fused roster, or a degraded status when it could not be read
Empty unless status is ok.
banned_unavailableSame meaning as ops_unavailable, for banned-players.json.
Empty unless status is ok.
Empty unless status is ok.
ops_unavailableTrue when ops.json could not be read or parsed. ops is then
empty, but that does not mean nobody is an operator -- it means this
answer cannot say.
partial_list_formatTrue when /list's reply did not match the vanilla format and had to
be parsed permissively (parser::parse_list's tier 2). The roster is
still usable; this is a hint that the counts may be approximate on a
heavily modded server.
Every outcome a read or a write can answer with, folded into one status
so a client renders a match rather than branching on HTTP status codes
that are all 200. Ok is the only variant the roster fields or the
action actually succeeding are meaningful under.
max_playersExecute Service Instance Minecraft Player Action
Runs one of the nine Minecraft player-management verbs (kick, ban, pardon, op, deop, gamemode, whisper, give, broadcast) over RCON. Every field is validated before anything reaches the server -- a malformed name, item id or message is a 400 naming which -- and a request that passes validation still answers 200 with a status field for every way running it could fail (the server is offline, RCON auth failed, the command timed out, or the server's own reply indicates the verb was not understood, which unsupported_by_server covers separately from every other status). Gated the same as attaching to this workload's console: an organization Owner or Admin, or the personal organization's owner. Every successful call is audited under a per-verb action name; message bodies (a kick or ban reason, a whisper, a broadcast) are never written to the audit log verbatim, only their length or whether one was given.
path Parameters
idExecute Service Instance Minecraft Player Action › Request Body
Decision Table
| Variant | Matching Criteria |
|---|---|
| type = object · requires: kind, name | |
| type = object · requires: kind, name | |
| type = object · requires: kind, name | |
| type = object · requires: kind, name | |
| type = object · requires: kind, name | |
| type = object · requires: kind, name, mode | |
| type = object · requires: kind, name, message | |
| type = object · requires: kind, name, item +1 more | |
| type = object · requires: kind, message |
kindnamereasonExecute Service Instance Minecraft Player Action › Responses
The verb's outcome, as a status
Every outcome a read or a write can answer with, folded into one status
so a client renders a match rather than branching on HTTP status codes
that are all 200. Ok is the only variant the roster fields or the
action actually succeeding are meaningful under.
List Subscription Resources
Lists the resources provisioned for one subscription in any organization the caller may see (design doc §44.2). An empty list is normal -- a subscription may have zero, one, or many resources (design doc §8.1); at most one resource is ever marked is_declared_primary, and none may be. When primary_role_is_inconsistent is true, two resources both satisfied the primary rule -- a data fault, never a legitimate state -- so no resource is marked and a consumer should surface the inconsistency rather than render it as an absent primary.
path Parameters
idList Subscription Resources › Responses
Resources
primary_role_is_inconsistenttrue when two live resources both satisfy the primary rule, which
A2-S9b made a hard error because it is never a legitimate state
(design doc §9.1).
When set, every is_declared_primary in data is false -- the
resolver refuses to guess between them -- and a consumer should say so
rather than render "no main resource", which is indistinguishable from
a subscription that legitimately has none.
It is a field rather than an error because this is a read-only
display surface and failing the whole response helps nobody. It is a
field rather than a log line because a silent degrade would make the
screen most likely to reveal the corruption the screen that hides it
(design doc §50).
The running service these resources belong to, carrying the name and slug the customer refers to it by. Included here rather than fetched separately because this read already resolves the instance to find the resources at all.
List Service Instance Resources
The live resources of one service (id, kind, role, status, hidden, and whether it is the product's declared primary): the ids the console, files, logs and metrics routes are addressed by. Open to everyone who may View the service: its organization's members and a per-service share holder, whose answer carries nothing about the subscription or its billing. 404 for anyone else.
path Parameters
idList Service Instance Resources › Responses
The service's resources
primary_role_is_inconsistenttrue when two live resources both satisfied the primary rule (a data fault); then no
resource is marked is_declared_primary.
Reinstall VPS
Reinstalls a VPS onto the operating system osImage (an id from GET /api/v2/catalog/products/{id}/operating-systems; the image already installed is allowed). Erases all data on the disk and cannot be undone: confirm must be true, and is required rather than defaulted so a request that lost it is a 400 and not a wipe.
Only a virtual machine of a VPS service can be reinstalled; any other resource is a 422. An image that is disabled, or whose minimum CPU, memory or storage this VPS does not meet, is a 400. So is an image whose monthly fee differs from the installed one: a reinstall cannot change what the subscription costs, so such an image needs a new order. The service's subscription must be serviceable, as for reprovisioning.
Answers 202 with an operation id. The rebuild runs on the durable reprovision queue, waits its turn behind any backup, restore or deployment holding this service, and survives a kernel restart. When it finishes the machine is down with its old credentials cleared: answer the service's vm_access setup step with a new administrator account and that write boots the fresh install. Public endpoints survive. Requires the same access as changing the service (orders.manage for an API token).
path Parameters
idresource_idReinstall VPS › Request Body
confirmMust be true. Reinstalling erases all data on the disk and cannot
be undone; the client is expected to have shown that to the person
before sending it.
os_imageThe operating system to install: the id of one entry of
GET /api/v2/catalog/products/{id}/operating-systems. May be the
image already installed.
Reinstall VPS › Responses
The queued rebuild's operation id, for polling its status
operation_idThe queued rebuild. Poll
GET /api/v2/service-instances/{id}/operations/{operation_id}.
os_imageThe operating system the machine will be rebuilt with.
resource_idservice_instance_idList Service Instance Backups
Every on-demand backup of this volume, newest first. maxBackups is the ceiling a create is refused against, published here so a panel never holds it as a literal. These are the customer's own snapshots; the platform's disaster-recovery backups run on a separate mechanism and never appear here. 404 for a resource that is not this volume, for a volume belonging to somebody else, and for a service whose product has no storage, which are deliberately the same answer.
path Parameters
resource_ididList Service Instance Backups › Responses
This volume's backups, newest first
max_backupsThe ceiling POST .../backups is refused against, published here so
a panel never holds it as a literal.
Create Service Instance Backup
Starts a snapshot backup of this volume. Runs in the background: the row this creates appears in the listing immediately with status: "creating" and becomes restorable once it reaches status: "ready". Refused with a quota error once this volume already holds maxBackups, and with a conflict while another backup or restore is already in progress for this volume. Refused entirely on a cluster that does not support volume snapshots. 404 for a resource that is not this volume and for one belonging to somebody else.
path Parameters
resource_ididCreate Service Instance Backup › Request Body
nameOptional label. Kernel fills in a timestamped default
("Backup 2026-09-10 14:35") when this is absent, null, or blank.
Create Service Instance Backup › Responses
Backup started; poll the listing for its progress
Delete Service Instance Backup
Deletes one backup and its underlying snapshot. Refused while the backup is still creating or restoring -- delete it once it settles into ready or failed. Returns no body, because there is no row left to return; read the remaining set from the listing. 404 for a backup belonging to another instance and for one that does not exist, deliberately the same answer.
path Parameters
backup_idresource_ididDelete Service Instance Backup › Responses
Backup deleted
Restore Service Instance Backup
Rolls this volume back to a previous backup. Irreversible: the workloads mounting it are stopped, its data is reverted to the snapshot, then they restart -- every change made since the backup was taken is lost. The backup must be status: "ready". Runs in the background across many reconciler ticks; poll the listing for restorePhase. Refused with a conflict while another backup or restore is already in progress for this volume. 404 for a backup belonging to another instance and for one that does not exist, deliberately the same answer.
path Parameters
backup_idresource_ididRestore Service Instance Backup › Responses
Restore started
Create Resource Command Console Session Ticket
Mints a short-lived signed URL for attaching to one workload's own console, through the cluster's edge gateway.
This is not a shell, and a client must not present it as one. The service behind it opens a PTY around the workload's own entrypoint and fans that single process's output out to every viewer; typing sends bytes to that process's stdin. There is no shell to drop to, no second session to open, and no command available beyond the ones the workload's own console implements. The separate Pty capability, which would be a real shell, has no backend on this platform and therefore no route.
Writes nothing. It is a POST because it produces a credential and because the audit entry is written before the credential is handed over. Every call returns a different single-purpose URL, and a GET that does that is one a browser, a proxy or a history entry will cache and replay.
The session is shared, not exclusive. One process, one PTY, one output stream: two people attached see the same bytes, including each other's typing, and both can type. That is deliberate and is the opposite of Framebuffer, which takes a lock because two pointers on one screen is a bug.
Attaching is the backlog. The bridge replays its own rolling scrollback buffer down the same socket on attach, so there is no separate history request and no cursor. When the buffer has been truncated the replay is prefixed with an ANSI soft reset, so the stream is ANSI and a client either interprets it or strips it; it must not render it as literal text.
There is no container parameter and there cannot be one. The bridge is per pod, not per container: it binds a fixed port, every container in the pod shares one network namespace, and it wraps the pod's entrypoint. This is the sharpest difference from createResourceLogStreamTicket, whose ticket must name exactly one container.
expires_at is a redemption deadline, not a session deadline. The gateway checks the ticket once, at the WebSocket upgrade, and an attached session then runs until one side disconnects. Redeem it immediately; do not re-mint to stay connected.
Gated on the permission to change the service, not the permission to see it: an ordinary organization member who can read a service cannot type into its console. 404 when the instance has no command console, when the named workload is not the one that has it, or when its cluster has no edge gateway configured.
path Parameters
resource_idThe workload within it whose console is being attached to.
The workload within it whose console is being attached to.
idCreate Resource Command Console Session Ticket › Responses
A signed, short-lived URL for attaching to one workload's console
expires_atWhen the gateway stops accepting this ticket.
This is a redemption deadline, not a session deadline. cluster-agent
checks exp once, when the socket is upgraded
(gateway/edge_token.rs:41, called from gateway/terminal.rs:35); an
attached session then runs until one side disconnects. So a client
redeems the ticket immediately and never re-mints to stay connected: it
mints again only to attach again.
urlThe gateway URL to open a WebSocket against, carrying the signed ticket in its query string.
Binary frames both ways, and no subprotocol: cluster-agent's /terminal
upgrade negotiates none (cluster-agent/src/gateway/mod.rs:88), unlike
its /vnc and /ssh upgrades. Anything that is not a binary frame is
dropped by the gateway rather than refused (gateway/terminal.rs:107),
so there is no control channel to speak into.
Create Resource Exec Pty Session Ticket
Mints a short-lived, single-use signed URL for opening a NEW interactive shell (bash, falling back to sh) inside one container of one workload, through the cluster's edge gateway.
This is not the command console. createResourceCommandConsoleSessionTicket types into the workload's own entrypoint; this starts a separate shell beside it, the way kubectl exec -it does. Browser SSH on a virtual machine is a third, separate capability.
Open the URL as a WebSocket with the zaroz-pty-v1 subprotocol and append &columns=<1..=500>&rows=<1..=200>. Binary frames carry terminal bytes both ways; a client text frame {"type":"resize","columns":100,"rows":40} resizes (out of range ends the session); the server sends {"type":"exit","code":n} when the shell exits and {"type":"session_end","reason":...} before any close it initiates, after which the client must not retry the same URL.
Single use. expires_at is a redemption deadline, about ten seconds. Redeem it immediately; a reconnect mints a new one. The open session ends on its own after an idle period or a maximum length set by the gateway.
Writes nothing but an audit entry, written before the credential is handed over; it is a POST because it produces a credential.
container is optional and must be a container the pod runs; omitted, it is the workload's configured one, else its primary. Which workloads offer a shell is data on the workload: a product can switch it off. Gated on the permission to change the service, like the command console. 404 when the instance or workload offers no shell, when it has no running pod, or when its cluster has no edge gateway.
path Parameters
resource_idThe workload within the service to open a shell in.
The workload within the service to open a shell in.
idquery Parameters
containerWhich container of the pod the shell opens in. Omit it for the workload's own: the one its product configures, else its primary container. Must be a container the pod actually runs.
Which container of the pod the shell opens in. Omit it for the workload's own: the one its product configures, else its primary container. Must be a container the pod actually runs.
Create Resource Exec Pty Session Ticket › Responses
A signed, single-use URL for opening a shell in one container
containerThe container the shell will open in.
expires_atWhen the gateway stops accepting this ticket. A redemption deadline: the ticket is single use and the open session is bounded by the gateway's own idle and maximum-length timeouts, not by this.
shellsThe shells the gateway tries, in order, until one starts.
urlThe gateway URL to open a WebSocket against, carrying the signed ticket
in its query string. Negotiate the zaroz-pty-v1 subprotocol and append
columns and rows.
List Service Instance Files
Lists one directory on this workload's volume. path is absolute within the mount and is sent exactly as the customer typed it: kernel normalises it, and a client that collapsed .. itself would be papering over the layer that has to refuse it. The path in the response is the normalised one, so a breadcrumb reflects what was actually read rather than what was asked for, and a customer pasting an SFTP-shaped path gets back the mount-relative equivalent. Entries are unordered; sorting belongs to the panel. truncated is true when the directory holds more entries than one response carries, which is a flag rather than a cursor because the backend offers no stable ordering to page over. A path containing .., or naming one of the refused system prefixes, is a 400 rather than a 404: a traversal attempt and a missing file are different answers. 404 for a service whose product does not offer this capability, which is the same answer a service belonging to somebody else gives.
path Parameters
resource_idThe workload within it whose volume is being browsed.
The workload within it whose volume is being browsed.
idquery Parameters
pathAbsolute within the mount, starting with /. Send it exactly as typed;
normalising on the client would hide a traversal from the layer that has
to refuse it.
Absolute within the mount, starting with /. Send it exactly as typed;
normalising on the client would hide a traversal from the layer that has
to refuse it.
List Service Instance Files › Responses
One directory's entries
Unordered. Sorting is the panel's, per FilesTransport.
pathThe normalized path that was listed, not the one that was typed, so
a breadcrumb reflects what kernel actually read. A customer pasting an
SFTP-shaped path (/server/config) gets back the mount-relative one
(/config).
truncatedTrue when the directory holds more entries than one response carries.
A flag rather than a cursor: there is no stable ordering to page over
(the sidecar returns whatever read_dir yields), so a cursor would
promise a consistency the backend cannot keep.
Delete Service Instance File
Removes one file or directory. Kernel reads the entry's kind itself and unlinks a file or removes a directory accordingly; the request never says which, because a client that claims "this is a file" is a client deciding what gets unlinked. recursive defaults to false and is required for a directory that is not empty, and kernel checks the directory itself rather than trusting the flag, so a client that forgets it deletes nothing rather than everything below the path. A delete naming the mount root is refused outright: emptying the volume is not a gesture a file browser should be able to reach, and a customer who genuinely wants it is asking to cancel the service.
path Parameters
resource_idThe workload within it whose volume is being browsed.
The workload within it whose volume is being browsed.
idquery Parameters
pathrecursiveRequired for a directory that is not empty. Defaults to false, so a
client that forgets it deletes nothing rather than everything.
Note what it does not do: it never chooses between unlinking a file and removing a tree. Kernel reads the entry's kind itself and dispatches on that, because a client that says "this is a file" is a client deciding what gets unlinked.
Required for a directory that is not empty. Defaults to false, so a
client that forgets it deletes nothing rather than everything.
Note what it does not do: it never chooses between unlinking a file and removing a tree. Kernel reads the entry's kind itself and dispatches on that, because a client that says "this is a file" is a client deciding what gets unlinked.
Delete Service Instance File › Responses
Removed
Read Service Instance File
Reads one text file for the viewer. Capped at one mebibyte, and a larger file is refused with a message naming the cap rather than truncated: an editor that saved back a truncated read would destroy the tail of the customer's file. A file that is not valid UTF-8 is refused for the same reason, since the write route takes a string and a lossy read followed by a save would rewrite a binary as replacement characters. There is deliberately no route serving raw bytes or a signed download URL in this capability yet, so a client offers neither.
path Parameters
resource_idThe workload within it whose volume is being browsed.
The workload within it whose volume is being browsed.
idquery Parameters
pathAbsolute within the mount, starting with /. Send it exactly as typed;
normalising on the client would hide a traversal from the layer that has
to refuse it.
Absolute within the mount, starting with /. Send it exactly as typed;
normalising on the client would hide a traversal from the layer that has
to refuse it.
Read Service Instance File › Responses
The file's text
contentUTF-8 text. A file that is not valid UTF-8 is refused rather than
lossily converted, because the transport's write takes a string and a
lossy read followed by a save would rewrite the customer's binary as
replacement characters.
pathsize_bytesBytes of content, which is what was actually read rather than what the
directory entry claimed a moment earlier.
Write Service Instance File
Replaces one file's contents, creating it when it does not exist. Capped at one mebibyte, the same number the read is capped at, so a file the editor could open can always be saved back. Takes no operation lease: a file write is not a reconfiguration and does not re-render the workload, and holding the service's lease for the length of an editor save would refuse a restart for no reason. The audit entry names the path and the size and never the bytes.
path Parameters
resource_idThe workload within it whose volume is being browsed.
The workload within it whose volume is being browsed.
idquery Parameters
pathAbsolute within the mount, starting with /. Send it exactly as typed;
normalising on the client would hide a traversal from the layer that has
to refuse it.
Absolute within the mount, starting with /. Send it exactly as typed;
normalising on the client would hide a traversal from the layer that has
to refuse it.
Write Service Instance File › Request Body
contentReplaces the file's contents entirely. Creates it when it does not exist.
Write Service Instance File › Responses
The written file, as the backend now sees it
kindWhat an entry is. Two values, closed: a filesystem entry the browser can
draw is a file or a directory, and the sidecar refuses to describe anything
else (entry_for_path answers invalid_argument for a socket or a device).
namepathAbsolute within the mount, always starting with /. This is the value
to hand back to any other route on this capability: it is the sidecar's
own answer about where the entry lives rather than a path the client
rebuilt from name, so following it addresses the file kernel listed.
modified_atnull when the backend reported none. Rendered, never parsed for
meaning.
size_bytesnull for a directory. The sidecar reports zero for one, and a rendered
zero reads as "this folder is empty", which is a claim kernel never
made.
Create Service Instance Directory
Creates one directory, and every missing parent along the way. Idempotent: creating a directory that already exists succeeds and returns it, which is what makes a retried request safe. The path travels in the body rather than the query string because this is the one route with no other reason to have one.
path Parameters
resource_idThe workload within it whose volume is being browsed.
The workload within it whose volume is being browsed.
idCreate Service Instance Directory › Request Body
pathCreate Service Instance Directory › Responses
The directory, as the backend now sees it
kindWhat an entry is. Two values, closed: a filesystem entry the browser can
draw is a file or a directory, and the sidecar refuses to describe anything
else (entry_for_path answers invalid_argument for a socket or a device).
namepathAbsolute within the mount, always starting with /. This is the value
to hand back to any other route on this capability: it is the sidecar's
own answer about where the entry lives rather than a path the client
rebuilt from name, so following it addresses the file kernel listed.
modified_atnull when the backend reported none. Rendered, never parsed for
meaning.
size_bytesnull for a directory. The sidecar reports zero for one, and a rendered
zero reads as "this folder is empty", which is a claim kernel never
made.
Create Service Instance File Download URL
Mints a signed, short-lived hand-off to this service's own region for one file on this workload's volume (ZC-1225): a cluster edge gateway base URL plus a token, after running the identical confinement every interactive route on this capability runs. The signature names the path, not a connection: swapping path for another file's on an otherwise-valid ticket invalidates it, because the path is part of what was signed. The client downloads directly from the returned base_url using the returned token; kernel's own process never serves the bytes. This replaces a kernel-redeemed /api/v2/public URL this route used to return; the request and its authorization are unchanged.
path Parameters
resource_idThe workload within it whose volume is being browsed.
The workload within it whose volume is being browsed.
idCreate Service Instance File Download URL › Request Body
pathCreate Service Instance File Download URL › Responses
The signed hand-off, and when it expires
base_urlexpires_attokenCreate Service Instance Files Session Ticket
Mints a short-lived signed hand-off to this service's own region (ZC-1225): a cluster edge gateway base URL plus a token, confined to this workload's whole volume, for a client that will make many calls against cluster-agent's own /fs/* surface directly. Kernel's own process never touches the bytes of any operation opened this way. This is addressed by {service_instance_id, resource_id}, which is what lets a multi-workload instance name a second volume. Gated identically to download-url and for the same reason: a browse session is a wider grant than a single file, not a narrower one. 404 when the instance has no file provider or its cluster has no edge gateway configured.
path Parameters
resource_idThe workload within it whose volume is being browsed.
The workload within it whose volume is being browsed.
idCreate Service Instance Files Session Ticket › Responses
The signed hand-off, and when it expires
base_urlexpires_attokenCreate Resource Framebuffer Session Ticket
Mints a short-lived signed URL for one virtual machine's screen, through the cluster's edge gateway, and takes the exclusive hold that goes with it.
This is the machine's console, below its operating system. It sees the bootloader, it survives the guest's own firewall, and nothing inside the guest records what is done through it. Whoever can open it can do anything an operator sitting at the machine could.
Writes nothing durable, but it does take the hold. It is a POST because it produces a credential, because the audit entry is written before that credential is handed over, and because it acquires an exclusive session. Every call returns a different single-purpose URL.
The hold is exclusive; the socket is not, and the difference matters. Unlike createResourceCommandConsoleSessionTicket this route takes a hold, so a second caller gets a 409 naming the current holder and takes the screen only by asking for it with force. The hold lapses on its own if it is not refreshed through holdResourceFramebufferLock, so a browser that goes away does not keep a screen forever.
What the hold does not do is close a connection that is already open. The gateway checks the ticket once at the WebSocket upgrade and never consults the hold, so taking a screen with force stops the previous holder from refreshing and tells them they lost it, while their socket stays live and interactive until they disconnect. Treat the hold as the agreement between two well behaved clients that it is, not as an eviction. Closing the loser's socket is a change to the gateway and is not made here.
protocols names the WebSocket subprotocol the socket must request. It travels with the URL rather than being hardcoded by each client, because it is a property of the endpoint being minted; a socket that requests the wrong one completes the handshake with nothing to read.
expires_at is a redemption deadline, not a session deadline. The gateway checks the ticket once, at the WebSocket upgrade; the screen then stays connected until one side disconnects or the hold is taken. Redeem it immediately and do not re-mint to stay connected. hold_expires_at is the different, longer clock: refresh before it to keep the screen.
Note that a session opened through /v1's order-scoped vnc/edge-url and one opened here do not exclude each other. The two locks are keyed differently, because a service instance has no order to key on and may own more than one machine.
Gated on the permission to change the service, not the permission to see it. 404 when the instance has no framebuffer, when the named resource is not one of its virtual machines, or when its cluster has no edge gateway configured.
path Parameters
resource_idThe virtual machine within it whose screen is being opened.
The virtual machine within it whose screen is being opened.
idquery Parameters
forceTake the screen from whoever currently holds it.
A deliberate act, not a retry: a client sends it only after a 409 and
only because somebody chose to take over. The previous holder is not
notified by kernel; their next hold refresh returns held: false and
names the new holder.
Take the screen from whoever currently holds it.
A deliberate act, not a retry: a client sends it only after a 409 and
only because somebody chose to take over. The previous holder is not
notified by kernel; their next hold refresh returns held: false and
names the new holder.
Create Resource Framebuffer Session Ticket › Responses
A signed, short-lived URL for one machine's screen, and the hold
expires_atWhen the gateway stops accepting this ticket.
A redemption deadline and not a session deadline: cluster-agent verifies
exp once at upgrade (gateway/vnc.rs:12) and never again, so an
attached screen outlives its ticket.
hold_expires_atWhen the exclusive hold lapses unless refreshed.
protocolsSubprotocols the socket must request. See [FRAMEBUFFER_SUBPROTOCOL].
session_idThe handle for this exclusive session.
Minted here rather than supplied by the client, unlike /v1's
sessionId query parameter. The client cannot then name somebody else's
session, and taking a screen over is spelled force rather than
spelled "guess the holder's identifier and refresh it".
Pass it to the hold and release routes. It is not a credential: holding this screen still requires passing the same authorization the mint did.
urlThe gateway URL to open a WebSocket against, carrying the signed ticket in its query string.
Hold Resource Framebuffer Lock
Refreshes the exclusive hold on one virtual machine's screen. A client calls this on a timer well inside the hold's lifetime while it is connected.
Losing the screen is a 200 carrying held: false, not an error. By the time a hold is lost the caller is no longer the one using the screen, and putting a failure in front of them would report a problem to the wrong person. The response names the new holder so a client can say who took it.
A hold that has already lapsed is simply re-taken, provided nothing else has claimed the screen in between: a keep-alive arriving one request late should not strand a client that still has the session open.
The hold exists because two pointers on one screen fight over one cursor. createResourceCommandConsoleSessionTicket deliberately has no equivalent, because several people watching one game server's console is normal and correct.
path Parameters
resource_idThe virtual machine within it whose screen is being opened.
The virtual machine within it whose screen is being opened.
idHold Resource Framebuffer Lock › Request Body
session_idThe session_id the ticket response minted. A session that no longer
holds the screen gets held: false rather than an error.
Hold Resource Framebuffer Lock › Responses
Whether the screen is still held, and by whom if not
heldexpires_atWhen this hold lapses unless refreshed again. Absent when the hold was lost, because there is nothing left to refresh.
holder_nameWho holds it instead, when the hold was lost. Absent when it was kept, and absent when nothing holds it at all.
Release Resource Framebuffer Lock
Gives one virtual machine's screen back, so the next person does not wait out the hold's expiry.
/v1 has no equivalent and a closing tab there leaves the screen held for the rest of the lifetime, which is the gap this closes. It is best effort by design: a session that no longer holds the screen releases nothing and gets released: false rather than an error, because the ordinary caller is a page being torn down and that is not a place to report a problem.
Releasing a hold does not close an already-connected socket. The gateway checks the ticket at upgrade and never consults the hold, so a client that releases must also disconnect.
path Parameters
resource_idThe virtual machine within it whose screen is being opened.
The virtual machine within it whose screen is being opened.
idquery Parameters
session_idThe session giving the screen back. A session that no longer holds it releases nothing, which is the ordinary outcome after being taken over.
The session giving the screen back. A session that no longer holds it releases nothing, which is the ordinary outcome after being taken over.
Release Resource Framebuffer Lock › Responses
Whether this session was the one holding the screen
releasedFalse when the session named no longer held the screen, which is the ordinary outcome of unmounting after being taken over. Not an error: a page being torn down is not a place to report one.
Get Resource Logs
Reads one container's retained output, oldest first. This is the backlog half of LogStream; createResourceLogStreamTicket is the live half.
It reads the retained window, not history. There is no log store on this platform. The Kubernetes log API serves only what the node's log rotation still holds, so an empty result means "not in the retained window" and never "never happened". The coverage field is kernel's own sentence naming what was actually read, and a consumer should show it beside the results rather than paraphrasing it.
search is a case-insensitive substring, not a regular expression, and it runs here rather than in the browser: filtering client-side only ever filters the window the browser happens to be holding, and the window read here is far larger than that and is discarded server-side before any non-matching line is sent.
cursor is opaque and resumes exactly. It carries the instant a previous response stopped at together with how many lines bearing that same instant were already returned, because Kubernetes timestamps are not unique within a nanosecond and resuming on an instant alone either repeats or drops the lines sharing it.
There is deliberately no until parameter. The Kubernetes log API has no such bound, and implementing one by trimming a tail-anchored read would return an empty page for any range that ends before the newest output, which reads as "nothing happened then". A real time range needs a log store, which is its own programme.
A line carries no stream and no level. The log API merges stdout and stderr with no marker, and nothing on this platform parses a severity; both are optional in the client contract precisely so neither has to be invented here.
path Parameters
resource_idThe workload within it whose output is being read.
The workload within it whose output is being read.
idquery Parameters
containerWhich container on the workload's pod. May be omitted when the pod runs exactly one, which is the common case; a multi-container pod requires it and the refusal names the containers to choose from.
Which container on the workload's pod. May be omitted when the pod runs exactly one, which is the common case; a multi-container pod requires it and the refusal names the containers to choose from.
cursorA next_cursor from an earlier response. Opaque; hand back exactly what
was given.
A next_cursor from an earlier response. Opaque; hand back exactly what
was given.
limitMost lines to return. Clamped rather than rejected: a caller asking for more than the ceiling wants as much as possible.
Most lines to return. Clamped rather than rejected: a caller asking for more than the ceiling wants as much as possible.
previousRead the previous, terminated instance of the container instead of the running one. The only way to see why a crash-looping container died.
Read the previous, terminated instance of the container instead of the running one. The only way to see why a crash-looping container died.
searchCase-insensitive substring, applied on the server before the lines reach the browser. Not a regular expression.
Case-insensitive substring, applied on the server before the lines reach the browser. Not a regular expression.
Get Resource Logs › Responses
The retained window, oldest first, with a cursor to continue from
containerThe container these lines came from. Always populated, including when the request named none and the workload runs exactly one.
containersEvery container on this workload's current pod, so a panel can offer a container picker without a second call. A workload with one container yields one entry, and a panel should render no picker for it rather than a select with a single option.
coverageKernel's own sentence about what was actually read, to be shown
beside the results rather than paraphrased or composed in the browser
(R2).
It exists because of one specific way this endpoint can mislead: there is no log store on this platform, so a search covers only the window node log rotation still holds. A customer searching for a line that scrolled out of that window must be told what was searched, not shown an empty result that reads as "it never happened".
Oldest first, which is reading order for a log.
truncatedtrue when the read hit its own bounds, so more output exists on either
side of what was returned.
next_cursorHand this back as cursor to continue forwards from where these lines
stopped. Opaque: its spelling may change.
searchEchoed back so a client can tell a response to its current filter from a late response to the previous one.
Create Resource Log Stream Ticket
Mints a short-lived signed URL for following one container's output live, through the cluster's own edge gateway. This is the live half of LogStream; getResourceLogs is the backlog half.
Writes nothing the caller can read back through this API, and one thing they can read elsewhere: the grant is recorded in the owning organization's audit feed as service_instance.log_stream_attached, written before the credential is handed over, the same ordering the command-console and framebuffer mints use. The entry names the container, which neither of those can, and never the token.
It is a POST because it produces a credential: every call returns a different single-purpose URL, and a GET that does that is one a browser, a proxy or a history entry will cache and replay.
The transport is a WebSocket, and that was a decision rather than an assumption. SSE was the alternative and was rejected on four grounds. A PTY needs keystrokes and resize messages travelling the other way, so choosing SSE here would guarantee the platform runs two transports rather than one. Five of the six endpoints on this gateway's router are already WebSocket upgrades and exactly one is SSE, so SSE would be a second convention rather than a replacement. The signed ticket is shared machinery across four resource kinds and would have to be reimplemented over an EventSource, which cannot send an Authorization header and would push the token into a query string on a long-lived connection. And SSE's one real advantage, Last-Event-ID, is the wrong granularity: the cursor this design needs is a property of the upstream read, not of the frame numbering, and has to be re-supplied on a fresh ticket regardless. The consequence accepted with it is that a WebSocket gives no automatic reconnect, so the reconnect ladder is a shared client concern.
There is no search here, and there cannot be one while kernel stays off the data path: the live bytes go from the cluster to the browser without passing through this process. Filtering the tail is a client concern; getResourceLogs is where a search runs on the server.
The ticket names exactly one container, and the gateway refuses any other, so a client switching containers mints a new one. It is valid for a minute; a client that wants to keep reading re-mints, which is what keeps a leaked URL from being a durable credential.
since is the resume cursor for the live half: pass the at of the last line already on screen and it is signed into the returned URL as since_time. The gateway reads it, clamps it to its own lookback bound, and uses it INSTEAD of the tail replay, so a reconnect resumes where the client stopped rather than repeating what it already holds. A malformed value degrades to the tail replay rather than failing the connection, so a client that sends a bad cursor still gets output. Omit it on a first connection, when there is nothing to resume from and the tail is what you want.
previous=true follows the container's previous, terminated instance instead of the running one, which is the only way to see why a crash-looping container died. It is signed into the ticket, so a ticket minted without it cannot be edited into one that reads the crashed instance. A terminated instance writes nothing further, so the stream closes once its retained output has been sent. It combines with since: the resume point applies to the previous instance's output.
path Parameters
resource_idThe workload within it whose output is being read.
The workload within it whose output is being read.
idquery Parameters
containerWhich container the ticket is minted for. May be omitted when the pod runs exactly one.
Which container the ticket is minted for. May be omitted when the pod runs exactly one.
previousFollow the previous, terminated instance of the container instead of the running one. The only way to see why a crash-looping container died.
Follow the previous, terminated instance of the container instead of the running one. The only way to see why a crash-looping container died.
sinceRFC3339 instant to resume the stream from, normally the at of the last
line already on screen.
RFC3339 instant to resume the stream from, normally the at of the last
line already on screen.
Create Resource Log Stream Ticket › Responses
A signed, short-lived URL for one container's live output
containerThe container the ticket is minted for. The gateway refuses any other, so a client switching containers mints a new ticket.
expires_atWhen the ticket stops being accepted. A client re-mints on expiry; the short life is what makes a leaked URL harmless.
urlThe gateway URL to open a WebSocket against. Carries the signed ticket in its query string and is single-purpose: it grants a read of exactly one container's output and nothing else.
Get Resource Metrics
Reads one resource's CPU, memory and network over a chosen window, as points already bucketed by the backend. window_minutes is 5, 15 or 30 and defaults to 30; anything else is refused, because metric retention is thirty minutes and a longer window has no samples to draw. Every window returns 60 buckets, so the bucket width is 5, 15 or 30 seconds respectively. A bucket holding no samples has a null value so a chart can break the line, which a stopped workload and an idle one need to look different. Each series carries a summary -- latest, mean and max over the whole window, computed from the raw samples rather than from the buckets, so a one-sample spike is still reported as the max -- and the ceiling it is measured against, or null where the series is unmetered. The summary is absent when the window holds no samples at all.
path Parameters
idresource_idThe resource within it whose measurements are wanted. Scoped per resource rather than per instance because a Supabase-shaped instance owns six workloads, and "CPU" is not one number across them.
The resource within it whose measurements are wanted. Scoped per resource rather than per instance because a Supabase-shaped instance owns six workloads, and "CPU" is not one number across them.
query Parameters
window_minutesWindow in minutes, ending now. One of 5, 15 or 30; anything else
is refused rather than clamped, because silently widening a window
makes two screens disagree about what "the last five minutes" showed.
Window in minutes, ending now. One of 5, 15 or 30; anything else
is refused rather than clamped, because silently widening a window
makes two screens disagree about what "the last five minutes" showed.
Get Resource Metrics › Responses
Every series for this resource over the requested window
coverageKernel's own sentence about what was actually read, to be shown
beside the charts rather than paraphrased or composed in the browser
(R2). The same field, for the same reason, as
[ResourceLogsResponse::coverage] -- named precisely because
00-program.md 15.3.1 calls it LogSearchResponse, which does not
exist, and a citation drift is how the next reader loses ten minutes.
It exists because of one specific way this endpoint misleads. Every
window returns [METRIC_BUCKETS] buckets whether or not anything was
sampled, so a resource with no samples at all comes back as four series
of sixty nulls -- four empty axes, no summary, and nothing said. A
consumer cannot tell that apart from a workload that was genuinely
stopped for the whole window, and it must not try: deciding which from
the points is exactly the reduction R2 forbids.
So kernel says which it is. The distinction the sentence carries is "no sample was stored" versus "usage was zero", and only the server knows it.
fromStart of the first bucket.
resolution_secondsBucket width, in seconds. (to - from) / resolution_seconds is the
length of every points array in series.
toEnd of the window. Exclusive: no bucket contains it.
window_minutesThe window actually served, echoed so a client can tell what it got without re-deriving it from its own request.
Get Resource SSH Connection Details
How to reach one Linux virtual machine over SSH, and whether its browser terminal is ready.
host, port, username and command are for the customer's own SSH client; host is empty while the machine has no public address of its own. authorized_key_fingerprints are the keys the machine was built trusting, and host_key_fingerprints the ones it enrolled for itself on first boot, which a client should see on its first connection.
browser_ssh_status is ready only when the machine is running, its host key is enrolled and its cluster's SSH broker is healthy; enrolling_host_key while the guest has not reported its key yet; otherwise unavailable. public_route_status is ready once the machine's public address routes to it.
Gated on the permission to change the service, like the session route beside it: nothing here is useful except to someone about to open a shell. 404 when the instance has no SSH capability or the resource is not one of its virtual machines; 503 when the machine cannot take an SSH session.
path Parameters
resource_ididGet Resource SSH Connection Details › Responses
How to reach the machine, and whether the browser terminal is ready
authorized_key_fingerprintsSHA-256 fingerprints of the public keys the machine was built trusting.
browser_ssh_statusready, enrolling_host_key or unavailable.
commandA ready-to-paste ssh user@host, or empty while there is no host.
hostThe machine's own public address, or empty while it has none.
host_key_fingerprintsSHA-256 fingerprints of the host keys the machine enrolled on first boot: what a client should see on its first connection.
operating_systemAlways linux: the capability is only derived for a Linux guest.
password_auth_enabledportpublic_route_statusready once the public address routes to the machine, else pending.
usernameThe guest account the machine was built with.
Get Resource VPS Details
The details panel's read for one virtual machine, Linux or Windows: the operating system, the guest account, the public IPv4 and IPv6 addresses, the internal addresses the guest reports, and where to connect (SSH on 22 for Linux, RDP on 3389 for Windows). The password is never included. Internal addresses come from the running guest and are null while it is stopped or its cluster cannot answer.
Gated like the SSH details read beside it. 404 when the instance has no SSH capability or the resource is not one of its virtual machines.
path Parameters
resource_ididGet Resource VPS Details › Responses
The machine's addresses and where to connect
connect_port22 for Linux (SSH), 3389 for Windows (RDP).
connect_protocolssh or rdp.
operating_systemlinux or windows.
public_ipv4The machine's public IPv4 address; empty while it has none.
usernameinternal_ipv4internal_ipv6public_ipv6Create Resource SSH Session
Issues a browser SSH session on one Linux virtual machine and returns the one-time URL its terminal connects to.
This is a shell on the customer's machine, as the guest account it was built with. The URL is redeemable once, within expires_in seconds, by the cluster's SSH broker, and only from the dashboard origin in the X-Zaroz-Dashboard-Origin header the request carried; a request without that header is refused. The broker then connects with a certificate valid for one minute, and the session is re-authorized on every heartbeat, so it ends within one heartbeat of the caller losing access to the service.
Browser sessions only: a restricted API token is refused with 403, because its narrower scope could not be re-applied on those heartbeats.
Unlike the framebuffer there is no exclusive hold; several terminals on one machine are normal. The limit is three live sessions per person per machine, and a fourth is refused with 429.
Gated on the permission to change the service. 404 when the instance has no SSH capability or the resource is not one of its virtual machines; 503 when the machine is not running, its host key is not enrolled yet, or its cluster's SSH broker is not healthy.
path Parameters
resource_ididCreate Resource SSH Session › Request Body
columnscorrelation_idrowsCreate Resource SSH Session › Responses
A one-time URL for the browser terminal
expires_insession_idurlwss://<edge>/ssh?ticket=.... Redeemable once, within expires_in
seconds, and only from the dashboard origin it was issued for.
Get Service Instance Volume
Kernel's own summary of one volume, so a client never sums file sizes or divides two byte counts to draw a meter. capacity_bytes is the claim's configured size, which is a quota rather than a measurement and is therefore always present. used_bytes is a recursive walk performed inside the cluster and is null whenever kernel cannot measure exactly this volume: the service has no file sidecar, the sidecar's walk covers more than this claim, or the walk did not finish in time. used_label and used_fraction are kernel's rendering of the same measurement and are null exactly when it is; render the label as written and treat the fraction as already clamped to [0, 1]. last_backup_at is the customer's most recent completed on-demand backup of this volume and never the platform's own disaster-recovery backups. There is no measurement timestamp, because the backend caches its walk and reports neither its age nor its duration, so any timestamp here would be the time kernel asked rather than the time anything was measured. 404 for a resource that is not a volume, for a volume belonging to somebody else, and for a service whose product has no storage, which are deliberately the same answer.
path Parameters
resource_idThe volume within it being described.
The volume within it being described.
idGet Service Instance Volume › Responses
Everything kernel knows about this volume
capacity_bytesThe claim's configured size. A quota rather than a measurement, so it is exactly what the customer bought and it never disagrees with the invoice.
mount_pathWhere the volume is bound inside the workload, for example /data. A
cross reference rather than a property of the claim: the mount lives on
the workload that mounts it, and this is the path the file browser opens
at for the same volume.
last_backup_atWhen the customer's most recent on-demand backup of this volume
finished, or null when they have never taken one that completed.
The customer's own snapshots only. The platform's disaster-recovery backups run on a different mechanism and are not counted here, because presenting one as the other would tell a customer their data is protected by something they never invoked.
used_bytesWhat the volume holds, or null when kernel cannot measure exactly this
claim: the service has no file sidecar, the sidecar's walk covers more
than this volume, or it did not answer in time. Absent rather than
approximated.
used_fractionA number in [0, 1], already clamped. Multiplying it by 100 for a
percentage width is a unit conversion for the widget rather than a
computation; deriving it from the two byte counts instead is not.
null exactly when used_bytes is.
used_labelKernel's sentence about the meter, for example "3.0 GiB of 25 GiB".
Render it as written. null exactly when used_bytes is.
