Patch a Workspace
const url = 'https://example.com/apis/nodus.dev/v1/namespaces/example/workspaces/example';const options = { method: 'PATCH', headers: {'Content-Type': 'application/merge-patch+json'}, body: '{}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PATCH \ --url https://example.com/apis/nodus.dev/v1/namespaces/example/workspaces/example \ --header 'Content-Type: application/merge-patch+json' \ --data '{}'Parameters
Section titled “ Parameters ”Path Parameters
Section titled “ Path Parameters ”The project.
The object’s name.
Query Parameters
Section titled “ Query Parameters ”Header Parameters
Section titled “ Header Parameters ”Request Bodyrequired
Section titled “ Request Bodyrequired ”object
Example generated
{}Responses
Section titled “ Responses ”OK
Workspace is a person’s GPU or CPU development machine with SSH, VS Code in the browser or on the desktop, JupyterLab, a persistent home Volume and schedules. Each running period is a session, recorded as an Attempt with its receipt (nodus get attempts -l nodus.dev/workspace=<name>).
object
object
object
object
object
object
object
WorkspaceSpec is the desired Workspace.
object
Connections inject their env and egress hosts (at most 4).
Env sets environment variables (at most 256). The NODUS_ prefix is reserved.
EnvVar is one environment variable: a literal value or a Secret key.
object
Name matches ^[A-Za-z_][A-Za-z0-9_]*$.
Value is the literal value.
EnvVarSource names where an env value comes from.
object
SecretKeySelector selects one key of a Secret.
object
Key is the key within it.
Name is the Secret.
Ephemeral runs without a home Volume: local files are lost when the Workspace stops.
IdleTimeout stops the Workspace after this long with no SSH session, tool traffic or Process (default 1h; 0s never stops it for idleness; otherwise 10m to 24h).
Image is the container image: a catalog image such as nodus/workspace-pytorch-cuda (the GPU default), nodus/workspace-cpu (the CPU default) or nodus/workspace-rocm, or your own image. It can change while the Workspace is stopped and applies on the next start.
ImagePullSecrets name Registry Secrets used to pull a private image (at most 4).
MaxCostUSD stops the Workspace once its charges reach this amount; it may only be raised.
Network sets egress for the container.
object
Egress is the outbound network policy.
object
Allow lists DNS names or *.suffix patterns (AllowList only; at most 128).
Policy is Deny, AllowList or Open.
Presets add curated host lists such as python-packages or huggingface.
Placement constrains where work may run.
object
Dedicated is reserved; only true is accepted.
Interruptible is Never, Allow (the scheduler decides by expected cost) or Prefer.
MaxRateUSDPerHour filters out offerings above this customer rate.
Offerings restricts placement to these Offerings.
Pool is a BYOC Pool in the project.
Profile is Balanced, Cost or Speed.
QueueTimeout is how long the Job may wait for capacity before failing with CapacityUnavailable (default 24h; 0s waits forever).
Regions are region classes (us, eu, …); empty means any.
Resources are capacity floors. For GPU work the offering’s host shape applies if larger.
object
CPU is the vCPU floor.
Disk is the ephemeral disk floor.
GPURequest asks for accelerators. A family (H100) matches any of its variants and never another family.
object
Count is the GPUs per node: 1, 2, 4 or 8.
Exact pins the exact variant instead of matching the family.
Interconnect is Any or NVLink.
MinMemory is the per-GPU memory floor.
Type lists 1–8 accelerator ids or families from the catalog.
Memory is the host memory floor.
Nodes above 1 is shorthand for spec.distributed.nodes and is stored in that form.
WorkspaceSchedule is one working window: the Workspace is ready by readyBy and stops at stopAt.
object
ReadyBy is when the Workspace must be ready; it starts 15 minutes earlier. At least 15 minutes from now.
StopAt is when the Workspace stops; after readyBy.
Secrets mount Secrets as env vars and 0400 files under /run/secrets/
SecretMount mounts one Secret, optionally pinned to a version. The bare name is accepted on write.
object
Name is the Secret.
Version pins a version; unset pins the latest at admission.
ServiceAccountName governs calls made from inside the Workspace (default “default”).
SSHKeys names the SSHKeys that may log in; empty means every key of the org’s members who may use this project (at most 100). Removing a key ends the sessions it opened.
State is Running (the default) or Stopped. Stopping saves /home/nodus and releases the machine.
Tools lists the tools to serve (default VSCode, Jupyter and SSH).
Volume is a ReadWriteOnce Volume mounted at /home/nodus and saved on every stop. Exactly one of volume and ephemeral: true.
WorkspaceStatus is the observed Workspace.
object
Conditions are Scheduled, Funded, Ready, Stopped, NodeUnreachable, SetupComplete and StateSaved.
object
WorkspaceConnect says how to reach the Workspace.
object
WorkspaceURL is one browser tool’s address.
object
URL opens the tool.
WorkspaceSSHConnect is the SSH entry of a Workspace.
object
Command connects from a terminal.
Host is ProxyCommand nodus ssh-proxy %h.
HostKey is the Workspace’s SSH host key (ssh-ed25519 …); it stays the same across sessions, and nodus ssh pins it for the host.
WorkspaceURL is one browser tool’s address.
object
URL opens the tool.
Cost is status.cost on every kind that spends money. It is a display copy of the ledger: amounts are decimal USD strings, and nothing is charged from these fields.
object
CostSegments splits a charge by billing segment.
object
BootUSD is the charge from the start of billing until the program started.
CoveredByNodus lists the segments (Boot, Running, Restore, Teardown) with time Nodus paid for instead of charging it, such as the start and teardown of a run that failed because of Nodus.
RestoreUSD is the charge for bringing a replacement up after capacity was lost.
RunningUSD is the charge while the program ran.
TeardownUSD is the charge from stop until deletion was confirmed, with the billing increment.
Final is true once the final charge has posted.
FundedUntilTime is when the current holds stop paying for the object.
HeldUSD is what is currently held for it.
LimitUSD is the object’s maxCostUSD, if it has one.
RateUSDPerHour is the sum of the hourly rates of its capacity that is still billing.
TotalUSD is what has been charged for this object so far.
Endpoints are the preview URLs of the browser tools.
WorkspaceEndpoint is one preview URL.
object
Name is the tool or port name.
Port is the container port.
URL is the preview address.
Estimate is returned in status.estimate by a dry-run (?dryRun=All) and on create for every compute kind (ADR-031). Amounts are decimal USD strings; the ETag of the dry-run response binds a later create to it.
object
AssemblyBoundUSD is the most a multi-node Job can cost if its members never assemble.
BlockingReasons say why a real create would fail now, with the amounts and a fix.
BlockingReason says why a create would fail now.
object
Code is the error code the create would return, for example InsufficientCredits.
Fix says what to do.
Message states the reason with the amounts involved.
ConcurrentHoldUSD is the total of the holds for every slot that starts at once.
USDBand is a median and a 90th-percentile amount in USD.
object
P50 is the median amount.
P90 is the 90th-percentile amount.
GangHoldUSD is the total of the member holds of a multi-node Job.
HoldUSD is the first hold that must fit your balance, every matching Budget and the object’s own cap.
MinimumChargeUSD is the billing increment rounding charged once per allocation.
USDBand is a median and a 90th-percentile amount in USD.
object
P50 is the median amount.
P90 is the 90th-percentile amount.
PlacementPreview is the customer-safe description of the capacity a create would use.
object
Explain is the scheduler’s explanation, the same shape as Attempt status.placement.explain.
Interruptible reports whether the capacity can be reclaimed.
Offering is the offering id, for example h100-sxm-80g-x8-us.
RegionClass is the region class of the offering.
WarmReuse reports whether warm capacity would be reused.
PricebookVersion is the price book the estimate used.
RateUSDPerHour is the hourly rate of the chosen capacity.
StartupEstimate is the expected time to start.
object
DurationBand is a median and a 90th-percentile duration, as Go duration strings.
object
P50 is the median duration.
P90 is the 90th-percentile duration.
DurationBand is a median and a 90th-percentile duration, as Go duration strings.
object
P50 is the median duration.
P90 is the 90th-percentile duration.
Topology is the resolved multi-node topology of a gang Job.
ValidUntil is when the prices this estimate used stop being current. A create bound by If-Match is admitted after it too, and never placed above rateUSDPerHour plus 10 %.
Warnings are non-blocking notes, for example ColdStart or InterruptibleSelected.
EstimateWarning is a non-blocking note on an estimate.
object
Code is the CamelCase warning code.
Message explains the warning.
HandledRequests records the request annotations already acted on.
object
WorkspaceHome is the saved state of the home directory.
object
Revision is the Volume revision the last stop committed; zero before the first save.
SavedTime is when that revision was committed.
Volume is the home Volume.
LastActivityTime is the last SSH session, tool request or Process seen; idleTimeout counts from it.
WorkspaceSessionReceipt is what one finished session cost.
object
Attempt is the session’s Attempt.
BilledSeconds is the time charged, from supplier billing start to confirmed deletion.
ChargeUSD is what the session cost.
EndTime is when its capacity was released.
StartTime is when the session started.
StopReason is why the session ended.
Message explains the phase.
NextScheduledStartTime is when the schedule will next start the Workspace (15 minutes before readyBy).
ObservedGeneration is the spec generation this status reflects.
Phase is Pending, Starting, Running, Recovering, Stopping, Stopped, Terminating or Failed.
Reason is a machine-readable cause of the phase.
WorkspaceSession is the running session.
object
Attempt is the session’s Attempt.
Offering is the capacity the session runs on.
RateUSDPerHour is the rate frozen for the session.
RegionClass is the region class of that capacity.
StartTime is when the session’s tools first answered; empty while starting.
DurationBand is a median and a 90th-percentile duration, as Go duration strings.
object
P50 is the median duration.
P90 is the 90th-percentile duration.
StopByTime is the funded edge while Funded is False: a money-driven stop commits the home until then and stops without the commit once it passes (ADR-086).
StopReason says why the Workspace is stopped; empty while it runs.
Example generated
{ "apiVersion": "example", "kind": "example", "metadata": { "annotations": { "additionalProperty": "example" }, "creationTimestamp": "example", "deletionGracePeriodSeconds": 1, "deletionTimestamp": "example", "finalizers": [ "example" ], "generateName": "example", "generation": 1, "labels": { "additionalProperty": "example" }, "managedFields": [ { "apiVersion": "example", "fieldsType": "example", "fieldsV1": { "additionalProperty": "example" }, "manager": "example", "operation": "example", "subresource": "example", "time": "example" } ], "name": "example", "namespace": "example", "ownerReferences": [ { "apiVersion": "example", "blockOwnerDeletion": true, "controller": true, "kind": "example", "name": "example", "uid": "example" } ], "resourceVersion": "example", "selfLink": "example", "uid": "example" }, "spec": { "connections": [ "example" ], "env": [ { "name": "example", "value": "example", "valueFrom": { "secretKeyRef": { "key": "example", "name": "example" } } } ], "ephemeral": true, "idleTimeout": "example", "image": "example", "imagePullSecrets": [ "example" ], "maxCostUSD": "example", "network": { "egress": { "allow": [ "example" ], "policy": "example", "presets": [ "example" ] } }, "placement": { "dedicated": true, "interruptible": "example", "maxRateUSDPerHour": "example", "offerings": [ "example" ], "pool": "example", "profile": "example", "queueTimeout": "example", "regions": [ "example" ] }, "resources": { "cpu": "example", "disk": "example", "gpu": { "count": 1, "exact": true, "interconnect": "example", "minMemory": "example", "type": [ "example" ] }, "memory": "example", "nodes": 1 }, "schedule": { "readyBy": "example", "stopAt": "example" }, "secrets": [ { "name": "example", "version": 1 } ], "serviceAccountName": "example", "sshKeys": [ "example" ], "state": "example", "tools": [ "example" ], "volume": "example" }, "status": { "conditions": [ { "lastTransitionTime": "example", "message": "example", "observedGeneration": 1, "reason": "example", "status": "example", "type": "example" } ], "connect": { "jupyter": { "url": "example" }, "ssh": { "command": "example", "host": "example", "hostKey": "example" }, "vscode": { "url": "example" } }, "cost": { "bySegment": { "bootUSD": "example", "coveredByNodus": [ "example" ], "restoreUSD": "example", "runningUSD": "example", "teardownUSD": "example" }, "final": true, "fundedUntilTime": "example", "heldUSD": "example", "limitUSD": "example", "rateUSDPerHour": "example", "totalUSD": "example" }, "endpoints": [ { "name": "example", "port": 1, "url": "example" } ], "estimate": { "assemblyBoundUSD": "example", "blockingReasons": [ { "code": "example", "fix": "example", "message": "example" } ], "concurrentHoldUSD": "example", "costUSD": { "p50": "example", "p90": "example" }, "gangHoldUSD": "example", "holdUSD": "example", "minimumChargeUSD": "example", "overheadUSD": { "p50": "example", "p90": "example" }, "placementPreview": { "explain": "example", "interruptible": true, "offering": "example", "regionClass": "example", "warmReuse": true }, "pricebookVersion": "example", "rateUSDPerHour": "example", "startup": { "cold": { "p50": "example", "p90": "example" }, "warm": { "p50": "example", "p90": "example" } }, "topology": "example", "validUntil": "example", "warnings": [ { "code": "example", "message": "example" } ] }, "handledRequests": { "additionalProperty": "example" }, "home": { "revision": 1, "savedTime": "example", "volume": "example" }, "lastActivityTime": "example", "lastSession": { "attempt": "example", "billedSeconds": 1, "chargeUSD": "example", "endTime": "example", "startTime": "example", "stopReason": "example" }, "message": "example", "nextScheduledStartTime": "example", "observedGeneration": 1, "phase": "example", "reason": "example", "session": { "attempt": "example", "offering": "example", "rateUSDPerHour": "example", "regionClass": "example", "startTime": "example" }, "startEstimate": { "p50": "example", "p90": "example" }, "stopByTime": "example", "stopReason": "example" }}default
Section titled “ default ”An error: a metav1.Status whose reason is a registered code.
Status is the error body of every API response: a Kubernetes metav1.Status (so kubectl and client-go understand it) plus three top-level extensions that those clients ignore (ADR-028).
object
object
object
Docs is the URL of the code’s docs page.
Fix says what to do next, for example a CLI command or the field to change.
object
object
RequestID identifies the request in logs and support tickets.
Example generated
{ "apiVersion": "example", "code": 1, "details": { "causes": [ { "field": "example", "message": "example", "reason": "example" } ], "group": "example", "kind": "example", "name": "example", "retryAfterSeconds": 1, "uid": "example" }, "docs": "example", "fix": "example", "kind": "example", "message": "example", "metadata": { "continue": "example", "remainingItemCount": 1, "resourceVersion": "example", "selfLink": "example", "shardInfo": { "selector": "example" } }, "reason": "example", "requestId": "example", "status": "example"}