Lelantos implements the E2B REST API surface. Sandbox lifecycle, command execution (commands.run), process streaming, and filesystem operations work through the stock E2B SDK pointed at Lelantos.
Lelantos implements the E2B REST API surface plus the in-VM RPC surface the SDK uses. You can create, list, kill, and set timeouts on sandboxes, run commands, stream stdout/stderr, and read/write files using the stock E2B SDK or the REST API.
The SDK works in-VM, not just for lifecycle.commands.run(), process.start() (background), streaming stdout/stderr, and files.read()/files.write()/files.list() all work through the SDK — the sandbox subdomain proxy transcodes the SDK's Connect-RPC stream and forwards it to the in-guest envd daemon. A few advanced features (files.watch(), PTY resize) are not yet wired; see the coverage table below for exact verdicts.
Get a Lelantos API key in e2b_ form — sign up at lelantos.ai and create a key. Lelantos issues keys with the lel_ prefix; for the E2B SDK use the same key in its e2b_ form (replace the leading lel_ with e2b_). The dashboard's API Keys → New API Key screen has a Lelantos / E2B SDK format toggle that shows both. The newer E2B SDK validates the key prefix client-side and rejects anything that isn't e2b_…, so always pass the e2b_ form to the SDK.
Point the SDK at Lelantos — set the SDK's domain / api_url (apiUrl) to lelantos.ai instead of e2b.dev.
from e2b import Sandboxsandbox = Sandbox.create( template="base", api_key="e2b_your_key_here", # same key, e2b_ form for the E2B SDK api_url="https://lelantos.ai", domain="lelantos.ai",)sandbox.files.write("/hello.txt", "Hello from Lelantos!")content = sandbox.files.read("/hello.txt")print(content)sandbox.kill()
import { Sandbox } from "e2b";const sandbox = await Sandbox.create({ template: "base", apiKey: "e2b_your_key_here", // same key, e2b_ form for the E2B SDK apiUrl: "https://lelantos.ai", domain: "lelantos.ai",});await sandbox.files.write("/hello.txt", "Hello from Lelantos!");const content = await sandbox.files.read("/hello.txt");console.log(content);await sandbox.kill();
# Before (E2B)from e2b import Sandboxsandbox = Sandbox.create(api_key="e2b_key")sandbox.files.write("/hello.txt", "Hello!")sandbox.kill()# After (Lelantos) — same key in e2b_ form, add api_url and domainfrom e2b import Sandboxsandbox = Sandbox.create( template="base", api_key="e2b_key", # your Lelantos key with the e2b_ prefix api_url="https://lelantos.ai", domain="lelantos.ai",)sandbox.files.write("/hello.txt", "Hello!")sandbox.kill()
// Before (E2B)import { Sandbox } from "e2b";const sandbox = await Sandbox.create({ apiKey: "e2b_key" });await sandbox.files.write("/hello.txt", "Hello!");await sandbox.kill();// After (Lelantos) — same key in e2b_ form, add apiUrl and domainimport { Sandbox } from "e2b";const sandbox = await Sandbox.create({ template: "base", apiKey: "e2b_key", // your Lelantos key with the e2b_ prefix apiUrl: "https://lelantos.ai", domain: "lelantos.ai",});await sandbox.files.write("/hello.txt", "Hello!");await sandbox.kill();
This table maps the E2B SDK surface to the Lelantos implementation that backs it, verified against the source. The stock e2b SDK's command-exec and filesystem calls reach the VM through the sandbox subdomain proxy → envd path (internal/dataplane/sandboxproxy/proxy.go), which transcodes the SDK's Connect-RPC envelope to the JSON the in-guest daemon understands.
Legend: ✅ Supported · ⚠️ Partial / caveat · ❌ Not supported · 🔶 Lelantos-native (no E2B equivalent)
GET /sandboxes/{id}/logs (sandboxes.go:1683, COMPAT-05)
For a live sandbox, merges process stdout/stderr (pulled from envd) with lifecycle events, time-ordered; historical sandboxes return lifecycle events only