Documentation

OmniRun
Documentation

Isolated virtual machines for AI agents. One API call to create, one to destroy. Every sandbox boots in under a second and runs its own kernel.

import { Sandbox } from '@omnirun/sdk';

const sandbox = await Sandbox.create('playground', {
  timeout: 300,
});

// sandbox.sandboxId → "sb_a1b2c3d4"

Quick Start

5-step walkthrough

Go from zero to running code in an isolated VM. Each step builds on the previous. The entire flow takes about 60 seconds. Available for TypeScript and Python.

Run in playground →
Step 1 -- Install
npm install @omnirun/sdk
Step 2 -- Create & Run
Step 3 -- Files
await sandbox.files.write('/tmp/data.csv', content)
Step 4 -- Teardown
await sandbox.kill()

TypeScript SDK

Installation & auth

Install the SDK and set your API key. The SDK automatically reads OMNIRUN_API_KEY from your environment.

All methods return typed responses. The SDK supports both ESM and CommonJS.

Run in playground →
Install
npm install @omnirun/sdk
Usage

Python SDK

Python client

The Python SDK provides both sync and async interfaces with full feature parity: Commands, Filesystem, PTY, Contexts, Desktop GUI, Exposures, Production, Webhooks, and LLM proxy.

View on GitHub →
Install
pip install omnirun
Usage

REST API

Endpoints

All endpoints require a Bearer token. Base URL: https://api.omnirun.io

MethodEndpointDescription
Sandboxes
POST/sandboxesCreate a new sandbox
GET/sandboxesList active sandboxes
GET/sandboxes/:idGet sandbox status
DELETE/sandboxes/:idTerminate sandbox
Commands
POST/sandboxes/:id/commandsRun a command
GET/sandboxes/:id/commandsList executed commands
Files
POST/sandboxes/:id/filesUpload a file
GET/sandboxes/:id/filesRead a file (path as query param)
Exposures
POST/sandboxes/:id/exposuresExpose a port with preview URL
GET/sandboxes/:id/exposuresList active exposures
DELETE/sandboxes/:id/exposures/:eidRemove an exposure
LLM Proxy
POST/llm/v1/chat/completionsOpenAI-compatible chat completion
GET/llm/v1/modelsList available models
GET/llm/v1/usageGet spend tracking info
Vault
POST/vault/initInitialize user vault
POST/vault/credentialsStore a credential
GET/vault/credentialsList stored credentials
Auth
POST/auth/magic-link/requestRequest a magic link email
POST/auth/otp/verifyVerify OTP code
GET/auth/meGet current user info
POST/auth/tokensCreate an API token
History
GET/sandboxes/historyList past sandbox sessions

Platform

LLM Proxy

Use hundreds of AI models through a single API key with built-in spend tracking and rate limiting. OpenAI-compatible — just change your base URL.

Auth uses the same omr_ API key as sandbox operations. Three endpoints: POST /llm/v1/chat/completions, GET /llm/v1/models, and GET /llm/v1/usage.

// Using the OpenAI SDK
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.omnirun.io/llm/v1",
  apiKey: "omr_your_api_key",
});

const completion = await client.chat.completions.create({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "Hello!" }],
});

console.log(completion.choices[0].message.content);
Available models
"openai/gpt-4o-mini"          // Free tier
"anthropic/claude-sonnet-4.6"  // Free tier
"google/gemini-3.1-pro-preview"  // Free tier
"kilo-auto/balanced"         // Free tier
"kilo-auto/free"             // Free tier

// 300+ more models available
// GET /llm/v1/models for full list
Spend tracking
// Free tier: €5.00 credit
// Spend tracked per-request from upstream
// 402 response when cap exceeded

GET /llm/v1/usage
// → { "spendUsedCents": 42,
//     "spendCapCents": 500,
//     "remainingCents": 458 }

Platform

Vault

Secure credential storage with per-user isolation. Store API keys and secrets in your vault, then inject them into sandboxes at creation time.

When vaultInject: true is set, all vault credentials are written to /tmp/.omnirun-env inside the sandbox and automatically sourced by the agent process. Vault sandboxes are exempt from idle auto-kill.

Initialize vault
curl -X POST https://api.omnirun.io/vault/init \
  -H "Authorization: Bearer $OMNIRUN_KEY"

// Auto-created on first login
Store credentials
curl -X POST https://api.omnirun.io/vault/credentials \
  -H "Authorization: Bearer $OMNIRUN_KEY" \
  -d '{"key": "OPENAI_API_KEY",
       "value": "sk-..."}'
Inject into sandbox
const sandbox = await Sandbox.create('playground', {
  vaultInject: true,
});

// Credentials written to /tmp/.omnirun-env
// Auto-sourced by the sandbox agent

Platform

OpenClaw

The openclaw template deploys an AI agent gateway in an isolated microVM. Connect messaging channels like WhatsApp, Telegram, Discord, and Slack.

All LLM requests route through the OmniRun proxy with per-user spend tracking and a €5 free tier. Use vaultInject: true to inject your own API keys for BYOK mode — set the config provider to "openai" or "anthropic" instead of "omnirun".

