SandboxTypeScript SDKClient

Sandbox client reference

Every public member of the Sandbox client: construction, account reads, creating and finding sandboxes, and bulk deletion. Resource managers such as client.secrets are on Resources.

import { Sandbox } from "@tangle-network/sandbox";
 
const client = new Sandbox({
  apiKey: process.env.TANGLE_API_KEY!,
  baseUrl: "https://sandbox.tangle.tools",
});

Construction

new Sandbox(config)

new Sandbox({
  apiKey: string,
  baseUrl: string,
  platformUrl?: string,
  timeoutMs?: number,
  signal?: AbortSignal,
  onTiming?: SdkTimingHook,
  directExec?: boolean,
})
OptionMeaning
apiKeyRequired. A missing key throws at construction.
baseUrlRequired. A trailing slash is removed.
platformUrlThe account API. Set automatically only when baseUrl is exactly https://sandbox.tangle.tools. client.run(), client.runs, fleet budget keys and prompt costUsd need it.
timeoutMsDefault per-request timeout; see SDK_TIMEOUTS.default.
signalCancels every request from this client.
onTimingReceives timing marks for each call.
directExecSend runtime calls straight to the sandbox when possible. On by default on servers and off in browsers.

client.withApiKey(apiKey): Sandbox

A new client with the same settings and another key.

client.fetch(path, init?, options?): Promise<Response>

An authenticated request to any Sandbox API path, for routes the SDK does not wrap. options.timeoutMs overrides the client timeout for that request.

const res = await client.fetch("/v1/startup-scripts");
console.log(res.status, await res.json());

Account

MemberReturnsRoute
health()boolean: the API answers.GET /health
getIdentity(){ customerId, billingOwnerId, apiKeyId, billingDelegationAuthorized }.GET /v1/me
usage()Today’s compute minutes, GPU seconds and cost, active and total sandboxes.GET /usage
subscription()Plan, status, credits, concurrency limit and resource limits.GET /subscription
shapes(){ presets, default, ceiling }: the size presets and your account’s ceiling.GET /v1/shapes
listBackends(){ backends }: the coding agents a sandbox can run.GET /v1/backends
getBackend(type)One entry from listBackends(), or undefined.GET /v1/backends
environments.list()Environments and your templates, with the runtimes each accepts.GET /v1/environments
environments.get(id)One environment, or null.GET /v1/environments
const { backends } = await client.listBackends();
console.log(backends.map((b) => b.type));
 
const { presets, ceiling } = await client.shapes();
console.log(presets, ceiling);

Create

client.create(options?, requestOptions?): Promise<SandboxInstance>

Creates a sandbox and resolves once it is running. requestOptions is { timeoutMs?, signal? } for the whole create, including the wait. Route: POST /v1/sandboxes.

const box = await client.create({
  name: "review-482",
  git: { url: "https://github.com/tangle-network/sandbox-demo" },
  backend: { type: "claude-code" },
  resources: { cpuCores: 2, memoryMB: 4096 },
  maxLifetimeSeconds: 3600,
  metadata: { pr: "482" },
  idempotencyKey: "review-482",
});

A timeout leaves the provision running on the server; the error names the idempotencyKey to retry with so the retry joins it.

Image, runtime and size

OptionTypeMeaning
environmentstringA catalog environment, template:<id>, or an image reference.
runtime"docker" | "firecracker"Container or microVM. Omit for the default.
resources{ cpuCores?, memoryMB?, diskGB?, accelerator?, advisory? }Size; accelerator with gpuLease requests a GPU lease.
barebooleanCommand execution and lifecycle only, without the agent runtime.
agentbooleanfalse provisions no coding agent, model credentials or startup scripts.
driver{ type: "tangle" }Run on Tangle network operators. Required for confidential.
capabilities["computer_use"]Boot the desktop services a computer-use agent needs. Size memoryMB for them.
ephemeralbooleanA scratch home directory that need not survive restarts.

Lifetime

OptionMeaning
maxLifetimeSecondsStop the sandbox after this interval. Create and each resume start a new interval; activity does not extend it.
idleTimeoutSecondsStop after this much inactivity.
coldTimeoutSecondsWhen a stopped sandbox’s compute may be reclaimed; a later resume provisions it again.
deleteAfterStoppedSecondsDelete a stopped sandbox after this long.

Code, environment and credentials

