Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions docs/codedocs/api-reference/box-error.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "BoxError"
description: "SDK error type that includes optional HTTP status codes."
---

**Source**: `packages/sdk/src/client.ts`

`BoxError` is thrown for SDK-level failures, HTTP errors, timeout errors, and parsing issues. It extends `Error` and includes an optional `statusCode` when the error originates from an HTTP response.

## When it is thrown
The SDK throws `BoxError` in several situations: missing credentials, non-2xx API responses, timeouts enforced by `AbortController`, and structured-output parsing failures. For example, `Box.create()` throws immediately if no API key is provided, and `agent.run()` throws if `responseSchema` parsing fails. These errors all share the same class so you can handle them consistently.

## Constructor
```ts
new BoxError(message: string, statusCode?: number)
```

## Properties
| Property | Type | Description |
|---------|------|-------------|
| name | `string` | Always `"BoxError"`. |
| message | `string` | Error message. |
| statusCode | `number \| undefined` | HTTP status if available. |

## Example
```ts
import { Box } from "@upstash/box";

try {
await Box.create();
} catch (err) {
if (err instanceof Error) {
console.error(err.name, err.message);
}
}
```

## Handling patterns
If you want to surface API failures to a user, check `statusCode` and map 401/403 errors to authentication issues, 429 to rate limits, and 5xx to transient failures. For timeouts, the SDK message is usually `"Request timeout"` or `"Run timed out"`. You can retry those selectively without retrying schema parsing errors, which typically indicate a prompt mismatch.

In typed codebases, you can use `err instanceof BoxError` to branch on Box-specific failures. This keeps your error handling narrower and avoids catching unrelated errors thrown by your own code.

When debugging, log both `message` and `statusCode` to differentiate authentication problems from runtime errors. If the status code is missing, the error likely occurred client-side (for example, a timeout or schema parsing failure) rather than from the HTTP response itself.
202 changes: 202 additions & 0 deletions docs/codedocs/api-reference/box.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
---
title: "Box"
description: "Create and manage durable sandboxed boxes with agents, exec, files, git, schedules, and snapshots."
---

**Source**: `packages/sdk/src/client.ts`

The `Box` class is the primary SDK surface. It represents a sandboxed workspace with a runtime, filesystem, and optional AI agent. You create a Box with `Box.create()` or reconnect to one with `Box.get()`.

## Constructor (static)
```ts
static create<TProvider = unknown>(config?: BoxConfig): Promise<Box<TProvider>>
```

**BoxConfig parameters**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| apiKey | `string` | `process.env.UPSTASH_BOX_API_KEY` | API key for Box authentication. |
| baseUrl | `string` | `https://us-east-1.box.upstash.com` | Base URL for the Box API. |
| name | `string` | — | Human-readable name for the box. |
| runtime | `"node" \| "python" \| "golang" \| "ruby" \| "rust"` | — | Runtime environment for the box. |
| size | `"small" \| "medium" \| "large"` | `"small"` | Resource size preset. |
| agent | `AgentConfig` | — | Agent provider/model configuration. |
| git | `{ token?: string; userName?: string; userEmail?: string }` | — | GitHub token and optional git identity. |
| env | `Record<string, string>` | — | Environment variables injected into the box. |
| attachHeaders | `Record<string, Record<string, string>>` | — | Secret headers injected into outbound HTTPS requests. |
| networkPolicy | `NetworkPolicy` | `{ mode: "allow-all" }` | Outbound network access policy. |
| skills | `string[]` | — | Skills to enable (owner/repo paths). |
| mcpServers | `McpServerConfig[]` | — | MCP servers to attach. |
| timeout | `number` | `600000` | Request timeout in milliseconds. |
| debug | `boolean` | `false` | Enable debug logging. |

**Example**
```ts
import { Box, Agent, ClaudeCode } from "@upstash/box";

const box = await Box.create({
runtime: "node",
agent: { provider: Agent.ClaudeCode, model: ClaudeCode.Sonnet_4_5 },
env: { NODE_ENV: "production" },
});
```

## Static methods