After starting the gateway, expose port 3000 and visit the /connect endpoint to scan the WhatsApp QR code. Once paired, messages are handled automatically.

Create OpenClaw sandbox
import { Sandbox } from "@omnirun/sdk";

const sandbox = await Sandbox.create("openclaw", {
  vaultInject: true,
});

// Write OpenClaw config
await sandbox.files.write(
  "/app/config.json",
  JSON.stringify({
    provider: "omnirun",
    model: "openai/gpt-4o-mini",
    channels: ["whatsapp"],
  })
);

// Start the gateway
await sandbox.commands.run("node /app/gateway.js");
OpenClaw config format
{
  "provider": "omnirun",      // Custom OmniRun provider
  "model": "openai/gpt-4o-mini",
  "channels": ["whatsapp"],  // or telegram, discord, slack
  "systemPrompt": "You are a helpful assistant."
}
Available models via proxy
"openai/gpt-4o-mini"          // Default, free tier
"anthropic/claude-sonnet-4.6"  // Free tier
"google/gemini-3.1-pro-preview"  // Free tier
"kilo-auto/balanced"         // Free tier

// BYOK: store your own key in the vault
// and set provider to "openai" or "anthropic"
WhatsApp pairing
// Expose the pairing endpoint
const exposure = await sandbox.expose(3000);

// Visit the URL to scan the QR code
console.log(exposure.url + "/connect");
// → https://abc123.run.omnirun.io/connect

// Once paired, messages flow automatically
// through the LLM proxy and back to WhatsApp

Integration

Claude Managed Agents

Anthropic runs the agent loop and model; every tool call (bash, read, write, edit, glob, grep) executes inside an isolated OmniRun microVM on your infrastructure. A worker polls Anthropic's work queue and, for each claimed session, spawns a fresh claude-agentsandbox (8 GB, restored from snapshot in a few seconds).

1. Create a self_hosted environment in the Anthropic Console and generate an environment key. 2. Run the worker (shown here) on your box. We ship a claude-worker systemd unit that polls with graceful drain on restart. 3. Point a session at that environment — its tool calls now run in your microVMs.

Never set ANTHROPIC_API_KEYon the worker — the spawner refuses to start if it's present, so it can never reach a sandbox. Only the scoped ANTHROPIC_ENVIRONMENT_KEY is forwarded into the VM.

Full setup guide →Self-host the worker on GitHub (Docker) →
Run the self-hosted worker
# Install Anthropic's worker CLI (ant)
curl -fsSL .../ant_1.10.0_linux_amd64.tar.gz \
  | tar -xz -C /usr/local/bin ant

# Env from your self_hosted environment (Console)
export ANTHROPIC_ENVIRONMENT_KEY=sk-ant-oat01-...
export ANTHROPIC_ENVIRONMENT_ID=env_...

# Each claimed session runs in a fresh microVM
ant beta:worker poll --on-work ./spawn.sh

spawn.sh — per-session launcher

ant invokes your spawn script once per claimed session, passing ANTHROPIC_SESSION_ID / ANTHROPIC_WORK_ID. It creates the microVM, starts ant beta:worker run inside, polls until the session exits, then tears the sandbox down. Customize template, env, concurrency cap, and egress here.

Egress — open by default

Agent sandboxes get full outbound by default — real agents need package registries and git. To lock a deployment down, set sniProxy: true with allowDomains in the create body; the SNI proxy then forwards only allow-listed hosts. It blocks everything else (including pypi/npm), so list what you need.

Session lifecycle

One microVM per session, one snapshot restore per spawn. Tool calls within a session share that VM; disk does not persist across sessions (no Persistent Memory yet). Outputs under /mnt/session/outputs can be copied back to the host before teardown.

Troubleshooting

Restarting the worker drains in-flight sessions (generous TimeoutStopSec). Run one poller per box — stray ant beta:worker poll processes compete for work. A per-template concurrency cap protects host RAM; sessions over the cap are deferred, not dropped.

Platform

Limits

Each user can run up to 3 concurrent sandboxes by default. Creating a sandbox beyond this limit returns a 429 status code.

Sandboxes with no activity for 15 minutes are automatically killed. Sandboxes created with vaultInject: true are exempt from idle auto-kill.

Limit behavior
// Concurrent sandbox limit: 3 per user
// Exceeding the limit returns HTTP 429

POST /sandboxes
// → 429 { "error": "concurrent sandbox limit reached" }

// Idle auto-kill: 15 minutes with no activity
// Vault-injected sandboxes are exempt

Platform

Networking

Sandboxes have no internet access by default. With internet: falsea sandbox is a true L3 air-gap — there's no route out at all. Set internet: true for full outbound egress.

The air-gap prevents data exfiltration for workloads that don't need the network. For workloads that need some outbound, an opt-in SNI egress proxycan restrict a sandbox to an allow-list of hosts — it inspects each TLS handshake and only forwards connections whose server name matches your list, dropping the rest. It is off by default and, when on, blocks every host not listed (including package registries).

