Everything public in github.com/xshellz/xshellz-go. All calls take a
context.Context; cancellation aborts the HTTP request or kills the remote
SSH command. Also rendered on
pkg.go.dev.
Words used below:
- Control plane — the xShellz REST API (
https://api.xshellz.com/v1), authenticated with your personal access token. - Data plane — a direct SSH connection to the box (as root), authenticated with a per-sandbox ed25519 key that never leaves your machine.
Spawns a new sandbox and returns a live handle. Synchronous — the box is
running when it returns. Generates a fresh in-memory ed25519 keypair; keep
sbx.PrivateKeyPEM() if you want to Connect from another process later.
CreateOptions{Name, APIKey, APIURL}— all optional;nilis valid.- Errors:
ErrNoAPIKey,ErrQuota(concurrent box limit),ErrAuth.
Returns a handle to the box with exactly this name, creating it if needed —
the "permanent named box" entrypoint (see the README recipe).
- Not found → creates the box and (keystore on, the default) persists the
private key to
<KeystoreDir>/<sanitized-name>.pem(0600). - Found → resolves the key (
PrivateKeyPEMoption wins, else keystore file), attaches, and callsStartfirst if the box is stopped. GetOrCreateOptions{APIKey, APIURL, PrivateKeyPEM, KeystoreDir, DisableKeystore}.- The returned handle is already detached, so
Closeleaves the box alive (a permanent box should outlive your program). CallKillto destroy it. - Errors:
ErrNoAPIKey,ErrAuth,ErrQuota,ErrMissingKey(box exists, no key found — the message says which file was expected).
Attaches to an existing sandbox by UUID with an explicit PEM private key.
Errors: ErrNoAPIKey, ErrNotFound, key parse errors.
All the account's sandboxes (running, stopped, provisioning).
GetBoxfile(ctx, opts *ConnectOptions) (string, error) / SetBoxfile(ctx, manifest string, opts *ConnectOptions) (string, error)
Account-level xshellz.box provisioning template (GET/PUT /v1/shells/agent/boxfile). Applied when a new box is created — seeded to
~/xshellz.box and used to preinstall packages. GetBoxfile returns ""
when nothing is saved; SetBoxfile returns the stored manifest, and an empty
manifest clears the template (sent as JSON null). Manifest max size:
16 KB.
~/.xshellz/keys resolved via os.UserHomeDir.
Sorted languages RunCode accepts: bash, node, php, python, ruby.
Runs cmd over SSH and waits. A non-zero exit code is data
(RunResult.ExitCode), not an error; errors mean transport failure, context
cancellation, or ErrNotRunning.
RunOptions{Cwd, Env, Stdout, Stderr}— withCwd/Envthe command is wrapped ascd CWD && env K=V ... sh -c 'CMD';Stdout/Stderrstream live in addition to being captured.RunResult{Stdout, Stderr string; ExitCode int}.
Writes code to a unique temp file (/tmp/xshellz-code-<rand>.<ext>), runs
the interpreter (python→python3, node, bash, ruby, php), always
deletes the temp file, and returns the same RunResult as Run. Unknown
language → ErrUnsupportedLanguage (message lists the supported set).
Starts cmd detached (nohup bash -c, output to
~/.xshellz/jobs/<id>.log) and returns a JobHandle. SpawnOptions.Name
prefixes the job id (sanitized). The job survives your program exiting but
not the box stopping/restarting.
Lists spawned jobs: Job{ID string; PID int; LogPath string; Running bool}.
Log files persist after a job exits — delete them on the box when done.
Fields: ID string, PID int, LogPath string.
| Method | What it does |
|---|---|
IsRunning(ctx) (bool, error) |
kill -0 probe of the job's pid |
Logs(ctx, tailLines int) (string, error) |
last tailLines log lines (≤0 → 100), combined stdout+stderr |
Stop(ctx) error |
SIGTERM, then SIGKILL after ~5s if still alive; no-op if already dead |
| Method | What it does |
|---|---|
WriteFile(ctx, remotePath string, data []byte) error |
bytes → box (parent dirs created) |
ReadFile(ctx, remotePath string) ([]byte, error) |
box → bytes |
Upload(ctx, localPath, remotePath string) error |
local file → box |
Download(ctx, remotePath, localPath string) error |
box → local file (mode 0644) |
Binary-safe (rides cat over SSH exec); whole files buffer in memory. All
return ErrNotRunning on a stopped box; a failing remote command surfaces
its stderr in the error.
GET /v1/shells/agent/{uuid}/stats. Wire fields (snake_case) map 1:1:
| Field | Wire | Meaning |
|---|---|---|
MemUsedMB / MemLimitMB / MemAllowedMB |
mem_used_mb … |
memory current / cgroup limit / plan ceiling (MB) |
CPUPercent / CPUAllowedVCPUs / CPUThrottledPeriods |
cpu_percent … |
CPU now (100 = 1 vCPU) / plan ceiling / throttle count |
PidsCurrent / PidsAllowed |
pids_current … |
processes now / plan ceiling |
DiskUsedMB / DiskAllowedMB |
disk_used_mb … |
disk now / plan ceiling (MB) |
NetRxMB / NetTxMB |
net_rx_mb … |
network totals (MB) |
BlkReadMB / BlkWriteMB |
blk_read_mb … |
block IO totals (MB) |
GET /v1/shells/agent/{uuid}/procs →
SandboxProcs{Procs []ProcessInfo; Sessions int; Agents []string; DiskUsedMB, DiskAllowedMB int}
with ProcessInfo{PID int; Comm string; CPU, Mem float64} (top processes,
active SSH sessions, detected coding agents).
GET /v1/shells/agent/{uuid}/terminal → a signed browser-terminal URL. The
embedded HMAC token expires after ~1 hour; mint fresh, don't store.
| Method | What it does |
|---|---|
Start(ctx) error |
resume an idle-stopped box (POST .../start); refreshes info, redials SSH lazily |
Restart(ctx) error |
reboot a running box (POST .../restart); /home preserved, processes/jobs are not |
Detach() |
make Close keep the box (drop SSH only) |
Close(ctx) error |
drop SSH + destroy the box (DELETE) unless detached; idempotent |
Kill(ctx) error |
drop SSH + destroy the box unconditionally (even if detached, e.g. a GetOrCreate box); idempotent, swallows 404 |
UUID() string |
sandbox id |
Status() string |
last-known status: StatusCreating / StatusRunning / StatusStopped (not auto-refreshed) |
SSHHost() string / SSHPort() int / SSHCommand() string |
public SSH endpoint / copy-paste one-liner |
Info() SandboxInfo |
full control-plane view (uuid, name, status, ssh endpoint, always-on, trial hours, isolation, timestamps) |
PrivateKeyPEM() []byte |
the box's PEM private key (persist to reattach later) |
Sentinels (errors.Is): ErrNoAPIKey, ErrAuth, ErrQuota, ErrNotFound,
ErrNotRunning, ErrMissingKey, ErrUnsupportedLanguage.
API failures additionally match errors.As(err, &apiErr) with
type APIError struct {
StatusCode int // HTTP status
Code string // machine code when present (e.g. "verification_required")
Message string // human-readable API message
Body string // raw response body
}DefaultAPIURL=https://api.xshellz.com/v1StatusCreating,StatusRunning,StatusStopped