SandboxTypeScript SDK

TypeScript SDK

@tangle-network/sandbox creates and drives sandboxes from your server, a Cloudflare Worker or, with a scoped token, a browser. This page covers install, the client, entrypoints, errors, retries and timeouts; the reference pages list every member.

Install

npm install @tangle-network/sandbox

The package is ESM. Optional integrations, such as the agent framework tool packs, use optional peer dependencies: install only the framework you use.

Create a client

import { Sandbox } from "@tangle-network/sandbox";
 
const client = new Sandbox({
  apiKey: process.env.TANGLE_API_KEY!,
  baseUrl: "https://sandbox.tangle.tools",
});
 
const box = await client.create();
try {
  const { stdout } = await box.exec("echo hello from $(hostname)");
  console.log(stdout);
} finally {
  await box.delete();
}

apiKey and baseUrl are both required, and the SDK reads no environment variables: a missing apiKey or baseUrl throws when you construct the client. TANGLE_API_KEY in these docs is only a naming convention.

OptionEffect
apiKeyYour Sandbox API key. It can create and delete compute, so keep it on servers.
baseUrlThe Sandbox API, https://sandbox.tangle.tools.
platformUrlThe account API used by client.run(), client.runs, fleet budget keys and prompt costUsd. Set automatically only when baseUrl is exactly https://sandbox.tangle.tools; set it yourself for any other baseUrl.
timeoutMsDefault per-request timeout.
signalAn AbortSignal that cancels every request from this client.
onTimingA hook that receives timing marks for each call.

client.withApiKey(otherKey) returns a client with the same settings and another key.

⚠️

Never ship your API key or a sandbox’s connection.authToken to a browser. Mint a scoped token on your server instead.

Choose an entrypoint

ImportWhat it gives you
@tangle-network/sandboxThe full client for trusted servers.
@tangle-network/sandbox/coreThe client without on-chain dependencies, for Cloudflare Workers and other edge runtimes.
@tangle-network/sandbox/runtimecreateSandboxRuntimeClient for browsers and Workers, built from a scoped token.
@tangle-network/sandbox/session-gatewaySessionGatewayClient: a browser event stream that resumes after a drop.
@tangle-network/sandbox/interactive-controlBrowserInteractiveSessionController for driving a coding agent’s terminal from a browser.
@tangle-network/sandbox/agentImporting it adds box.agents, and it exports tool packs for OpenAI, Anthropic, Vercel AI and Mastra and an MCP server.
@tangle-network/sandbox/public-templatesPublicTemplatesClient and its publish types.
@tangle-network/sandbox/previewPreview operations and a preview MCP server for agents that publish their own work.
@tangle-network/sandbox/linesLinesClient and SandboxLines for phone and messaging addresses.
@tangle-network/sandbox/intelligenceA browser-safe client for trace and run-session reads from Tangle Intelligence.
@tangle-network/sandbox/openaiFunctions that translate between OpenAI wire formats and sandbox runs, plus tool-call hooks. A library, not a hosted endpoint.
@tangle-network/sandbox/authProductTokenIssuer for issuing your own product tokens on a server. Needs node:crypto.
@tangle-network/sandbox/tangleBlueprintSandboxClient and operator sessions for creating sandboxes through Tangle network operators on-chain.
@tangle-network/sandbox/gpu-leaseThe GPU lease marketplace resolver for Tangle network operators: quotes, intents and operator selection.
@tangle-network/sandbox/select-seat/commandA Node-only command transport for choosing which of your coding-plan seats a run uses.
@tangle-network/sandbox/collaborationCollaborative document helpers. The hosted service does not offer collaboration.
@tangle-network/sandbox/examplesquickstartExamples, the runnable quickstart programs as data.

@tangle-network/sandbox/agent works by side effect: box.agents exists only after you import it.

import "@tangle-network/sandbox/agent";

Handle errors

Every SDK failure is a SandboxError. Branch on error.code, the server’s code, or error.catalogCode, the platform’s error class. The subclasses such as NotFoundError and StateError are deprecated aliases.

import { SandboxError } from "@tangle-network/sandbox";
 
try {
  await box.exec("make test");
} catch (error) {
  if (!(error instanceof SandboxError)) throw error;
  if (error.catalogCode === "INVALID_STATE") {
    await box.resume();
  } else if (error.retryable) {
    await new Promise((r) => setTimeout(r, error.retryAfterMs ?? 1_000));
  } else {
    console.error(error.code, error.nextStep, error.requestId);
    throw error;
  }
}
FieldMeaning
codeThe server’s code, such as CHILDREN_EXIST or GPU_PROVIDER_NOT_CONFIGURED.
catalogCodeThe platform class: NOT_FOUND, INVALID_STATE, VALIDATION_ERROR, QUOTA_EXCEEDED and others.
statusHTTP status.
retryable, retryAfterMs, etaSecondsWhether and when a retry can succeed.
nextStep, docsWhat to do, and where it is explained.
requestId, traceIdQuote these when you contact support.
missingEnvKeys, maxChildrenExtra detail for RESUME_ENV_REQUIRED and BRANCH_FANOUT_EXCEEDS_HOST.

Every code and its fix is on Error codes.

A few calls report failure in their result rather than by throwing:

  • exec returns a non-zero exitCode.
  • prompt returns success: false with error and errorCode, and status: "unknown" when the stream was lost. Check result.success.

Retries and idempotency

The SDK resends a request only when sending it twice is safe: GET, PUT, DELETE and any request with an Idempotency-Key, after a dropped connection, a 502 to 504, or a 429 with Retry-After. It never resends a code the platform marks non-retryable. create() adds its own retry for capacity refusals inside its time budget.

Pass idempotencyKey to create, snapshot, stop, delete, fork and process jobs when your own code may retry. For coding agent turns, a stable sessionId keeps context and a turnId makes the turn safe to retry; see Streaming.

Timeouts

SDK_TIMEOUTS exports the default timeout of each operation. Pass timeoutMs to a call to change it. The values are on Limits.

import { SDK_TIMEOUTS } from "@tangle-network/sandbox";
 
const box = await client.create({}, { timeoutMs: SDK_TIMEOUTS.create * 2 });

Things that catch people out

  • A browser or Worker client built from a scoped token uses scoped.sidecarProxyUrl as its baseUrl, and a browser SessionGatewayClient uses it as its url.
  • box.search() and box.fs.search() yield matches; read them with for await.
  • A command on a stopped sandbox throws INVALID_STATE. Call box.resume() first.
  • box.direct() sends runtime calls straight to the sandbox and skips the API’s credential refresh and secret checks. Never use it for prompts.

Python and REST

The Python SDK covers the core lifecycle, commands, files, git, snapshots, egress, prompts, batches, fleets and intelligence reports. Every TypeScript method maps to a REST route, listed on its reference page. From Python, call a route the SDK does not wrap through client.fetch(method, path, json=, params=, headers=, timeout=), which returns the raw response and does not raise on an error status.

Reference

  • Client: construction, account reads, create and every option, get, list, deleteMatching.
  • Sandbox instance: state, lifecycle, snapshots, branches, egress, GPU and access.
  • Runtime: commands, processes, files, git, ports, previews, terminals and the browser clients.
  • Agents: prompts, streams, sessions, interactive control and box.agents.
  • Resources: secrets, SSH keys, teams, templates, images, instances, fleets, batches, runs and lines.

Next