Read security model →
Toggle internet access
const sandbox = await Sandbox.create('agent', {
  internet: false
});

// internet: false → true L3 air-gap, no route out
// internet: true  → full outbound egress
// per-domain: opt-in SNI allow-list (sniProxy)
Try it — Network Isolation

Platform

File Transfer

Upload and download files using signed, time-bound URLs. All file access is scoped to a single sandbox.

Upload & download
// Write a file to the sandbox
await sandbox.files.write(
  '/tmp/input.json',
  JSON.stringify(data)
);

// Read a file from the sandbox
const output = await sandbox.files.read(
  '/tmp/result.csv'
);
Try it — File I/O

Platform

Templates

Templates define the pre-installed packages and base configuration for a sandbox. Use built-in templates or create your own.

Try playground templates →
Available templates
// Built-in templates
'playground'   // General purpose
'rust'         // Rust toolchain
'typescript'   // Node.js + TS
'javascript'   // Node.js
'php'          // PHP 8.x
'sql'          // PostgreSQL
'zig'          // Zig compiler
'claude-agent' // Claude Managed Agents (8 GB)

// Custom template
const sb = await Sandbox.create('my-custom-template');
Try it — Python Sandbox

Platform

Desktop Sandbox

Run a full Linux GUI desktop (XFCE) inside a Firecracker microVM. Control the desktop programmatically with mouse clicks, keyboard input, and screenshots — perfect for AI computer use, visual testing, and GUI automation. Available in both TypeScript and Python SDKs.

View examples →
const sb = await Sandbox.create('desktop');

// Take a screenshot
const png = await sb.desktop.screenshot();

// Click, type, and press keys
await sb.desktop.leftClick(512, 384);
await sb.desktop.type('hello world');
await sb.desktop.press('Return');

// Get screen info
const screen = await sb.desktop.getScreen();
// { width: 1024, height: 768 }
Web Browsing
Automated web browsing in a desktop sandbox — Firefox navigating to Hacker News and GitHub Trending
AI Agent (Computer Use)
AI agent autonomously writing and running Python code in a desktop sandbox
App Automation
Automated terminal interaction — typing and running a Python fizzbuzz program
Visual Testing
Visual regression testing — filling a login form and capturing screenshots
SDK Reference — sandbox.desktop
screenshot()Capture the desktop as PNG
leftClick(x, y)Click at coordinates
rightClick(x, y)Right-click at coordinates
doubleClick(x, y)Double-click at coordinates
type(text)Type text character by character
press(key)Press a key or combo (e.g. "ctrl+c")
moveMouse(x, y)Move cursor to coordinates
scroll(dir, amount)Scroll up/down/left/right
drag(x1, y1, x2, y2)Drag from one point to another
getScreen()Get resolution and cursor position
getStreamInfo()Get noVNC connection details

Live Desktop Streaming

Every desktop sandbox runs noVNC on port 6080. Create a preview URL with sandbox.expose(6080) to get a shareable link for live desktop viewing in any browser — no VNC client needed.

Reference

Security Model

OmniRun uses Firecracker microVMs for hardware-level isolation. Each sandbox runs its own Linux kernel, unlike containers which share the host kernel.

Full security overview →
Isolation stack
// Isolation layers (top → bottom)
'Your Code'        // Userspace
'Guest Kernel'     // Dedicated per sandbox
'microVM'  // Minimal VMM
'KVM'              // Hardware virtualization
'Host OS'          // Hardened host
Try it — Isolation Check

Reference

Benchmarks

MicroVM boot times compared to traditional containers and full VMs. OmniRun sandboxes boot in under a second.

OmniRun (Firecracker)842ms
Docker container1.2s
Cloud VM (EC2)~30s

Median of cold-start measurements on Hetzner AX102 bare metal. 1,000 runs.

Try it — Benchmark

Reference

Changelog

Recent updates and improvements to the OmniRun platform.

v1.3.0 -- March 2026

LLM Proxy, Vault & Multi-Region

  • LLM Proxy: OpenAI-compatible API at /llm/v1 with per-user spend tracking and €5 cap
  • Vault System: Secure credential storage with per-sandbox injection
  • Auto Vault: Vault automatically created on first login
  • Sandbox Limits: Per-user concurrent limit (default 3) with idle auto-kill (15 min)
  • OpenClaw Template: Pre-configured AI agent sandbox (2 vCPU, 1GB)
  • Channel Connection: /connect page for WhatsApp pairing via OpenClaw
  • Multi-Region: Frankfurt (fra) node with region-prefix preview URLs
  • SDK 0.5.0: LLM class with streaming support
  • CLI 0.7.0: omni llm chat/models/usage commands

v1.2.0 -- March 2026

Zig template + air-gap networking

Added Zig playground template. Sandboxes can now run fully air-gapped with internet: false.

v1.1.0 -- February 2026

Python SDK + file transfer

Released Python SDK. Added signed file upload/download URLs.

v1.0.0 -- January 2026

General availability

Initial public release with TypeScript SDK, REST API, and 6 language templates.