SDKs

Components

#SDKs

Clients for Sandbox API v1. They speak to any endpoint — local, self-hosted or cloud — and learn what it offers from capabilities().

SDK Status Tested
python/ (sandboxapi) standard library only; unix socket, http(s), private CA yes: make test-sdk runs it against a real sandboxd
typescript/ (sandboxapi) fetch-based: Node 18+, Deno, Bun, browsers; http(s) endpoints not yet run: written to the same contract, no Node in the development environment that wrote it

Both cover sandboxes, processes (run, background, output streaming, stdin, signals), files, suspend/resume and snapshots. Attach and tunnels (connection upgrades) are in the Go client and the CLI only, for now.

Against a gateway in front of many sandboxd nodes, both also have its user-facing calls (a plain sandboxd answers each with not_found):

Python TypeScript
whoami() whoami() the user, tenant, scopes and key id behind the API key
ssh_info() sshInfo() the SSH server's host and port, and the host keys to pin
add_ssh_key(key, sandbox="") addSSHKey(key, sandbox?) register an authorized_keys line; sandbox limits it to one
ssh_keys() sshKeys() your registered keys
remove_ssh_key(id) removeSSHKey(id)
ssh_access(ref, ttl_secs=0) sshAccess(ref, ttlSecs?) a short-lived login; its user is the token, and the whole credential until expires_at

And its jobs, agent runs and secrets — work the gateway runs after the request that started it has gone (docs/jobs.md):

Python TypeScript
create_job(spec) createJob(spec) start a job: command or agent + prompt/prompts, parallelism, completions, retries, timeout_secs, env, secrets, keep, notify, …
agent_run(agent, prompt, **opts) agentRun(agent, prompt, opts?) a job of one agent run
jobs() jobs() your jobs, newest first, without their runs
job(id) job(id) one job, with each run's state, exit code, attempts and sandbox
cancel_job(id) cancelJob(id) runs not started never are; running ones' sandboxes are terminated
job_output(id, run) jobOutput(id, run) what a run kept of its stdout and stderr
job_file(id, run, path) jobFile(id, run, path) a file a run kept (keep.files)
set_secret(name, value) setSecret(name, value) set one of the tenant's secrets; never returned
secrets() secrets() the tenant's secrets by name
delete_secret(name) deleteSecret(name)

And organizations (docs/organizations.md). A client made with org="acme" (Python) or { org: "acme" } (TypeScript), or derived with with_org("acme") / withOrg("acme"), sends X-Sandbox-Org: acme on every request, so everything it does acts in that organization; the gateway answers not_found for one the key's user is not a member of.

Python TypeScript
orgs() orgs() the organizations the key may act in, its own tenant first (default when unnamed)
create_org(name) createOrg(name) needs org:create; you become its owner
org_members(org) orgMembers(org) any member may list them
set_org_member(org, user, role="", tenant="") setOrgMember(org, user, {role?, tenant?}) owners add a member or change a role
remove_org_member(org, user, tenant="") removeOrgMember(org, user, tenant?) owners; what the member had open there ends at once

The gateway's admin calls (API keys, nodes, cordon) are in the Go client only; admin_orgs() / adminOrgs() lists every organization for an admin key.

Byte fields are bytes (bytes / Uint8Array); the wire format's base64 is handled inside. A sandbox has no repository: put code in with the files calls, or clone it inside the sandbox.

Edit on GitHubsdk/README.md