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

# Managing machines

> Every automation gets the boxd TypeScript SDK already signed in as this machine's account: create, exec, fork, snapshot and manage machines with no configuration.

`@boxd/run` re-exports the [boxd TypeScript SDK](/reference/typescript-sdk) as `boxd`, pre-authenticated as the account this machine belongs to. Import it and call it. Authentication is already handled.

```ts theme={"theme":"github-dark"}
import { boxd } from "@boxd/run";

const machines = await boxd.machines.list();
```

Everything the SDK offers is there: machines, snapshots, checkpoints, disks, env vars and secrets, domains, organizations, API keys. This page covers what is specific to using it from an automation. The method reference is the [SDK page](/reference/typescript-sdk).

## What it can reach

The client is scoped like the machine it runs on:

| Where the script runs                              | What `boxd` can manage                                                 |
| -------------------------------------------------- | ---------------------------------------------------------------------- |
| Your personal machine, or a private org-billed one | Your machines in that organization                                     |
| A shared org machine                               | The organization's shared machines only, never a member's private ones |
| An isolated machine                                | None. Isolated machines have no `run` and no SDK credential            |

This is the same rule the in-machine `boxd` CLI follows, so a script can do exactly what a shell on that machine can do.

## Fan work out to fresh machines

The reason to reach for the SDK from an automation is usually fan-out. Something happens, and you want one clean machine per unit of work rather than doing it all on the machine the script lives on.

```ts theme={"theme":"github-dark"}
// review-on-pr.run.ts
import { boxd, githubApp } from "@boxd/run";

githubApp.on("pull_request.opened", { repo: "acme/api" }, async (pr) => {
  const box = await boxd.machines.create({ fromSnapshot: "api-golden", name: `review-${pr.number}` });
  try {
    const r = await boxd.machines.exec(box.id, {
      command: ["sh", "-c", `git fetch origin pull/${pr.number}/head && git checkout FETCH_HEAD && claude -p 'Review the diff against main and print findings'`],
      timeout: 15 * 60_000,
    });
    const gh = await githubApp.client();
    await gh.rest.issues.createComment({ owner: "acme", repo: "api", issue_number: pr.number, body: r.stdout });
  } finally {
    await boxd.machines.delete(box.id);
  }
});
```

`machines.create({ fromSnapshot })` boots a copy of a [snapshot](/guides/snapshots) with everything already installed and running. `exec` collects `stdout`, `stderr`, `exitCode` and `success`. An array `command` is shell-quoted for you, and a string is passed to a shell as is.

## Fork the machine you are on

A [fork](/guides/fork) copies a running machine, memory and disk included, in about 160 ms. From a script that means "take a copy of exactly this state and try something on it":

```ts theme={"theme":"github-dark"}
import { boxd } from "@boxd/run";

const me = process.env.BOXD_VM_NAME!;
const fork = await boxd.machines.fork(me, { name: `${me}-experiment` });
const r = await boxd.machines.exec(fork.id, { command: ["sh", "-c", "npm test"] });
console.log(r.success ? "green on the fork" : r.stderr);
await boxd.machines.delete(fork.id);
```

A forked machine also inherits the automations of its source and starts them immediately, so forking is how an automation scales itself out. See [Jobs](/guides/automations/jobs#forks-and-snapshots).

## Checkpoint before a risky step

```ts theme={"theme":"github-dark"}
const me = process.env.BOXD_VM_NAME!;
await boxd.machines.checkpoints.create(me, "before-migration");
try {
  await riskyMigration();
} catch (e) {
  await boxd.machines.checkpoints.restore(me, "before-migration");   // back to the moment before
  throw e;
}
```

[Checkpoints](/guides/checkpoints) are per-machine save points, up to ten per machine.

## Keep a fleet alive on a schedule

```ts theme={"theme":"github-dark"}
import { boxd, every } from "@boxd/run";

every("1 hour", async () => {
  const stale = (await boxd.machines.list()).filter(
    (m) => m.name.startsWith("review-") && Date.now() - Date.parse(m.createdAt) > 6 * 3600_000,
  );
  for (const m of stale) await boxd.machines.delete(m.id);
});
```

## Your laptop, through the same object

`boxd.local` is the laptop bridge: files under your home directory and your own Chrome, via the [client utilities](/guides/client-utilities). It is covered in [Scripts](/guides/automations/scripts#boxdlocal-your-laptop) and [Browsers](/guides/automations/browser).

## Errors

SDK calls throw typed errors exactly as on the [SDK page](/reference/typescript-sdk#errors). A script that lets one escape a handler logs it and carries on. One that lets it escape the top level counts as a crash and enters the [retry ladder](/guides/automations/jobs#crashes-and-retries).
