> ## Documentation Index
> Fetch the complete documentation index at: https://opensandbox-oc-s-762ac928075c46d2828bcb22.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK

> Complete TypeScript SDK reference

## Installation

```bash theme={null}
npm install @opencomputer/sdk
```

```typescript theme={null}
import { Sandbox, Usage, Tags } from "@opencomputer/sdk";
import { Image } from "@opencomputer/sdk/dist/image.js";
import { Snapshots } from "@opencomputer/sdk/dist/snapshot.js";
```

***

## Sandbox

### Static Methods

#### `Sandbox.create(opts?): Promise<Sandbox>`

Create a new sandbox.

| Parameter    | Type                    | Default  | Description                                        |
| ------------ | ----------------------- | -------- | -------------------------------------------------- |
| `template`   | string                  | `"base"` | Template name                                      |
| `timeout`    | number                  | `0`      | Idle timeout in seconds                            |
| `apiKey`     | string                  | env var  | API key                                            |
| `apiUrl`     | string                  | env var  | API URL                                            |
| `envs`       | Record\<string, string> | —        | Environment variables                              |
| `metadata`   | Record\<string, string> | —        | Arbitrary metadata                                 |
| `cpuCount`   | number                  | —        | CPU cores                                          |
| `memoryMB`   | number                  | —        | Memory in MB                                       |
| `image`      | Image                   | —        | Declarative image definition (see [Image](#image)) |
| `snapshot`   | string                  | —        | Name of a pre-built snapshot                       |
| `onBuildLog` | `(log: string) => void` | —        | Build log callback (when using `image`)            |

```typescript theme={null}
const sandbox = await Sandbox.create({ template: "my-stack", timeout: 600 });
```

#### `Sandbox.connect(sandboxId, opts?): Promise<Sandbox>`

Connect to an existing sandbox.

| Parameter   | Type   | Description        |
| ----------- | ------ | ------------------ |
| `sandboxId` | string | Sandbox ID         |
| `apiKey`    | string | API key (optional) |
| `apiUrl`    | string | API URL (optional) |

```typescript theme={null}
const sandbox = await Sandbox.connect("sb-abc123");
```

#### `Sandbox.createFromCheckpoint(checkpointId, opts?): Promise<Sandbox>`

Create a new sandbox from a checkpoint.

| Parameter      | Type   | Default | Description                  |
| -------------- | ------ | ------- | ---------------------------- |
| `checkpointId` | string | —       | Checkpoint ID (**required**) |
| `timeout`      | number | `0`     | Idle timeout                 |
| `apiKey`       | string | env var | API key                      |
| `apiUrl`       | string | env var | API URL                      |

```typescript theme={null}
const forked = await Sandbox.createFromCheckpoint("cp-abc123");
```

#### `Sandbox.createCheckpointPatch(checkpointId, opts): Promise<PatchResult>`

Create a patch for a checkpoint.

| Parameter      | Type   | Required | Description       |
| -------------- | ------ | -------- | ----------------- |
| `checkpointId` | string | Yes      | Target checkpoint |
| `script`       | string | Yes      | Bash script       |
| `description`  | string | No       | Description       |
| `apiKey`       | string | No       | API key           |
| `apiUrl`       | string | No       | API URL           |

```typescript theme={null}
const result = await Sandbox.createCheckpointPatch("cp-abc", { script: "apt install -y curl" });
```

#### `Sandbox.listCheckpointPatches(checkpointId, opts?): Promise<PatchInfo[]>`

```typescript theme={null}
const patches = await Sandbox.listCheckpointPatches("cp-abc");
```

#### `Sandbox.deleteCheckpointPatch(checkpointId, patchId, opts?): Promise<void>`

```typescript theme={null}
await Sandbox.deleteCheckpointPatch("cp-abc", "pa-xyz");
```

### Instance Methods

#### `sandbox.kill(): Promise<void>`

Terminate the sandbox.

#### `sandbox.isRunning(): Promise<boolean>`

Check if the sandbox is running.

#### `sandbox.hibernate(): Promise<void>`

Snapshot VM state and stop. No compute cost while hibernated.

#### `sandbox.wake(opts?): Promise<void>`

Resume a hibernated sandbox.

| Parameter | Type   | Default | Description             |
| --------- | ------ | ------- | ----------------------- |
| `timeout` | number | `0`     | Idle timeout after wake |

#### `sandbox.setTimeout(timeout): Promise<void>`

Update the idle timeout.

| Parameter | Type   | Description            |
| --------- | ------ | ---------------------- |
| `timeout` | number | New timeout in seconds |

#### `sandbox.createCheckpoint(name): Promise<CheckpointInfo>`

Create a named checkpoint.

#### `sandbox.listCheckpoints(): Promise<CheckpointInfo[]>`

List all checkpoints for the sandbox.

#### `sandbox.restoreCheckpoint(checkpointId): Promise<void>`

Revert in-place to a checkpoint.

#### `sandbox.deleteCheckpoint(checkpointId): Promise<void>`

Delete a checkpoint.

#### `sandbox.createPreviewURL(opts): Promise<PreviewURLResult>`

| Parameter    | Type                     | Required | Description              |
| ------------ | ------------------------ | -------- | ------------------------ |
| `port`       | number                   | Yes      | Container port (1–65535) |
| `domain`     | string                   | No       | Custom domain            |
| `authConfig` | Record\<string, unknown> | No       | Auth configuration       |

#### `sandbox.listPreviewURLs(): Promise<PreviewURLResult[]>`

#### `sandbox.deletePreviewURL(port): Promise<void>`

### Properties

| Property    | Type       | Description                       |
| ----------- | ---------- | --------------------------------- |
| `sandboxId` | string     | Sandbox ID (readonly)             |
| `status`    | string     | Current status (readonly)         |
| `agent`     | Agent      | [Agent sessions](#agent)          |
| `exec`      | Exec       | [Command execution](#exec)        |
| `files`     | Filesystem | [File operations](#filesystem)    |
| `pty`       | Pty        | [Terminal sessions](#pty)         |
| `commands`  | Exec       | **Deprecated** — alias for `exec` |

### Types

#### SandboxOpts

```typescript theme={null}
interface SandboxOpts {
  template?: string;
  timeout?: number;
  apiKey?: string;
  apiUrl?: string;
  envs?: Record<string, string>;
  metadata?: Record<string, string>;
  cpuCount?: number;
  memoryMB?: number;
  image?: Image;
  snapshot?: string;
  onBuildLog?: (log: string) => void;
}
```

#### CheckpointInfo

```typescript theme={null}
interface CheckpointInfo {
  id: string;
  sandboxId: string;
  orgId: string;
  name: string;
  sandboxConfig: object;
  status: string;       // "processing" | "ready" | "failed"
  sizeBytes: number;
  createdAt: string;
}
```

#### PatchInfo

```typescript theme={null}
interface PatchInfo {
  id: string;
  checkpointId: string;
  sequence: number;
  script: string;
  description: string;
  strategy: string;     // "on_wake"
  createdAt: string;
}
```

#### PatchResult

```typescript theme={null}
interface PatchResult {
  patch: PatchInfo;
}
```

#### PreviewURLResult

```typescript theme={null}
interface PreviewURLResult {
  id: string;
  sandboxId: string;
  orgId: string;
  hostname: string;
  customHostname?: string;
  port: number;
  cfHostnameId?: string;
  sslStatus: string;
  authConfig?: object;
  createdAt: string;
}
```

***

## Usage & Tags

Query billing-aligned usage, inspect per-sandbox memory points, and
manage sandbox tags used for grouping. Full reference:
[Usage & Tags](/reference/typescript-sdk/usage).

<Note>
  **Preview:** Usage and tag APIs are new. Endpoints, response fields,
  and SDK method names may change before GA; temporary inaccuracies or
  rough edges are possible while the surface settles.
</Note>

```typescript theme={null}
const usage = new Usage("https://app.opencomputer.dev", process.env.OPENCOMPUTER_API_KEY!);
const tags = new Tags("https://app.opencomputer.dev", process.env.OPENCOMPUTER_API_KEY!);
```

### `usage.forSandbox(sandboxId, opts?): Promise<SandboxUsageResponse>`

Return 1-minute allocated and used memory points for one sandbox.
`from` and `to` accept ISO dates (`YYYY-MM-DD`) or RFC3339
timestamps; default window is the last hour.

```typescript theme={null}
const r = await usage.forSandbox("sb-abc123", {
  from: "2026-05-27T00:00:00Z",
  to: "2026-05-27T01:00:00Z",
});

console.log(r.totals.memoryAllocatedGbSeconds, r.totals.memoryUsedGbSeconds);
```

### `usage.bySandbox(opts?): Promise<UsageBySandboxResponse>`

Rank sandboxes by usage. Supports ISO date or RFC3339 `from` / `to`,
`filter`, `sort`, `limit`, and `cursor`.

```typescript theme={null}
const page = await usage.bySandbox({
  filter: { "tag:team": "payments" },
  limit: 20,
});
```

### `usage.byTag(tagKey, opts?): Promise<UsageByTagResponse>`

Group usage by one tag key, with an `untagged` sibling bucket.

```typescript theme={null}
const byTeam = await usage.byTag("team", {
  filter: { "tag:env": "prod" },
});
```

### `tags.set(sandboxId, tags): Promise<{ tags; tagsLastUpdatedAt }>`

Replace the full tag set for a sandbox. `{}` clears all tags.

```typescript theme={null}
await tags.set("sb-abc123", {
  team: "payments",
  env: "prod",
});
```

### `tags.get(sandboxId): Promise<{ tags; tagsLastUpdatedAt }>`

Read the current tag set for a sandbox.

```typescript theme={null}
const current = await tags.get("sb-abc123");
```

### `tags.listKeys(): Promise<TagKeyInfo[]>`

List tag keys seen in the organization.

```typescript theme={null}
const keys = await tags.listKeys();
```

All `*GbSeconds` fields are GiB-seconds. For example, 4096 MiB
provisioned for one minute reports `240` `memoryAllocatedGbSeconds`.

***

## Agent

Accessed via `sandbox.agent`.

### `sandbox.agent.start(opts?): Promise<AgentSession>`

Start an agent session.

| Parameter         | Type                             | Description              |
| ----------------- | -------------------------------- | ------------------------ |
| `prompt`          | string                           | Initial prompt           |
| `model`           | string                           | Claude model             |
| `systemPrompt`    | string                           | System prompt            |
| `allowedTools`    | string\[]                        | Restrict tools           |
| `permissionMode`  | string                           | Permission mode          |
| `maxTurns`        | number                           | Max turns (default: 50)  |
| `cwd`             | string                           | Working directory        |
| `mcpServers`      | Record\<string, McpServerConfig> | MCP servers              |
| `resume`          | string                           | Resume session ID        |
| `onEvent`         | (event: AgentEvent) => void      | Event callback           |
| `onError`         | (data: string) => void           | Stderr callback          |
| `onExit`          | (exitCode: number) => void       | Exit callback            |
| `onScrollbackEnd` | () => void                       | Scrollback done callback |

```typescript theme={null}
const session = await sandbox.agent.start({
  prompt: "Build a todo app",
  onEvent: (e) => console.log(e.type),
});
```

### `sandbox.agent.attach(sessionId, opts?): Promise<AgentSession>`

Reconnect to a running agent session. Accepts `onEvent`, `onError`, `onExit`, `onScrollbackEnd`.

### `sandbox.agent.list(): Promise<AgentSessionInfo[]>`

List all agent sessions.

### AgentSession

| Member              | Type             | Description                |
| ------------------- | ---------------- | -------------------------- |
| `sessionId`         | string           | Session ID                 |
| `done`              | Promise\<number> | Resolves with exit code    |
| `sendPrompt(text)`  | method           | Send follow-up prompt      |
| `interrupt()`       | method           | Interrupt current turn     |
| `configure(config)` | method           | Update agent configuration |
| `kill(signal?)`     | Promise\<void>   | Kill agent process         |
| `close()`           | method           | Close WebSocket            |

### Types

#### AgentEvent

```typescript theme={null}
interface AgentEvent {
  type: string;
  [key: string]: unknown;
}
```

#### McpServerConfig

```typescript theme={null}
interface McpServerConfig {
  command: string;
  args?: string[];
  env?: Record<string, string>;
}
```

***

## Exec

Accessed via `sandbox.exec`.

### `sandbox.exec.run(command, opts?): Promise<ProcessResult>`

Run a command synchronously.

| Parameter | Type                    | Default | Description                  |
| --------- | ----------------------- | ------- | ---------------------------- |
| `command` | string                  | —       | Shell command (**required**) |
| `timeout` | number                  | `60`    | Timeout in seconds           |
| `env`     | Record\<string, string> | —       | Environment variables        |
| `cwd`     | string                  | —       | Working directory            |

```typescript theme={null}
const result = await sandbox.exec.run("npm test", { cwd: "/app" });
```

### `sandbox.exec.start(command, opts?): Promise<ExecSession>`

Start a long-running command with streaming.

| Parameter               | Type                       | Description                              |
| ----------------------- | -------------------------- | ---------------------------------------- |
| `command`               | string                     | Command (**required**)                   |
| `args`                  | string\[]                  | Arguments                                |
| `env`                   | Record\<string, string>    | Environment variables                    |
| `cwd`                   | string                     | Working directory                        |
| `timeout`               | number                     | Timeout in seconds                       |
| `maxRunAfterDisconnect` | number                     | Seconds to keep running after disconnect |
| `onStdout`              | (data: Uint8Array) => void | Stdout callback                          |
| `onStderr`              | (data: Uint8Array) => void | Stderr callback                          |
| `onExit`                | (exitCode: number) => void | Exit callback                            |

```typescript theme={null}
const session = await sandbox.exec.start("node server.js", {
  onStdout: (data) => process.stdout.write(data),
});
```

### `sandbox.exec.background(command, opts?): Promise<ExecSession>`

Alias for `start`. Same signature and return type — use when the intent is "run this in the background and observe it".

### `sandbox.exec.shell(opts?): Promise<Shell>`

Open a stateful shell session whose `cwd`, env vars, and shell functions persist across `.run()` calls. Foreground-only. See the [full reference](/reference/typescript-sdk/exec#sandbox-exec-shell-opts).

```typescript theme={null}
const sh = await sandbox.exec.shell({ cwd: "/app" });
await sh.run("export NODE_ENV=test");
const r = await sh.run("npm test");
await sh.close();
```

### `sandbox.exec.attach(sessionId, opts?): Promise<ExecSession>`

Reconnect to a running exec session.

| Parameter         | Type                       | Description               |
| ----------------- | -------------------------- | ------------------------- |
| `sessionId`       | string                     | Session ID (**required**) |
| `onStdout`        | (data: Uint8Array) => void | Stdout callback           |
| `onStderr`        | (data: Uint8Array) => void | Stderr callback           |
| `onExit`          | (exitCode: number) => void | Exit callback             |
| `onScrollbackEnd` | () => void                 | Scrollback replay done    |

### `sandbox.exec.list(): Promise<ExecSessionInfo[]>`

List all exec sessions.

### `sandbox.exec.kill(sessionId, signal?): Promise<void>`

Kill an exec session. Default signal: `9` (SIGKILL).

### ExecSession

| Member            | Type             | Description                       |
| ----------------- | ---------------- | --------------------------------- |
| `sessionId`       | string           | Session ID                        |
| `done`            | Promise\<number> | Resolves with exit code           |
| `sendStdin(data)` | method           | Send input (string or Uint8Array) |
| `kill(signal?)`   | Promise\<void>   | Kill process                      |
| `close()`         | method           | Close WebSocket                   |

### Types

#### ProcessResult

```typescript theme={null}
interface ProcessResult {
  exitCode: number;
  stdout: string;
  stderr: string;
}
```

#### ExecSessionInfo

```typescript theme={null}
interface ExecSessionInfo {
  sessionID: string;
  sandboxID: string;
  command: string;
  args: string[];
  running: boolean;
  exitCode?: number;
  startedAt: string;
  attachedClients: number;
}
```

***

## Filesystem

Accessed via `sandbox.files`.

### `sandbox.files.read(path): Promise<string>`

Read a file as a UTF-8 string.

### `sandbox.files.readBytes(path): Promise<Uint8Array>`

Read a file as raw bytes.

### `sandbox.files.write(path, content): Promise<void>`

Write content to a file. Accepts `string` or `Uint8Array`.

### `sandbox.files.list(path?): Promise<EntryInfo[]>`

List directory contents. Default path: `"/"`.

### `sandbox.files.makeDir(path): Promise<void>`

Create a directory (recursive).

### `sandbox.files.remove(path): Promise<void>`

Delete a file or directory.

### `sandbox.files.exists(path): Promise<boolean>`

Check if a path exists. Client-side wrapper — attempts a read and returns `false` on error.

### Types

#### EntryInfo

```typescript theme={null}
interface EntryInfo {
  name: string;
  isDir: boolean;
  path: string;
  size: number;
}
```

***

## Pty

Accessed via `sandbox.pty`.

### `sandbox.pty.create(opts?): Promise<PtySession>`

Create an interactive terminal session.

| Parameter  | Type                       | Default | Description      |
| ---------- | -------------------------- | ------- | ---------------- |
| `cols`     | number                     | `80`    | Terminal columns |
| `rows`     | number                     | `24`    | Terminal rows    |
| `onOutput` | (data: Uint8Array) => void | —       | Output callback  |

### PtySession

| Member       | Type   | Description                       |
| ------------ | ------ | --------------------------------- |
| `sessionId`  | string | Session ID                        |
| `send(data)` | method | Send input (string or Uint8Array) |
| `close()`    | method | Close the PTY                     |

***

## Image

Fluent, immutable builder for declarative sandbox images. Each method returns a new `Image` instance.

### `Image.base(): Image`

Start from the default OpenSandbox environment (Ubuntu 22.04, Python, Node.js, build tools).

```typescript theme={null}
import { Image } from "@opencomputer/sdk";

const image = Image.base()
  .aptInstall(['curl', 'jq'])
  .pipInstall(['requests', 'pandas'])
  .env({ PROJECT_ROOT: '/workspace' })
  .workdir('/workspace');
```

### Builder Methods

| Method                                | Parameters               | Description                           |
| ------------------------------------- | ------------------------ | ------------------------------------- |
| `aptInstall(packages)`                | `string[]`               | Install system packages via apt-get   |
| `pipInstall(packages)`                | `string[]`               | Install Python packages via pip       |
| `runCommands(...cmds)`                | `string[]`               | Run shell commands during build       |
| `env(vars)`                           | `Record<string, string>` | Set environment variables             |
| `workdir(path)`                       | `string`                 | Set default working directory         |
| `addFile(remotePath, content)`        | `string, string`         | Embed a file with inline content      |
| `addLocalFile(localPath, remotePath)` | `string, string`         | Read a local file into the image      |
| `addLocalDir(localPath, remotePath)`  | `string, string`         | Read a local directory into the image |

### `image.toJSON(): ImageManifest`

Returns the image manifest as a plain object.

### `image.cacheKey(): string`

Computes a deterministic SHA-256 hash of the manifest for cache lookups.

***

## Snapshots

Standalone class — not a property on Sandbox.

### `new Snapshots(opts?)`

```typescript theme={null}
import { Snapshots } from "@opencomputer/sdk";

const snapshots = new Snapshots();
// or with explicit config:
const snapshots = new Snapshots({ apiKey: "...", apiUrl: "..." });
```

| Parameter | Type   | Description                                            |
| --------- | ------ | ------------------------------------------------------ |
| `apiKey`  | string | API key (falls back to `OPENCOMPUTER_API_KEY` env var) |
| `apiUrl`  | string | API URL (falls back to `OPENCOMPUTER_API_URL` env var) |

### `snapshots.create(opts): Promise<SnapshotInfo>`

Create a pre-built snapshot from a declarative image.

| Parameter     | Type                    | Required | Description                  |
| ------------- | ----------------------- | -------- | ---------------------------- |
| `name`        | string                  | Yes      | Unique snapshot name         |
| `image`       | Image                   | Yes      | Declarative image definition |
| `onBuildLogs` | `(log: string) => void` | No       | Build log streaming callback |

### `snapshots.list(): Promise<SnapshotInfo[]>`

List all snapshots for the current organization.

### `snapshots.get(name): Promise<SnapshotInfo>`

Get a snapshot by name.

### `snapshots.delete(name): Promise<void>`

Delete a snapshot. Existing sandboxes created from it are not affected.

### Types

#### SnapshotInfo

```typescript theme={null}
interface SnapshotInfo {
  id: string;
  name: string;
  status: string;       // "building" | "ready" | "failed"
  contentHash: string;
  checkpointId: string;
  manifest: object;
  createdAt: string;
  lastUsedAt: string;
}
```

***

## Secret Stores

### `SecretStore.create(opts)`

Create a new secret store.

```typescript theme={null}
import { SecretStore } from '@opencomputer/sdk';

const store = await SecretStore.create({
  name: 'my-agent-secrets',
  egressAllowlist: ['api.anthropic.com'],
});
```

<ParamField body="opts" type="CreateSecretStoreOpts" required>
  <Expandable title="properties">
    <ParamField body="name" type="string" required>
      Store name (unique per organization).
    </ParamField>

    <ParamField body="egressAllowlist" type="string[]" optional>
      Allowed egress hosts (e.g. `["api.anthropic.com"]`).
    </ParamField>
  </Expandable>
</ParamField>

**Returns:** `Promise<SecretStoreInfo>`

### `SecretStore.list(opts?)`

List all secret stores.

```typescript theme={null}
const stores = await SecretStore.list();
```

**Returns:** `Promise<SecretStoreInfo[]>`

### `SecretStore.get(storeId, opts?)`

Get a secret store by ID.

```typescript theme={null}
const store = await SecretStore.get('store-uuid');
```

<ParamField body="storeId" type="string" required>
  UUID of the secret store.
</ParamField>

**Returns:** `Promise<SecretStoreInfo>`

### `SecretStore.update(storeId, opts)`

Partial updates — only the fields you pass are changed.

```typescript theme={null}
const updated = await SecretStore.update('store-uuid', {
  name: 'new-name',
  egressAllowlist: ['api.anthropic.com', '*.openai.com'],
});
```

<ParamField body="storeId" type="string" required>
  UUID of the store to update.
</ParamField>

<ParamField body="opts" type="UpdateSecretStoreOpts" required>
  <Expandable title="properties">
    <ParamField body="name" type="string" optional>
      New store name.
    </ParamField>

    <ParamField body="egressAllowlist" type="string[]" optional>
      New allowed egress hosts.
    </ParamField>
  </Expandable>
</ParamField>

**Returns:** `Promise<SecretStoreInfo>`

### `SecretStore.delete(storeId, opts?)`

Deletes the store and all its secrets. Running sandboxes are not affected.

```typescript theme={null}
await SecretStore.delete('store-uuid');
```

**Returns:** `Promise<void>`

### `SecretStore.setSecret(storeId, name, value, opts?)`

Set a secret in a store. Secrets are encrypted at rest. The value is never returned by the API.

```typescript theme={null}
await SecretStore.setSecret('store-uuid', 'ANTHROPIC_API_KEY', 'sk-ant-...');
```

Optionally restrict which hosts can receive this secret:

```typescript theme={null}
await SecretStore.setSecret('store-uuid', 'ANTHROPIC_API_KEY', 'sk-ant-...', {
  allowedHosts: ['api.anthropic.com'],
});
```

<ParamField body="storeId" type="string" required>
  UUID of the secret store.
</ParamField>

<ParamField body="name" type="string" required>
  Secret name (used as the env var name in sandboxes).
</ParamField>

<ParamField body="value" type="string" required>
  Secret value (encrypted at rest, never returned by API).
</ParamField>

**Returns:** `Promise<void>`

### `SecretStore.listSecrets(storeId, opts?)`

Returns secret metadata only. Values are never exposed.

```typescript theme={null}
const entries = await SecretStore.listSecrets('store-uuid');
// [{ name: 'ANTHROPIC_API_KEY', allowedHosts: ['api.anthropic.com'], ... }, ...]
```

**Returns:** `Promise<SecretEntryInfo[]>`

### `SecretStore.deleteSecret(storeId, name, opts?)`

```typescript theme={null}
await SecretStore.deleteSecret('store-uuid', 'DATABASE_URL');
```

**Returns:** `Promise<void>`

### Creating a Sandbox with a Secret Store

Pass the `secretStore` option to `Sandbox.create()` to inject the store's secrets:

```typescript theme={null}
import { Sandbox } from '@opencomputer/sdk';

const sandbox = await Sandbox.create({
  secretStore: 'my-agent-secrets',
  timeout: 600,
});

// Secrets are available as sealed env vars
const result = await sandbox.commands.run('echo $ANTHROPIC_API_KEY');
// stdout: "osb_sealed_abc123..." (sealed, not the real key)

// But outbound HTTPS requests get the real value substituted by the proxy
const apiResult = await sandbox.commands.run(
  'curl -s https://api.anthropic.com/v1/messages -H "x-api-key: $ANTHROPIC_API_KEY" ...'
);
// The proxy replaces the sealed token with the real key before it hits Anthropic
```

### Types

#### SecretStoreInfo

| Property          | Type       | Description          |
| ----------------- | ---------- | -------------------- |
| `id`              | `string`   | Store UUID           |
| `orgId`           | `string`   | Organization UUID    |
| `name`            | `string`   | Store name           |
| `egressAllowlist` | `string[]` | Allowed egress hosts |
| `createdAt`       | `string`   | ISO 8601 timestamp   |
| `updatedAt`       | `string`   | ISO 8601 timestamp   |

#### SecretEntryInfo

| Property       | Type       | Description                       |
| -------------- | ---------- | --------------------------------- |
| `id`           | `string`   | Entry UUID                        |
| `storeId`      | `string`   | Parent store UUID                 |
| `name`         | `string`   | Secret name (env var name)        |
| `allowedHosts` | `string[]` | Host restrictions for this secret |
| `createdAt`    | `string`   | ISO 8601 timestamp                |
| `updatedAt`    | `string`   | ISO 8601 timestamp                |