### `Box.get()`
```ts
static get<TProvider = unknown>(boxId: string, options?: BoxGetOptions): Promise<Box<TProvider>>
```
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| boxId | `string` | — | Box ID to reconnect to. |
| options.apiKey | `string` | `process.env.UPSTASH_BOX_API_KEY` | API key. |
| options.baseUrl | `string` | `https://us-east-1.box.upstash.com` | API base URL. |
| options.gitToken | `string` | — | GitHub token used for git operations. |
| options.timeout | `number` | `600000` | Request timeout. |
| options.debug | `boolean` | `false` | Enable debug logging. |

### `Box.getByName()`
```ts
static getByName<TProvider = unknown>(name: string, options?: BoxGetOptions): Promise<Box<TProvider>>
```
Alias for `Box.get()` in this SDK version (name is treated as ID by the backend).

### `Box.list()`
```ts
static list(options?: ListOptions): Promise<BoxData[]>
```

### `Box.delete()`
```ts
static delete(options: BoxConnectionOptions & { boxIds: string | string[] }): Promise<void>
```

### `Box.fromSnapshot()`
```ts
static fromSnapshot<TProvider = unknown>(snapshotId: string, config?: BoxConfig): Promise<Box<TProvider>>
```

## Instance namespaces

### `box.agent`
```ts
run<T>(options: RunOptions<T, TProvider>): Promise<Run<T | string>>
stream(options: StreamOptions<TProvider>): Promise<StreamRun<string, Chunk>>
```

### `box.exec`
```ts
command(command: string): Promise<Run<string>>
code(options: CodeExecutionOptions): Promise<Run<string>>
stream(command: string): Promise<StreamRun<string, ExecStreamChunk>>
streamCode(options: CodeExecutionOptions): Promise<StreamRun<string, ExecStreamChunk>>
```

### `box.files`
```ts
read(path: string, options?: { encoding?: "base64" }): Promise<string>
write(options: { path: string; content: string; encoding?: "base64" }): Promise<void>
list(path?: string): Promise<FileEntry[]>
upload(files: UploadFileEntry[]): Promise<void>
download(options?: { folder?: string }): Promise<void>
```

### `box.git`
```ts
clone(options: GitCloneOptions): Promise<void>
diff(): Promise<string>
status(): Promise<string>
commit(options: GitCommitOptions): Promise<GitCommitResult>
updateConfig(options: GitConfigUpdateOptions): Promise<GitConfig>
push(options?: { branch?: string }): Promise<void>
createPR(options: GitPROptions): Promise<PullRequest>
exec(options: GitExecOptions): Promise<GitExecResult>
checkout(options: GitCheckoutOptions): Promise<void>
```

### `box.schedule`
```ts
exec(options: ExecScheduleOptions): Promise<Schedule>
agent(options: AgentScheduleOptions<TProvider>): Promise<Schedule>
list(): Promise<Schedule[]>
get(id: string): Promise<Schedule>
pause(id: string): Promise<void>
resume(id: string): Promise<void>
delete(id: string): Promise<void>
```

### `box.skills`
```ts
add(skillId: string): Promise<void>
remove(skillId: string): Promise<void>
list(): Promise<string[]>
```

## Lifecycle and config

### `box.cd()`
```ts
cd(path: string): Promise<void>
```
Changes the SDK-tracked working directory after verifying the path exists.

### `box.getStatus()`
```ts
getStatus(): Promise<{ status: string }>
```

### `box.configureModel()`
```ts
configureModel(model: string): Promise<void>
```

### `box.updateNetworkPolicy()`
```ts
updateNetworkPolicy(policy: NetworkPolicy): Promise<void>
```

### `box.pause()` / `box.resume()` / `box.delete()`
```ts
pause(): Promise<void>
resume(): Promise<void>
delete(): Promise<void>
```

## Snapshots
```ts
snapshot(options: { name: string }): Promise<Snapshot>
listSnapshots(): Promise<Snapshot[]>
deleteSnapshot(snapshotId: string): Promise<void>
```

## Logs and runs
```ts
logs(options?: { offset?: number; limit?: number }): Promise<LogEntry[]>
listRuns(): Promise<BoxRunData[]>
```

## Previews
```ts
getPreviewUrl(port: number, options?: { bearerToken?: boolean; basicAuth?: boolean }): Promise<Preview>
listPreviews(): Promise<{ previews: Preview[] }>
deletePreview(port: number): Promise<void>
```

