# Ephemeral Box

`EphemeralBox` is a lightweight, short-lived sandbox that provides only **exec** and **file** operations. It's designed for quick, disposable compute tasks where a full Box (with agent, git, snapshots, etc.) is unnecessary.

---

## Creation

<CodeGroup>
```typescript box.ts
import { EphemeralBox } from "@upstash/box"

const box = await EphemeralBox.create({
  runtime: "node",  // "node" | "python" | "golang" | "ruby" | "rust"
  ttl: 3600,        // seconds, max 259200 (3 days), default 259200
  name: "my-ephemeral-worker",          // optional
  networkPolicy: { mode: "allow-all" }, // optional
})
```

```python box.py
from upstash_box import EphemeralBox

box = EphemeralBox.create(
    runtime="node",  # "node" | "python" | "golang" | "ruby" | "rust"
    ttl=3600,        # seconds, max 259200 (3 days), default 259200
    name="my-ephemeral-worker",            # optional
    network_policy={"mode": "allow-all"},  # optional
)
```
</CodeGroup>

**Key difference from `Box.create()`:** Ephemeral boxes are ready immediately — no polling. The API returns with `status: "idle"` and the box is usable right away.

The request sends `{ ephemeral: true, ttl?, runtime? }` to `POST /v2/box`.

---

## Available API

| Feature | Box | EphemeralBox |
|---|---|---|
| `exec.command()` | Yes | Yes |
| `exec.code()` | Yes | Yes |
| `exec.stream()` | Yes | Yes |
| `exec.streamCode()` | Yes | Yes |
| `files.read/write/list/upload/download` | Yes | Yes |
| `schedule.exec/prompt/list/get/pause/resume/delete` | Yes | Yes |
| `cd()` / `cwd` | Yes | Yes |
| `getStatus()` | Yes | Yes |
| `delete()` | Yes | Yes |
| `networkPolicy` / `updateNetworkPolicy()` | Yes | Yes |
| `expiresAt` | No | Yes |
| `agent.run()` / `agent.stream()` | Yes | **No** |
| `git.*` | Yes | **No** |
| `getPublicURL()` / `listPublicURLs()` / `deletePublicURL()` | Yes | **No** |
| `snapshot()` / `fromSnapshot()` | Yes | Yes |
| `pause()` / `resume()` | Yes | **No** |
| `configureModel()` | Yes | **No** |
| `logs()` / `listRuns()` | Yes | **No** |

---

## Properties

- **`id`** — box identifier (e.g. `"sweet-shark-26021"`)
- **`expiresAt`** — Unix timestamp (seconds) when the box auto-deletes

---

## How it differs from Box

1. **Instant creation** — no polling loop; the response is the ready box
2. **Auto-expiry** — boxes are automatically deleted after TTL; `expiresAt` tracks this
3. **Reduced surface** — only exec + files; no agent, git, public URLs, snapshots, pause/resume
4. **Simpler config** — `EphemeralBoxConfig` has only `apiKey`, `runtime`, `ttl`, `name`, `networkPolicy`, `baseUrl`, `timeout`, `debug` (no agent, git, env, skills, mcpServers)
5. **Composition over inheritance** — `EphemeralBox` wraps an internal `Box` and exposes only the relevant subset, so agent/git/etc. are not accessible even at runtime

---

## Examples

### Run a shell command

<CodeGroup>
```typescript box.ts
const run = await box.exec.command("echo hello")
console.log(run.result) // "hello"
```

```python box.py
run = box.exec.command("echo hello")
print(run.result)  # "hello"
```
</CodeGroup>

### Execute inline code

<CodeGroup>
```typescript box.ts
const result = await box.exec.code({
  code: 'console.log(JSON.stringify({ sum: 1 + 2 }))',
  lang: "js",
})
```

```python box.py
result = box.exec.code(
    code="import json; print(json.dumps({'sum': 1 + 2}))",
    lang="python",
)
```
</CodeGroup>

### File operations

<CodeGroup>
```typescript box.ts
await box.files.write({ path: "data.json", content: '{"key":"value"}' })
const content = await box.files.read("data.json")
```

```python box.py
box.files.write(path="data.json", content='{"key":"value"}')
content = box.files.read("data.json")
```
</CodeGroup>

### Clean up early

Otherwise the box auto-deletes at `expiresAt`.

<CodeGroup>
```typescript box.ts
await box.delete()
```

```python box.py
box.delete()
```
</CodeGroup>

---

## Exported types

- `EphemeralBox` — the class
- `EphemeralBoxConfig` — config for `EphemeralBox.create()`
- `EphemeralBoxData` — extends `BoxData` with `ephemeral: boolean` and `expires_at: number`
