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

# Run a sandbox

> Create a microVM sandbox, run commands in it, and destroy it.

For CLI setup and authentication, see [CLI Quickstart](/cli/quickstart).

## Create a sandbox

<CodeGroup>
  ```bash Bash theme={null}
  runcloud sandbox create --json
  ```

  ```typescript TypeScript theme={null}
  import { Client } from "@run-cloud/sdk";

  const cloud = new Client();
  const sandbox = await cloud.sandboxes.create({ image: "runcloud/agent-base" });

  console.log(sandbox.id, sandbox.state);
  ```
</CodeGroup>

With nothing specified you get the default reservation of 0.125 vCPU / 128 MiB.
Use exact resources when you need a different allocation:

<CodeGroup>
  ```bash Bash theme={null}
  runcloud sandbox create --cpu 2 --memory 4096 --json
  ```

  ```typescript TypeScript theme={null}
  await cloud.sandboxes.create({ cpu: 2, memory: 4096 });
  ```
</CodeGroup>

The response includes:

| Field        | Use                                                               |
| ------------ | ----------------------------------------------------------------- |
| `id`         | Sandbox id. Use it with `exec`, `get`, `snapshot`, and `destroy`. |
| `state`      | `running`, `paused`, `stopped`, `interrupted`, or `destroyed`.    |
| `image`      | Base image the sandbox booted from.                               |
| `milli_cpu`  | Reserved CPU in millicores — `125` is the 0.125 vCPU default.     |
| `mem_mb`     | Reserved memory in MiB. This is a hard ceiling.                   |
| `region`     | Where the sandbox was placed.                                     |
| `created_at` | Creation timestamp.                                               |

The TypeScript SDK adds camelCase aliases (`milliCpu`, `memMb`, `createdAt`)
alongside the raw API fields, so either spelling works.

## Run a command

<CodeGroup>
  ```bash Bash theme={null}
  runcloud sandbox exec sbx_abc123 "npm install && npm test"
  ```

  ```typescript TypeScript theme={null}
  const result = await cloud.sandboxes.exec(
    sandbox.id,
    "npm install && npm test",
  );

  console.log(result.exitCode);
  console.log(result.stdout);
  console.log(result.stderr);
  ```
</CodeGroup>

A string command runs through `/bin/sh -c`, so pipes and `&&` work. Pass an
array instead to execute a program directly without a shell:

```ts theme={null}
await cloud.sandboxes.exec(sandbox.id, ["node", "-e", "console.log(1)"]);
```

**A non-zero exit code is returned, not thrown.** Check `exitCode` yourself —
only transport and API failures raise `RunCloudError`. Exec requires the sandbox
to be `running`; a paused sandbox returns `409`.

## List and inspect

<CodeGroup>
  ```bash Bash theme={null}
  runcloud sandbox list --json
  runcloud sandbox list --state running --json
  runcloud sandbox logs sbx_abc123 --lines 200
  ```

  ```typescript TypeScript theme={null}
  const all = await cloud.sandboxes.list();
  const running = await cloud.sandboxes.list({ state: "running" });
  const one = await cloud.sandboxes.get(sandbox.id);
  ```
</CodeGroup>

You only ever see sandboxes owned by an organization you belong to.

## Destroy

<CodeGroup>
  ```bash Bash theme={null}
  runcloud sandbox rm sbx_abc123
  ```

  ```typescript TypeScript theme={null}
  await cloud.sandboxes.destroy(sandbox.id);
  ```
</CodeGroup>

Billing stops when the sandbox is destroyed. Wrap your work in `try/finally` so
a thrown error still tears the sandbox down:

```ts theme={null}
const sandbox = await cloud.sandboxes.create();
try {
  await cloud.sandboxes.exec(sandbox.id, "./run-job.sh");
} finally {
  await cloud.sandboxes.destroy(sandbox.id);
}
```

## Retry-safe creates

If your job runner might retry a create, pass an idempotency key. A repeat with
the same key returns the original sandbox instead of spawning — and billing — a
second one.

```ts theme={null}
await cloud.sandboxes.create({
  image: "runcloud/agent-base",
  idempotencyKey: jobId,
});
```

## Errors

| Status | Meaning                                                                 |
| ------ | ----------------------------------------------------------------------- |
| `400`  | Malformed `cpu`/`memory`, or an empty `cmd`.                            |
| `401`  | Missing or invalid API key.                                             |
| `402`  | Organization is over its credit limit or past its payment grace period. |
| `403`  | You are not a member of the requested organization.                     |
| `404`  | No such sandbox, or it belongs to another organization.                 |
| `409`  | The sandbox is not running (for example, `exec` on a paused sandbox).   |
| `429`  | The organization is at its 100 concurrent sandbox limit.                |
