Back to Docs/Sandboxes

Sandboxes

Run agentic work or control an isolated OpenPond sandbox from server-side TypeScript.

openpond-sdk is the server-side TypeScript SDK for agentic Work and isolated OpenPond sandboxes. Use openpond.work when a model should plan and complete the task. Use openpond.sandboxes when your application already knows the commands and file operations to run.

Manage compute in Console

Open Sandboxes in Services to inspect compute and usage. Use Sandboxes for running resources and How to use for API setup. The service links to Templates and Snapshots management for reusable build inputs; inspect individual resources for their runtime logs. Inspect the selected resource's state, limits, and retained files before stopping or deleting it. Persistent storage is described in Persistent Volumes.

For application-controlled execution, follow the SDK examples below. For a model that should plan the task, use Work; for a known execution plan, use the raw sandbox operations.

How-tos

Requirements

  • Node.js 22.14 or newer and earlier than Node 25.
  • An OpenPond API key from the authenticated API keys page.
  • Server-side code. Never put the key in browser code or a NEXT_PUBLIC_* variable.

Install the SDK:

bash
npm install openpond-sdk

Set OPENPOND_API_KEY in your server environment. The client uses https://api.openpond.ai by default.

Run ephemeral Work

This complete example asks Work to create a Markdown file, copies every completed output into application-owned storage, and tells the SDK to delete compute after persistence succeeds.

ts
import { mkdir, writeFile } from "node:fs/promises"; import path from "node:path"; import { createOpenPondClient } from "openpond-sdk"; const apiKey = process.env.OPENPOND_API_KEY?.trim(); if (!apiKey) throw new Error("OPENPOND_API_KEY is required"); const outputDirectory = path.resolve("openpond-outputs"); await mkdir(outputDirectory, { recursive: true }); const openpond = createOpenPondClient({ apiKey }); const result = await openpond.work.run({ prompt: "Create a five-step launch checklist and output a Markdown file.", budgetUsd: "0.25", maxSteps: 20, timeoutSeconds: 180, cleanup: "delete", async persistOutput({ output, download }) { const downloaded = await download(); const bytes = Buffer.from(downloaded.file.contentsBase64, "base64"); await writeFile(path.join(outputDirectory, path.basename(output.name)), bytes); }, onEvent(event) { if (event.type === "status") console.log(event.message); if (event.type === "tool") console.log(event.command, event.status); }, }); console.log(result.text, result.outputs, result.lifecycle);

Files created under /workspace/outputs are detected automatically. The SDK waits for persistOutput for every detected file before deleting the sandbox. If persistence fails, it stops and retains the sandbox for recovery instead of deleting the only copy.

The local folder above is suitable for a single long-lived server. A serverless or multi-instance application should implement the same callback with durable object storage. Later turns can start fresh compute and receive previously stored results through inputs.

cleanup defaults to keep for compatibility, so first-party ephemeral Work callers should set cleanup: "delete" explicitly. Use cleanup: "stop" only when retaining the sandbox is a deliberate product decision.

Run one raw command

Use openpond.sandboxes when your application owns the execution plan:

ts
import { createOpenPondClient } from "openpond-sdk"; const apiKey = process.env.OPENPOND_API_KEY?.trim(); if (!apiKey) throw new Error("OPENPOND_API_KEY is required"); const openpond = createOpenPondClient({ apiKey }); let sandboxId: string | undefined; try { const sandbox = await openpond.sandboxes.create({ resources: { cpu: 2, memoryGb: 4, diskGb: 16 }, budget: { maxUsd: "0.25" }, quotas: { maxSpendUsd: "0.25", maxDurationSeconds: 900, idleTimeoutSeconds: 300, maxCommands: 20, maxOpenPorts: 1, maxSnapshots: 1, }, }); sandboxId = sandbox.id; const result = await openpond.sandboxes.exec(sandbox.id, { command: "printf 'sandbox ready\\n'", timeoutSeconds: 30, }); if (result.command.status !== "succeeded") { throw new Error(`Command failed with exit code ${result.command.exitCode}`); } console.log(result.command.output); } finally { if (sandboxId) await openpond.sandboxes.delete(sandboxId, { async: true }); }

A synchronous create returns once the sandbox is ready. If you opt into { async: true }, poll get(sandboxId) until its state is running before executing work.

Choose the right surface

NeedUse
Let a model inspect, create, and validate a resultopenpond.work.run
Run known commands and file operationsopenpond.sandboxes
Keep durable workflow identity, events, checkpoints, and review stateopenpond.sandboxes.runtimes

Continue with Work, sandboxes, and runtimes, files, processes, and previews, or pricing and budgets.