OptionMeaning
git{ url, ref?, depth?, sparse?, auth?: { token } | { grant: "read" } }. See Git.
cwdWorking directory below the workspace; . is the cloned repository’s root.
envEnvironment variables.
envRecoveryWhich withheld environment keys may be supplied again on resume.
secretsStored secret names, or "all". See Secrets.
proxySecretsProxy custody policies passed at create.
backend{ type, profile?, model?, interactions? }: the coding agent. See Agents.
confidentialTEE requirements; see Security.
gpuLease{ maxSpendUsd, maxLifetimeSeconds, idleTimeoutSeconds?, provider? }, with resources.accelerator.

Network, access and storage

OptionMeaning
egressPolicy{ mode, allowDomains?, includeImplicitDomains? }. See Egress.
sshEnabled, sshPublicKeys, sshKeyIdsSSH access. See Terminals.
webTerminalEnabledThe browser terminal.
storageYour own snapshot bucket. See Snapshots.
fromSnapshot, fromSandboxIdStart from a snapshot; both are required together.
templateId, publicTemplateId, publicTemplateVersionIdStart from a template. See Templates.
retain{ paths }: workspace paths kept with the coding agent’s sessions.

Ownership, policy and retries

OptionMeaning
name, metadataYour label and tags.
teamIdCreate in a team; membership is checked first.
ownerContext"isolated" runs without your secrets, scripts or Hub authority. Use createIsolated.
privacy{ egress?: "redact" | "block" | "off", logs?: "on" | "off" }.
compliance{ hipaa: true } or ["hipaa"]. Refused with COMPLIANCE_NOT_ENTITLED or COMPLIANCE_CELL_UNAVAILABLE.
idempotencyKeyOne logical create. A retry with the same key joins it.
retry{ capacity: false } returns CAPACITY_EXHAUSTED at once instead of retrying.
funding"wallet" or "referral_credit".

client.createIsolated(options, requestOptions?): Promise<SandboxInstance>

create with ownerContext: "isolated", no secrets and SSH off. See Isolated sandboxes.

Find

client.get(id): Promise<SandboxInstance | null>

null when the sandbox does not exist. Route: GET /v1/sandboxes/{id}.

client.list(options?): Promise<SandboxInstance[]>

OptionMeaning
statusOne status or several.
scope"personal", "team", "all" or `team:${teamId}`.
limit, offsetPaging.
runOnly sandboxes created for this caller run id.

Route: GET /v1/sandboxes.

client.waitForRunning(id, { timeoutMs?, signal? }): Promise<SandboxInstance>

Waits for an existing sandbox to run. Throws NOT_FOUND for an unknown id and INVALID_STATE when provisioning failed.

client.runGenerations(run): Promise<SandboxRunGeneration[]>

Every compute generation recorded for one caller run: sandbox id, state, start and close times, and why it closed.

Delete

client.delete(id, options?)

The same as box.delete(options) for a sandbox you have only the id of. With { wait: false } it returns a SandboxOperation.

client.deleteMatching(filter, options?)

const result = await client.deleteMatching(
  { metadataPrefix: { pr: "482" } },
  { cascade: true, until: "removed" },
);

Deletes every sandbox you own whose metadata value for each key in metadataPrefix starts with the given prefix. cascade: true also deletes branch children, which otherwise block a parent’s delete with CHILDREN_EXIST. Each sandbox reports destroyed, already_absent or failed.

Session broadcast

MemberEffect
broadcastSessionEvent(sessionId, event)Sends a server-originated event to a product session over the API’s /session WebSocket.
broadcastSessionAgentEvent(sessionId, event)Delivers a payload through SessionGatewayClient’s onAgentEvent.

box.registerSessionMapping and box.unregisterSessionMapping map a product session to a sandbox.

Resource managers

client.secrets, client.sshKeys, client.teams, client.environments, client.publicTemplates, client.instances, client.fleets, client.runs, client.lines and client.intelligence are on Resources, with client.runBatch, client.streamBatch and client.run.

Python and REST

The Python client has create, list, get, usage, subscription, health and close. create returns before the sandbox runs; call box.wait_for(SandboxStatus.RUNNING). It has no create_isolated, shapes, list_backends, get_identity, wait_for_running, run_generations or delete_matching. Call those routes through client.fetch, which returns the raw response and does not raise on an error status:

backends = client.fetch("GET", "/v1/backends").json()["backends"]
shapes = client.fetch("GET", "/v1/shapes").json()

Next