Sandbox

Quickstart

Spin up your first Tenki Sandbox session in under a minute. Install the CLI, authenticate with an API key, and run commands inside an isolated Linux microVM.

Tenki Sandbox provides disposable Linux microVMs that you can control through the CLI, Go SDK, or TypeScript SDK. It's designed for running AI agents, executing untrusted code, automating jobs, spinning up reproducible development environments, and handling one-off compute tasks.

A sandbox session lets you:

  • run shell commands and stream output
  • read and write files
  • expose ports through preview URLs
  • accept SSH connections
  • mount workspace-scoped persistent volumes
  • snapshot and restore VM state
  • spin up new sessions from a reusable template
  • run OpenCode inside the VM for AI-driven workflows

Early access

Tenki Sandbox is rolling out via the Agent Sandbox waitlist at /features/sandbox. The CLI and SDKs in this guide are public; access to the API is gated until your workspace is enabled.

1. Install the CLI

Install the latest stable tenki CLI:

curl -fsSL https://tenki.cloud/install.sh | bash

Pin a version when you need reproducibility:

curl -fsSL https://tenki.cloud/install.sh | bash -s -- --version 0.1.0

The binary installs to ~/.local/bin/tenki by default. Override the location with TENKI_INSTALL_DIR.

Verify the install:

tenki --version
tenki sandbox --help

The CLI command group is tenki sandbox, with tenki sbx available as a shorter alias.

2. Authenticate

Generate an API key from your workspace settings, then export it:

export TENKI_API_KEY=tk_your_api_key
# Optional: override the default API endpoint (defaults to https://api.tenki.cloud)
export TENKI_API_URL=https://api.tenki.cloud

The CLI and both SDKs read TENKI_API_KEY automatically. Tokens that start with tk_ are sent as Authorization: Bearer <token>.

3. Create your first session

tenki sandbox create --name demo --cpu 2 --memory-mb 4096

By default the CLI waits for the session to reach READY and prints the session ID. Persist it as the current session so you can omit --session from later commands:

tenki sandbox set <session-id>

The remaining steps assume the current session is set. Pass --session <session-id> explicitly on any command if you skipped set or want to target a different session.

4. Run a command

tenki sandbox exec bash -lc 'uname -a && whoami'

You will see streamed stdout and stderr, the final status, exit code, duration, and an execution ID.

5. Move files in and out

echo 'hello sandbox' | tenki sandbox write --path /workspace/hello.txt
tenki sandbox read --path /workspace/hello.txt

You can also write a local file directly:

tenki sandbox write --path /workspace/config.json --data-file ./config.json

6. Expose a port

Start a server inside the sandbox, then publish its port at a public preview URL:

tenki sandbox exec bash -lc 'python3 -m http.server 3000 &'
tenki sandbox expose --port 3000

The CLI prints a preview_url you can open in a browser. List exposed ports with tenki sandbox ports and remove one with tenki sandbox unexpose.

7. Tear it down

tenki sandbox terminate

SDK quickstart

Prefer code to a CLI? The same workflow works through either SDK.

Go

go get github.com/TenkiCloud/tenki-sdk-go/sandbox
package main

import (
  "context"
  "log"
  "time"

  tenkisandbox "github.com/TenkiCloud/tenki-sdk-go/sandbox"
)

func main() {
  ctx := context.Background()

  client, err := tenkisandbox.New() // reads TENKI_API_KEY from env
  if err != nil {
    log.Fatal(err)
  }
  defer client.Close()

  session, err := client.CreateAndWait(
    ctx,
    3*time.Minute,
    tenkisandbox.WithName("demo"),
    tenkisandbox.WithCPUCores(2),
    tenkisandbox.WithMemoryMB(4096),
  )
  if err != nil {
    log.Fatal(err)
  }
  defer session.Close(ctx)

  result, err := session.Exec(
    ctx,
    "bash",
    tenkisandbox.WithArgs("-lc", "echo hello && uname -a"),
    tenkisandbox.WithTimeout(30*time.Second),
  )
  if err != nil {
    log.Fatal(err)
  }

  log.Printf("status=%s exit=%d stdout=%s", result.Status, result.ExitCode, result.StdoutString())
}

TypeScript

npm install @tenki/sandbox
import { TenkiSandbox } from "@tenki/sandbox";

const sandbox = new TenkiSandbox(); // reads TENKI_API_KEY from env

await using session = await sandbox.createAndWait({
  name: "demo",
  cpuCores: 2,
  memoryMb: 4096,
});

const result = await session.exec("bash", {
  args: ["-lc", "echo hello && uname -a"],
  timeoutMs: 30_000,
});

console.log(`exit=${result.exitCode} stdout=${result.stdout}`);

await using ensures the session is closed automatically when it leaves scope.

What's next

  • Read the Concepts page to learn how sessions, volumes, snapshots, and templates fit together.
  • See Sessions for command execution, file I/O, port exposure, and SSH.
  • See Volumes, Snapshots, and Templates for durable state.
  • The full SDK reference covers every option for both Go and TypeScript.

Need help? Email us at [email protected] and we'll be happy to onboard you.

LinkedInProduct Hunt