## Example: Combine agent + git + files
```ts
import { Box, Agent, ClaudeCode } from "@upstash/box";

const box = await Box.create({
runtime: "node",
agent: { provider: Agent.ClaudeCode, model: ClaudeCode.Sonnet_4_5 },
git: { token: process.env.GITHUB_TOKEN },
});

await box.git.clone({ repo: "https://github.com/example/project" });
await box.agent.run({ prompt: "Add a CONTRIBUTING.md file" });
const diff = await box.git.diff();
console.log(diff.slice(0, 200));

await box.delete();
```
95 changes: 95 additions & 0 deletions docs/codedocs/api-reference/ephemeral-box.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
---
title: "EphemeralBox"
description: "Create short-lived boxes optimized for exec and file operations."
---

**Source**: `packages/sdk/src/client.ts`

`EphemeralBox` is a lightweight wrapper around `Box` for short-lived tasks. It exposes exec, files, schedules, and lifecycle methods, but excludes agent and git operations.

## Constructor (static)
```ts
static create(config?: EphemeralBoxConfig): Promise<EphemeralBox>
```

**EphemeralBoxConfig parameters**
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| apiKey | `string` | `process.env.UPSTASH_BOX_API_KEY` | API key for Box authentication. |
| baseUrl | `string` | `https://us-east-1.box.upstash.com` | API base URL. |
| name | `string` | — | Human-readable name. |
| runtime | `"node" \| "python" \| "golang" \| "ruby" \| "rust"` | — | Runtime environment. |
| size | `"small" \| "medium" \| "large"` | `"small"` | Resource size preset. |
| ttl | `number` | `259200` | Time-to-live in seconds (max 3 days). |
| env | `Record<string, string>` | — | Environment variables for the box. |
| attachHeaders | `Record<string, Record<string, string>>` | — | Secret outbound headers. |
| networkPolicy | `NetworkPolicy` | `{ mode: "allow-all" }` | Outbound network policy. |
| timeout | `number` | `600000` | Request timeout. |
| debug | `boolean` | `false` | Enable debug logging. |

## Static methods

### `EphemeralBox.fromSnapshot()`
```ts
static fromSnapshot(snapshotId: string, config?: EphemeralBoxConfig): Promise<EphemeralBox>
```

### `EphemeralBox.getByName()`
```ts
static getByName(name: string, options?: BoxGetOptions): Promise<Box>
```

### `EphemeralBox.delete()`
```ts
static delete(options: BoxConnectionOptions & { boxIds: string | string[] }): Promise<void>
```

## Instance namespaces

### `box.exec`
```ts
command(command: string): Promise<Run<string>>
code(options: CodeExecutionOptions): Promise<Run<string>>
stream(command: string): Promise<StreamRun<string, ExecStreamChunk>>
streamCode(options: CodeExecutionOptions): Promise<StreamRun<string, ExecStreamChunk>>
```

### `box.files`
```ts
read(path: string, options?: { encoding?: "base64" }): Promise<string>
write(options: { path: string; content: string; encoding?: "base64" }): Promise<void>
list(path?: string): Promise<FileEntry[]>
upload(files: UploadFileEntry[]): Promise<void>
download(options?: { folder?: string }): Promise<void>
```

### `box.schedule`
```ts
exec(options: ExecScheduleOptions): Promise<Schedule>
agent(options: AgentScheduleOptions): Promise<Schedule>
list(): Promise<Schedule[]>
get(id: string): Promise<Schedule>
pause(id: string): Promise<void>
resume(id: string): Promise<void>
delete(id: string): Promise<void>
```

## Lifecycle
```ts
cd(path: string): Promise<void>
getStatus(): Promise<{ status: string }>
delete(): Promise<void>
snapshot(options: { name: string }): Promise<Snapshot>
listSnapshots(): Promise<Snapshot[]>
deleteSnapshot(snapshotId: string): Promise<void>
```

## Example
```ts
import { EphemeralBox } from "@upstash/box";

const box = await EphemeralBox.create({ runtime: "node", ttl: 3600 });
const run = await box.exec.command("node -e 'console.log(1+1)'");
console.log(run.result);
await box.delete();
```
Loading