> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ns.rocks/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Create and drive cloud machines for AI agents from TypeScript.

The Nullspace TypeScript SDK (`@nullspace/sdk`) gives you on-demand Linux
machines from Node or the browser. Its public surface mirrors the
[Python SDK](/guides/python-sdk/overview) camelCased — same resource names, same
namespacing, same error semantics — so one mental model teaches both languages.

## Install

```bash theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
npm install @nullspace/sdk@<version>
```

Requires Node 18+. WebSocket-backed surfaces (PTY, exec streaming, lifecycle
events) need a global `WebSocket`, which Node 22+ and all browsers provide.

## Configure

Authentication resolves from explicit options first, then the environment:

* `NULLSPACE_API_KEY` — required API key.
* `NULLSPACE_API_URL` (alias `NULLSPACE_BASE_URL`) — base URL.

```ts theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
import { NullspaceClient } from "@nullspace/sdk";

const client = new NullspaceClient({ apiKey: "ns_live_..." });
```

## Quickstart

Create → exec → file → destroy, in under 10 lines:

```ts theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
import { Machine } from "@nullspace/sdk";

await using machine = await Machine.create();

const result = await machine.commands.run("echo 'Hello!'", { shell: true });
console.log(result.stdout);

await machine.files.write("/hello.txt", "world");
console.log(await machine.files.read("/hello.txt"));
// `await using` destroys the machine when the scope exits.
```

## Resources

A `Machine` exposes namespaced resources, mirroring Python:

* `machine.commands` — `run` (with `onStdout` / `onStderr` streaming), `list`,
  `kill`, `sendStdin`, `getLogs`.
* `machine.files` — `read`, `write`, `list`, `exists`, `info`, `makeDir`,
  `remove`, `rename`, `upload` / `download` with progress callbacks.
* `machine.pty` — `open()` returns a handle (send input, resize, async-iterate
  output, `wait()`, `kill()`).
* `machine.code` — `run()` streams Jupyter-style execution events over SSE.
* `machine.lifecycle` — `list()` history and `subscribe()` live events.

Lifecycle and advanced primitives live on the machine or client:

```ts theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
const child = await machine.fork();            // copy-on-write fork
const snap = await machine.createSnapshot();   // durable snapshot
const resumed = await client.snapshots.resume(snap.id);
const preview = await machine.createSignedPreviewUrl(8080);

const vol = await client.volumes.create("data");
await machine.attachVolume(vol.id, "/data");

const template = await client.templates
  .builder()
  .fromUbuntuImage("22.04")
  .aptInstall(["curl"])
  .build({ name: "my-template" });
```

## Errors

Every failure is a typed subclass of `MachineError` with a stable `code`,
matching the Python hierarchy: `NotFoundError`, `AuthError`, `ConflictError`,
`QuotaExceededError`, `RateLimitError`, `TimeoutError`, `BuildError`,
`FileUploadError`, and more.

```ts theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
import { NotFoundError } from "@nullspace/sdk";

try {
  await client.machines.get("mch_missing");
} catch (err) {
  if (err instanceof NotFoundError) {
    // ...
  }
}
```

## Browser support

The REST and SSE core works in browsers; WebSocket (PTY, exec streaming,
lifecycle) and filesystem-path helpers are Node-first. WebSocket routes
authenticate with the `nullspace-api-key` subprotocol so browsers work without
setting headers. See the package README for the full support matrix.

## Not included

The MCP server and CLI remain Python-owned (`nullspace-sdk[cli,mcp]`). Some
advanced REST domains the Python SDK exposes are not yet wrapped in the
TypeScript surface; the per-operation coverage manifest lives in
`specs/client-surfaces/typescript-sdk.yaml`.
