WorkspaceService
AddWorkspaceGuest
Section titled “AddWorkspaceGuest”POST /spin.v1.WorkspaceService/AddWorkspaceGuest
Invite a person to log in to a workspace as its guest, by their email: the owner’s to ask, and the next access the owner signs names them. They log in once it does.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
email | string |
Response
No fields: {}.
AttachVSCodeServer
Section titled “AttachVSCodeServer”POST /spin.v1.WorkspaceService/AttachVSCodeServer
Give a running workspace the VS Code server of a client’s commit, while it runs: published first when this installation has not got it and fetches servers on its own (InstallationSettings.vscode_fetch), refused as FAILED_PRECONDITION when it does not. Asked again until it answers attached.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
commit | string | commit is 40 hex digits. |
publish | boolean | publish tries a publish of commit again when the last one failed; without it, that failure is the answer. A client sets it on its first ask, and not on those that follow. |
Response
| Field | Type | What it is |
|---|---|---|
attached | boolean | attached: the workspace has the server now. Otherwise it is being published, and step says where that is. |
step | string | |
detached | list of string | detached are the servers the workspace gave up to make room, asked for longest ago. |
CheckPortAccess
Section titled “CheckPortAccess”POST /spin.v1.WorkspaceService/CheckPortAccess
Whether one request may reach one published port. The gate in front of them.
Request
| Field | Type | What it is |
|---|---|---|
workspaceName | string | From the subdomain |
port | integer (int32) | |
sessionToken | string | The session token as the proxy received it, empty for a request with no session at all. Only a PUBLIC port is reachable that way. |
httpsBackend | boolean | As in OpenWorkspaceProxySessionRequest |
Response
| Field | Type | What it is |
|---|---|---|
status | WorkspaceProxyStatus | |
allowed | boolean | |
access | PortAccess | What the port’s level is, so the proxy can tell a refusal that a login would fix from one it would not: an anonymous request to a PRIVATE port is a redirect, and a signed-in request to the same port is a 403 no amount of signing in changes. |
workspaceId | string | The workspace the name was decided about, when allowed. The proxy pools connections by it and opens sessions for it: a name is freed by a rename and taken by someone else’s workspace, and a connection pooled by name would carry the next request into the old one. |
CheckPortPublished
Section titled “CheckPortPublished”POST /spin.v1.WorkspaceService/CheckPortPublished
Whether a published port’s name is one this installation serves, whoever may reach it: the proxy’s on-demand TLS question, asked before any browser has a session to send.
Request
| Field | Type | What it is |
|---|---|---|
workspaceName | string | From the subdomain |
port | integer (int32) | |
httpsBackend | boolean | As in CheckPortAccessRequest: 3000s- is not 3000- |
Response
| Field | Type | What it is |
|---|---|---|
published | boolean | The port is published on a workspace that is not deleted, at any level and in any state. |
CloneWorkspace
Section titled “CloneWorkspace”POST /spin.v1.WorkspaceService/CloneWorkspace
Clone a running workspace: a snapshot of its disk, published, and a workspace created from it with the source’s team, project and ref, size, network policies and environment, owned by the caller. Disk only: a clone has an identity of its own, so no memory goes with it. The snapshot stays, as the clone’s floor. Answers once the clone exists, which takes as long as publishing the source’s disk.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
name | string | The clone’s name; generated when empty. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace | |
snapshot | Snapshot | The source’s snapshot the clone was made from, which stays as the clone’s floor. |
CreateSnapshot
Section titled “CreateSnapshot”POST /spin.v1.WorkspaceService/CreateSnapshot
Create a snapshot of the current workspace state
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
description | string | Optional description |
withMemory | boolean | with_memory keeps the machine’s memory too, taken at the instant the disk is sealed; the guest is paused for tens of milliseconds, and the call returns once the memory is written. |
Response
| Field | Type | What it is |
|---|---|---|
snapshot | Snapshot |
CreateWorkspace
Section titled “CreateWorkspace”POST /spin.v1.WorkspaceService/CreateWorkspace
Create a new workspace
Request
| Field | Type | What it is |
|---|---|---|
name | string | Optional, generated if empty |
teamId | string | Optional: team ID (personal workspace if empty) |
image | string | A published image (ListImages); required unless from_snapshot_id is set |
preset | string | The preset it is sized by, by name (AdminService.ListResourcePresets): its cores, memory, disk and how it grows. Empty is the installation’s default preset, or with none marked 1 core, 512 MB and 10 GB free. A disabled preset is refused. |
env | map of string to string | Environment variables |
fromSnapshotId | string | Create workspace from a shared snapshot |
networkTags | list of string | network_tags are the network policies this workspace runs under, by name - the same idea as a GCP instance’s network tags. The host’s ruleset names the tag and holds the set of machines carrying it, so this decides which rules apply without naming a rule. Empty runs the workspace under the installation’s default, and under “offline” where it declares none: a create that names nothing reaches nothing, rather than everything. A tag the host has no policy for fails the start rather than being ignored: a workspace asking for a policy the node does not have is a question with two answers, and quietly choosing “run it without” is how one ends up less contained than whoever launched it believes. |
projectId | string | A project of a team the caller is in: the workspace is the project’s - its team, image, preset and tags, which the request then names none of - and its guest clones the project’s repository at ref, the project’s own when empty. |
ref | string | |
requestId | string | Optional, at most 128 bytes: the client’s key for this create, so a retry after an answer it never got is answered with the workspace the first attempt made. The same key with another request is refused (FAILED_PRECONDITION). |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
DeleteSnapshot
Section titled “DeleteSnapshot”POST /spin.v1.WorkspaceService/DeleteSnapshot
Delete a snapshot
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
snapshotId | string |
Response
No fields: {}.
DeleteWorkspace
Section titled “DeleteWorkspace”POST /spin.v1.WorkspaceService/DeleteWorkspace
Delete a workspace: into the trash, where the installation keeps one, or erased.
Request
| Field | Type | What it is |
|---|---|---|
id | string | |
force | boolean | Force delete regardless of state (skips state validation) |
permanently | boolean | permanently erases the workspace now - its disk, snapshots and keys - rather than putting it in the trash; a workspace already in the trash is erased only this way. What is erased cannot be undeleted: the store expires its bytes when its retention ends. |
Response
| Field | Type | What it is |
|---|---|---|
trashedUntil | Timestamp | Until when it can be undeleted; unset when it was erased. |
DiffSnapshots
Section titled “DiffSnapshots”POST /spin.v1.WorkspaceService/DiffSnapshots
Compare two of a workspace’s snapshots file by file.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
fromSnapshotId | string | Empty compares from what the workspace was created from. |
toSnapshotId | string | |
under | string | under narrows the comparison to one path of the filesystem, from its root; empty is all of it. The walk starts there rather than filtering, so what is outside it costs nothing and does not fill the answer. |
Response
| Field | Type | What it is |
|---|---|---|
changes | list of FileChange | Every change from one snapshot to the other, a directory before what is under it. |
truncated | boolean | truncated says there are more changes than one answer carries. |
ExposePort
Section titled “ExposePort”POST /spin.v1.WorkspaceService/ExposePort
Port exposure
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
port | integer (int32) | |
httpsBackend | boolean | See ExposedPort.https_backend |
description | string | |
access | PortAccess | Left unset, this is PRIVATE. Exposing a port is not the same as publishing it. |
Response
| Field | Type | What it is |
|---|---|---|
exposedPort | ExposedPort |
GetOwnerWord
Section titled “GetOwnerWord”POST /spin.v1.WorkspaceService/GetOwnerWord
A workspace’s newest access - who logs in, consent to collect logs, the settings approved - with what the next must say: the people the owner invited and the settings the guest would be handed now, for the owner to sign. Its owner’s and its guests’ to read.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string |
Response
| Field | Type | What it is |
|---|---|---|
word | OwnerWord | word is the newest the owner signed; unset for a workspace whose owner has signed none. |
owner | AccessPerson | owner is the workspace’s owner, with their keyring as it is now: who signs the next. Empty keyring for an owner who has signed none. |
dotfiles | DotfilesConfig | settings are the startup configuration the guest would be handed at its next registration: the owner’s settings after the team’s policy. A word approves them by their digest, which the client computes from these, as the guest does from what it is handed. |
defaultShell | string | |
env | map of string to string | |
editorSettings | map of string to string | |
taskfile | string | |
egressRoot | string | egress_root is the installation’s egress root, PEM: what the guest is handed at registration, and trusts only when a word names its digest. A client names it only once it has held it to the root it pinned for the installation, never on this answer’s say alone. |
identityAudiences | list of string | identity_audiences is who the installation gives identities for, empty for anybody: what a client offers its owner to name in a word, which a host holds every token to as well. |
teamId | string | The workspace as its first access says it: team, image, and the snapshot and workspace it was cloned from. The next access says the same; the first says these. |
image | string | |
parentSnapshotId | string | |
parentWorkspaceId | string | |
guests | list of AccessPerson | guests are the people the owner invited, each with their keyring as it is now: who the next access names besides the owner. One with an empty keyring has signed none, and is named once they have. |
role | string | role is the caller’s: “owner”, or “guest” - who reads it and signs nothing. |
repository | RepositoryConfig | repository is the one the workspace opened, part of the settings a word approves as the five above are: unset for a workspace that opened no project. |
prebuildClaim | string (byte) | prebuild_claim is, for a workspace opened from a prebuild, the claim the host that built it signed (PrebuildClaim), whose SHA-256 repository.prebuild_claim_digest is: a client verifies it, and that it names the repository and the commit the settings do, before its word approves them. |
prebuildWriters | map of string to string (byte) | prebuild_writers is the record of the claim’s writer, by its id (writers/<id>.json in the installation’s store), which the client holds to its own anchors as it does a launch claim’s. |
GetWorkspace
Section titled “GetWorkspace”POST /spin.v1.WorkspaceService/GetWorkspace
Get a specific workspace
Request
| Field | Type | What it is |
|---|---|---|
id | string | Workspace ID or name |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
GetWorkspaceConsole
Section titled “GetWorkspaceConsole”POST /spin.v1.WorkspaceService/GetWorkspaceConsole
The tail of the workspace’s serial console: the kernel, vminit, then the supervisor. It is where a machine that never came up says why, and it is read on demand from the host that holds it. An installation that collects consoles also keeps them, searchable for their retention (LogService.SearchWorkspaceLogs); one that does not keeps them on the host, since the console also carries what the tenant’s own programs print.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
lines | integer (int32) | How many lines from the end; zero asks for the default. The host bounds it either way. |
Response
| Field | Type | What it is |
|---|---|---|
lines | list of string | Newest last, as the console was written. |
truncated | boolean | truncated says there are lines before the first one here, so what this begins with is not mistaken for the start of the boot. |
hostId | string | Which host answered. A console belongs to the machine that wrote it, and a workspace that has moved has nothing to say about the run that failed on the host it left. |
GetWorkspaceEgress
Section titled “GetWorkspaceEgress”POST /spin.v1.WorkspaceService/GetWorkspaceEgress
What a running workspace has actually reached beyond the node.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string |
Response
| Field | Type | What it is |
|---|---|---|
destinations | list of ObservedDestination | Most traffic first, so what an allowlist has to carry is at the top. |
lookups | list of ResolverLookup | The workspace’s recent lookups its host’s resolver did not answer as asked, newest first: “it cannot resolve github.com” is an upstream failing, a name pointing into the node being removed, or a query type refused, and this says which. Answered lookups are not kept. |
refused | list of RefusedDestination | What the host’s drops refused the workspace in the last hour, most packets first: the node’s own networks, or what none of its policies allows. The other half of destinations, and what a policy that is too narrow looks like from outside the machine. |
brokered | list of BrokeredRequest | The workspace’s recent requests to names its policies broker with an injection, newest first: what the host’s egress proxy set a header on, and what it refused and why. A brokered name no rule injects on is relayed byte for byte and leaves no request here. |
GetWorkspaceHistory
Section titled “GetWorkspaceHistory”POST /spin.v1.WorkspaceService/GetWorkspaceHistory
Get workspace history (snapshots/state changes timeline)
Request
| Field | Type | What it is |
|---|---|---|
id | string | |
limit | integer (int32) | Number of events (default: 50) |
Response
| Field | Type | What it is |
|---|---|---|
events | list of WorkspaceEvent |
GetWorkspaceIdentity
Section titled “GetWorkspaceIdentity”POST /spin.v1.WorkspaceService/GetWorkspaceIdentity
Who the workspace is outside spin: the identity its tokens and signatures carry, the issuer a relying party trusts it by, and what it was cloned from.
Request
| Field | Type | What it is |
|---|---|---|
id | string |
Response
| Field | Type | What it is |
|---|---|---|
spiffeId | string | The workspace’s SPIFFE ID, spiffe://<domain>/t/<team>/w/<workspace>: every subject in it is under it - the user’s at /u, each agent’s at /a/<name> - so a relying party names the workspace by it as a prefix. |
userSubject | string | The workspace user’s subject, what its tokens and signatures carry. |
issuer | string | The issuer its tokens name, https://id.<domain>, where the key set and the allowed signers are. |
parentSnapshotId | string | What the workspace was cloned from: the snapshot, and the workspace whose disk it was when that is still there and of the same team. Empty for a workspace made from an image. |
parentWorkspaceId | string | |
audiences | list of string | Who the installation gives identities for; empty is anybody. |
GetWorkspaceStatus
Section titled “GetWorkspaceStatus”POST /spin.v1.WorkspaceService/GetWorkspaceStatus
What every party believes about one workspace, and where they disagree.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string |
Response
| Field | Type | What it is |
|---|---|---|
state | WorkspaceState | What the control plane believes, which is what every other surface shows. |
failureReason | string | Only when state = FAILED |
supervisor | SupervisorStatus | |
host | WorkspaceHostStatus | |
volume | WorkspaceVolumeStatus | |
disagreements | list of StatusDisagreement | Where the four disagree, in the order they should be read. Empty means they agree - which is the answer when a workspace is simply healthy, and is worth saying. |
runtime | WorkspaceRuntime | What the machine has and uses now, asked of its host. Absent - not zero - when there is no machine to ask about: not running, on no connected host, or a host that did not answer in time. Zero cores would read as a machine that has none. |
failure | WorkspaceFailure | Which part failed, when state = FAILED; failure_reason is the detail. Workspace.failure. |
injections | list of InjectionStatus | Each header a brokered rule of the workspace’s policies sets, and whether what it is set from is there to set: a request to a brokered name is refused when it is not, and this is where that is seen from outside the machine. |
GrantPortAccess
Section titled “GrantPortAccess”POST /spin.v1.WorkspaceService/GrantPortAccess
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
port | integer (int32) | |
userId | string |
Response
| Field | Type | What it is |
|---|---|---|
exposedPort | ExposedPort |
GrantWorkspaceResources
Section titled “GrantWorkspaceResources”POST /spin.v1.WorkspaceService/GrantWorkspaceResources
Give a workspace more cores and memory of its own, up to its preset’s ceiling: its host reserves them and its machine is grown while it runs. The grant lasts until it is released or the workspace is deleted.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
cpuCores | integer (int32) | |
memoryMb | integer (int32) | |
lasts | Duration | How long the grant lasts before it is given back on its own, from now: at least a minute. Unset keeps it until it is given back. Each grant says it anew: one that says nothing about time is kept, whatever the one before it said. |
move | boolean | move says what to do when a running workspace’s host has no room for the grant: move it to a host that has - suspended where it runs, its processes as they are, and resumed there from the checkpoint. The guest is paused from the checkpoint until it runs on the other host, which takes as long as storing its memory and publishing its disk. Without it such a grant is refused. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
KeepWorkspace
Section titled “KeepWorkspace”POST /spin.v1.WorkspaceService/KeepWorkspace
Keep a running workspace awake for a while: neither the idle suspension nor the running cap fires before kept_until, and the question asked before one (suspends_at) is withdrawn. An answer with an end, never permanent: at most a day at a time (MaxKeepMinutes).
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
lasts | Duration | How long from now it is kept awake: a minute to a day. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
ListDeletedWorkspaces
Section titled “ListDeletedWorkspaces”POST /spin.v1.WorkspaceService/ListDeletedWorkspaces
The caller’s workspaces in the trash, and until when each can be undeleted.
Request
No fields: {}.
Response
| Field | Type | What it is |
|---|---|---|
workspaces | list of DeletedWorkspace |
ListExposedPorts
Section titled “ListExposedPorts”POST /spin.v1.WorkspaceService/ListExposedPorts
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
page | PageRequest |
Response
| Field | Type | What it is |
|---|---|---|
ports | list of ExposedPort | |
page | PageResponse |
ListImages
Section titled “ListImages”POST /spin.v1.WorkspaceService/ListImages
The images a workspace can actually be created from. A client that offers a name from anywhere else - a constant it ships, a container registry it knows of - offers a create that fails, because a workspace’s disk is cloned from a published image and nothing else.
Request
No fields: {}.
Response
| Field | Type | What it is |
|---|---|---|
images | list of Image | One entry per name, newest publication of it, in the order a person reads a list. |
ListNetworkPolicies
Section titled “ListNetworkPolicies”POST /spin.v1.WorkspaceService/ListNetworkPolicies
The network policies a workspace can be created with, as the hosts report them.
Request
No fields: {}.
Response
| Field | Type | What it is |
|---|---|---|
policies | list of NetworkPolicy | |
hostsEnforcing | integer (int32) | Of the hosts connected, how many have installed what the installation declares. They are told on their next heartbeat, so the two differ for a moment after an apply - and go on differing when a host cannot install what was declared, which is the thing worth seeing. |
hostsConnected | integer (int32) |
ListSnapshots
Section titled “ListSnapshots”POST /spin.v1.WorkspaceService/ListSnapshots
List snapshots for a workspace
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
page | PageRequest |
Response
| Field | Type | What it is |
|---|---|---|
snapshots | list of Snapshot | |
page | PageResponse |
ListWorkspaceQuarantineDenials
Section titled “ListWorkspaceQuarantineDenials”POST /spin.v1.WorkspaceService/ListWorkspaceQuarantineDenials
What a workspace attempted past its policy: the refusals its supervisor reported, newest first - an administrator’s reading of what was tried while it was held.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | The workspace’s id. |
limit | integer (int32) | How many of the newest to answer; the newest first. |
Response
| Field | Type | What it is |
|---|---|---|
denials | list of QuarantineDenial | Newest first. |
ListWorkspaces
Section titled “ListWorkspaces”POST /spin.v1.WorkspaceService/ListWorkspaces
List workspaces for the authenticated user
Request
| Field | Type | What it is |
|---|---|---|
page | PageRequest | |
stateFilter | WorkspaceState | Optional filter by state |
teamId | string | Optional filter by team (empty = all user’s workspaces) |
nameFilter | string | Optional search by name prefix |
Response
| Field | Type | What it is |
|---|---|---|
workspaces | list of Workspace | |
page | PageResponse |
MoveWorkspace
Section titled “MoveWorkspace”POST /spin.v1.WorkspaceService/MoveWorkspace
Move a running workspace to another host: suspended where it runs, its processes as they are, and resumed there from the checkpoint, holding what it holds. Placement chooses the host, as it does at a start. A workspace that is not running is refused: placement decides where it runs at its next start.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
OpenWorkspaceProxySession
Section titled “OpenWorkspaceProxySession”POST /spin.v1.WorkspaceService/OpenWorkspaceProxySession
One connection into a published port, for the proxy, when it needs a new one.
Request
| Field | Type | What it is |
|---|---|---|
workspaceName | string | From the subdomain, as CheckPortAccess takes it |
port | integer (int32) | The published port inside the workspace |
sessionToken | string | The session token of whoever the connection is being opened for, validated here. It is the difference between a control plane that can refuse and one that cannot. The proxy gates each request in front, but this is reachable on its own, and without a credential to check, anything that could reach it would open a session into any published port of any workspace. Empty is allowed and reaches only PUBLIC ports. |
httpsBackend | boolean | The hostname’s s. A port whose flag differs answers as one that is not exposed. |
workspaceId | string | The workspace CheckPortAccess decided the request about. A name that now names another answers as a port that is not exposed: the session is for the workspace that was decided. |
Response
| Field | Type | What it is |
|---|---|---|
status | WorkspaceProxyStatus | |
relayUrl | string | Where the two ends of this connection meet, and the token that names it there. Set only when status is ACCESSIBLE. The token is single-use: one connection, one token. |
sessionToken | string | |
httpsBackend | boolean | The flag of the row the session was authorized on: whether the proxy speaks TLS. |
QuarantineWorkspace
Section titled “QuarantineWorkspace”POST /spin.v1.WorkspaceService/QuarantineWorkspace
Hold a workspace in quarantine: an administrator’s decision, held until one releases it. A stopped workspace is held at once; one whose machine runs is stopped first, forced, and held when its host says it stopped. Its disk is kept as it was, and meanwhile its own person cannot start, move or delete it.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | The workspace’s id. |
reason | string | What the administrator saw that led to holding it: kept on the audit entry for this act, not on the row. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
RecoverWorkspace
Section titled “RecoverWorkspace”POST /spin.v1.WorkspaceService/RecoverWorkspace
Re-home a workspace whose host is gone, at a cost its owner accepts.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
acceptDataLoss | boolean | False asks what it would cost. True accepts that cost and does it. |
Response
| Field | Type | What it is |
|---|---|---|
recovered | boolean | False for a cost report, true when the workspace was re-homed. |
unpublishedSeconds | string (int64) | What recovering costs: the work the dead host had not published, as of its last report, plus the time since - a host that has been silent for an hour has been writing for that hour too, and reporting only what it last said would understate it. |
unpublishedBytes | string (int64) | |
hostLastReportedAt | Timestamp | When that report was made. The two numbers above are only as fresh as this. |
newHostId | string | The host it now runs on. Set only when recovered. |
ReleaseWorkspaceQuarantine
Section titled “ReleaseWorkspaceQuarantine”POST /spin.v1.WorkspaceService/ReleaseWorkspaceQuarantine
Release what was quarantined: stopped, with its disk as it was - or, where the stop a quarantine asked for ended FAILED, failed as it is, and no longer held.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | The workspace’s id. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
ReleaseWorkspaceResources
Section titled “ReleaseWorkspaceResources”POST /spin.v1.WorkspaceService/ReleaseWorkspaceResources
Give a grant back: the workspace holds its floor again, and its machine is shrunk while it runs.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
RemoveWorkspaceGuest
Section titled “RemoveWorkspaceGuest”POST /spin.v1.WorkspaceService/RemoveWorkspaceGuest
Take a guest out: refused at the control plane at once, and at the workspace once the owner signs an access without them.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
userId | string |
Response
No fields: {}.
RestoreWorkspace
Section titled “RestoreWorkspace”POST /spin.v1.WorkspaceService/RestoreWorkspace
Put a stopped workspace’s disk back to one of its snapshots, or to what it was created from.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
snapshotId | string | One of this workspace’s own published snapshots. Empty restores what the workspace was created from - its image’s snapshot as it was at creation, not the one the image names now. |
withMemory | boolean | with_memory resumes the snapshot’s memory too: the workspace’s processes go on from the instant the snapshot was taken, running or stopped before. Only for a snapshot taken with memory; a running workspace is resumed only on its own host. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
RevokePortAccess
Section titled “RevokePortAccess”POST /spin.v1.WorkspaceService/RevokePortAccess
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
port | integer (int32) | |
userId | string |
Response
| Field | Type | What it is |
|---|---|---|
exposedPort | ExposedPort |
SetOwnerWord
Section titled “SetOwnerWord”POST /spin.v1.WorkspaceService/SetOwnerWord
Take an access the owner signed with a key of their keyring, and carry it to the guest: refused unless their newest keyring holds the key, of this workspace, at a counter past the one kept, saying what the first said of the workspace. The control plane writes no access; it only keeps and carries the owner’s.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
word | OwnerWord |
Response
No fields: {}.
SetPortAccess
Section titled “SetPortAccess”POST /spin.v1.WorkspaceService/SetPortAccess
Who may reach a published port, and who it is shared with.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
port | integer (int32) | |
access | PortAccess |
Response
| Field | Type | What it is |
|---|---|---|
exposedPort | ExposedPort |
SetWorkspaceNetworkTags
Section titled “SetWorkspaceNetworkTags”POST /spin.v1.WorkspaceService/SetWorkspaceNetworkTags
Change which egress policies a workspace runs under, while it runs.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
networkTags | list of string |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace | |
droppedConnections | integer (int32) | dropped_connections is how many of the machine’s open connections were cut, because the change took a policy away and what a policy no longer allows must not survive in a socket that was opened before it. Zero when the change only added. |
SetWorkspaceNetworkWatch
Section titled “SetWorkspaceNetworkWatch”POST /spin.v1.WorkspaceService/SetWorkspaceNetworkWatch
Watch where a workspace connects: its host records each lookup, each destination it is let through to and each it is refused, with the time, into the workspace’s logs.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
watch | boolean |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
StartWorkspace
Section titled “StartWorkspace”POST /spin.v1.WorkspaceService/StartWorkspace
Start a stopped workspace on its own disk, or resume a suspended one from the memory it kept.
Request
| Field | Type | What it is |
|---|---|---|
id | string | |
fromDisk | boolean | Boot a suspended workspace from its disk, dropping the memory it was suspended with: what is left when that memory was taken on a machine no host runs now (WORKSPACE_FAILURE_MACHINE_CHANGED). The guest boots as from a power cut. Refused for a workspace that is not suspended. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
StopWorkspace
Section titled “StopWorkspace”POST /spin.v1.WorkspaceService/StopWorkspace
Stop a running workspace. Its disk is its volume, kept as it is; no snapshot is taken.
Request
| Field | Type | What it is |
|---|---|---|
id | string | |
force | boolean | Force kill instead of graceful |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
SuspendWorkspace
Section titled “SuspendWorkspace”POST /spin.v1.WorkspaceService/SuspendWorkspace
Put a running workspace down with its processes where they are: its memory and its disk are checkpointed and the machine is stopped, and its next start resumes that instant - on any host carrying the same machine. The same thing a drained host does to what it runs. The guest is paused from the checkpoint until it is resumed: it does nothing in between, and nothing it did is given up. Answered once the memory is stored and the disk published. One that fails after the checkpoint lets the guest run on where it was.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace | |
snapshotId | string | snapshot_id is the checkpoint the next start resumes, and a snapshot like any other: it is listed, it can be restored by name, and deleting it is what makes the workspace start from its disk instead. |
UndeleteWorkspace
Section titled “UndeleteWorkspace”POST /spin.v1.WorkspaceService/UndeleteWorkspace
Take a workspace out of the trash, stopped, with its disk and snapshots as they were.
Request
| Field | Type | What it is |
|---|---|---|
id | string | The workspace’s id: a name is not unique among the ones in the trash. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
UnexposePort
Section titled “UnexposePort”POST /spin.v1.WorkspaceService/UnexposePort
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
port | integer (int32) |
Response
No fields: {}.
UpdateWorkspace
Section titled “UpdateWorkspace”POST /spin.v1.WorkspaceService/UpdateWorkspace
Update workspace properties (name, env)
Request
| Field | Type | What it is |
|---|---|---|
id | string | Required: workspace ID or name |
name | string | Optional: new name |
env | map of string to string | Optional: replace environment variables |
wakeOnAccess | boolean or null | Note: resource changes require stop/start Optional: Workspace.wake_on_access |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
WaitSnapshot
Section titled “WaitSnapshot”POST /spin.v1.WorkspaceService/WaitSnapshot
Wait for a snapshot to be published: until then it cannot be restored, cloned or diffed.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
snapshotId | string | |
timeoutSeconds | integer (int32) | At most 600; zero is 300. |
Response
| Field | Type | What it is |
|---|---|---|
snapshot | Snapshot |
WaitWorkspace
Section titled “WaitWorkspace”POST /spin.v1.WorkspaceService/WaitWorkspace
Wait for a workspace to reach a state: create, start and stop are answered once they are asked for, and this is how a caller learns they are done without polling.
Request
| Field | Type | What it is |
|---|---|---|
workspaceId | string | |
state | WorkspaceState | |
timeoutSeconds | integer (int32) | At most 600; zero is 300. |
Response
| Field | Type | What it is |
|---|---|---|
workspace | Workspace |
Generated by task reference from spin/internal/controlplane/apidocs/spin.v1.openapi.json at 8eee32b9d.
Documents Spinbox v20261019.02. This page as Markdown, for a model or a terminal.

