Skip to content

SDK Reference

The Runra SDK provides a TypeScript/JavaScript client for the Runra Sandbox API and the Runra Runtime. Install both packages to build applications that create sandboxes, execute code, and orchestrate AI agents.

Terminal window
# Sandbox API client (REST)
npm install @runra/sdk
# Runtime orchestration (agents + providers)
npm install @runra/runtime

The REST API client for managing sandboxes and executing code.

Main client class for interacting with the Runra Sandbox API.

import { Runra } from "@runra/sdk";
const client = new Runra({
apiKey: string; // Runra API key (defaults to RUNRA_API_KEY env)
apiUrl?: string; // API base URL (default: "https://api.box.runra.dev")
timeoutMs?: number; // Request timeout (default: 30_000)
maxRetries?: number; // Auto-retry on 5xx (default: 2)
});
client.sandboxes: SandboxesAPI; // Sandbox management methods
client.apiKey: string; // Current API key (masked)
client.apiUrl: string; // Current API URL

Manage sandbox lifecycle.

create(config: SandboxConfig): Promise<Sandbox>

Section titled “create(config: SandboxConfig): Promise<Sandbox>”

Create a new sandbox.

interface SandboxConfig {
image: string; // Required: base image
resources?: { // Optional: resource limits
cpu?: 2 | 4 | 8; // Default: 2
memoryMb?: number; // Default: 4096 (2048–16384)
diskMb?: number; // Default: 10240 (5120–51200)
};
env?: Record<string, string>; // Environment variables
workdir?: string; // Working directory (default: "/workspace")
timeoutMs?: number; // Max lifetime ms (default: 300_000, max: 86_400_000)
idleTimeoutMs?: number; // Auto-pause after idle ms (default: 120_000)
metadata?: Record<string, string>; // Custom tags (max 20 keys)
network?: { // Network policies
egress?: {
allow?: string[]; // Allowed outbound domains
default?: "allow" | "deny"; // Default egress policy
};
ingress?: {
allowPorts?: number[]; // Allow inbound on these ports
};
};
}

Returns:

interface Sandbox {
id: string; // Sandbox ID (e.g., "sb_x7k2m9p4q1")
state: "creating" | "running" | "paused" | "terminated";
image: string;
resources: {
cpu: number;
memoryMb: number;
diskMb: number;
};
env: Record<string, string>;
workdir: string;
timeoutMs: number;
idleTimeoutMs: number;
metadata: Record<string, string>;
network: {
egress?: { allow: string[]; default: "allow" | "deny" };
ingress?: { allowPorts: number[] };
};
createdAt: string; // ISO 8601
startedAt: string | null;
pausedAt: string | null;
terminatedAt: string | null;
// Instance methods (see below)
exec(command: string, options?: ExecOptions): Promise<ExecutionResult>;
files: FileOperations;
exposePort(port: number): Promise<Port>;
getPorts(): Promise<Port[]>;
closePort(port: number): Promise<void>;
pause(): Promise<void>;
resume(): Promise<void>;
terminate(): Promise<void>;
on(event: string, handler: (...args: any[]) => void): void;
}

Retrieve a sandbox by ID.

list(opts?: ListOptions): Promise<SandboxList>

Section titled “list(opts?: ListOptions): Promise<SandboxList>”

List sandboxes with optional filters.

interface ListOptions {
state?: "running" | "paused" | "terminated";
image?: string;
limit?: number; // Default: 20, max: 100
offset?: number; // Default: 0
metadata?: Record<string, string>; // Filter by metadata values
}
interface SandboxList {
data: Sandbox[];
pagination: {
total: number;
limit: number;
offset: number;
hasMore: boolean;
};
}

Resume a paused sandbox.

Methods available on a Sandbox instance:

exec(command: string, options?: ExecOptions): Promise<ExecutionResult>
Section titled “exec(command: string, options?: ExecOptions): Promise<ExecutionResult>”
interface ExecOptions {
cwd?: string; // Working directory
env?: Record<string, string>; // Additional env vars
timeoutMs?: number; // Command timeout (default: 60_000, max: 300_000)
stdin?: string; // Text to pipe to stdin
onStdout?: (line: string) => void; // Stream stdout line-by-line
onStderr?: (line: string) => void; // Stream stderr line-by-line
}
interface ExecutionResult {
stdout: string;
stderr: string;
exitCode: number | null;
durationMs: number;
signal: string | null;
}
interface FileOperations {
read(path: string): Promise<string>;
write(path: string, content: string): Promise<void>;
list(path: string): Promise<FileEntry[]>;
exists(path: string): Promise<boolean>;
delete(path: string, options?: { recursive?: boolean }): Promise<void>;
mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;
}
interface FileEntry {
name: string;
path: string;
isDirectory: boolean;
sizeBytes: number;
modifiedAt: string;
}
interface Port {
port: number;
url: string; // e.g., "https://3000-ab12cd.box.runra.dev"
exposedAt: string;
}
on(event: string, handler: Function): void
Section titled “on(event: string, handler: Function): void”
sandbox.on("started", () => {});
sandbox.on("paused", (e: { runtimeDurationMs: number }) => {});
sandbox.on("resumed", (e: { pausedDurationMs: number }) => {});
sandbox.on("terminated", (e: { reason: string; totalRuntimeMs: number }) => {});
sandbox.on("error", (e: { error: Error }) => {});
import { RunraError } from "@runra/sdk";
class RunraError extends Error {
code: string; // Error code
status: number; // HTTP status
details?: Record<string, unknown>; // Error details
retryable: boolean; // Safe to retry?
requestId: string; // Request ID for support
}

Error Codes:

type ErrorCode =
| "INVALID_REQUEST"
| "INVALID_CONFIG"
| "UNAUTHORIZED"
| "FORBIDDEN"
| "SANDBOX_NOT_FOUND"
| "INVALID_STATE"
| "RATE_LIMITED"
| "RESOURCE_EXHAUSTED"
| "INTERNAL_ERROR"
| "COMMAND_TOO_LONG"
| "EXECUTION_TIMEOUT"
| "NETWORK_ERROR";

The full runtime for orchestrating AI agents with sandbox infrastructure.

import { Runra } from "@runra/runtime";
const runra = new Runra(options: RunraOptions);
interface RunraOptions {
sandbox: SandboxProviderConfig; // Sandbox infrastructure
agent?: AgentConfig; // Agent adapter
llm?: LLMProviderConfig; // LLM backend
observability?: ObservabilityConfig; // Event exporters
}
interface SandboxProviderConfig {
provider: "runra-sandbox" | "cubesandbox" | "docker" | "e2b" | string;
apiKey?: string;
apiUrl?: string;
config?: Record<string, unknown>;
defaults?: {
image?: string;
resources?: { cpu?: number; memoryMb?: number; diskMb?: number };
timeoutMs?: number;
idleTimeoutMs?: number;
env?: Record<string, string>;
workdir?: string;
network?: { egress?: { allow?: string[]; default?: "allow" | "deny" } };
};
}
interface AgentConfig {
provider: "claude-code" | "codex" | "opencode" | "custom" | string;
config?: Record<string, unknown>;
}
interface LLMProviderConfig {
provider: "openai" | "anthropic" | "gemini" | "openrouter" | "ollama" | "vllm" | "custom" | string;
config?: Record<string, unknown>;
}
interface ObservabilityConfig {
provider?: string;
config?: Record<string, unknown>;
exporters?: Array<{
provider: string;
config?: Record<string, unknown>;
filter?: {
types?: string[];
condition?: (event: RuntimeEvent) => boolean;
minLevel?: "debug" | "info" | "warn" | "error";
};
}>;
}
start(params: StartParams): Promise<AgentResult>
Section titled “start(params: StartParams): Promise<AgentResult>”
interface StartParams {
prompt: string;
sandboxId?: string; // Use existing sandbox
sandboxOptions?: SandboxConfig; // Create new sandbox
}
interface AgentResult {
success: boolean;
summary: string;
totalTurns: number;
totalDurationMs: number;
totalCost: number;
error?: string;
}
createSandbox(config: SandboxConfig): Promise<Sandbox>
Section titled “createSandbox(config: SandboxConfig): Promise<Sandbox>”
getSandbox(id: string): Promise<Sandbox | null>
Section titled “getSandbox(id: string): Promise<Sandbox | null>”
listSandboxes(opts?: ListOptions): Promise<Sandbox[]>
Section titled “listSandboxes(opts?: ListOptions): Promise<Sandbox[]>”
on(event: RuntimeEventType, handler: Function): void
Section titled “on(event: RuntimeEventType, handler: Function): void”
runra.on("exec.completed", (event) => {
console.log(`Executed ${event.data.command} in ${event.data.durationMs}ms`);
});
runra.on("sandbox.created", (event) => {
console.log(`Sandbox ${event.sandboxId} created`);
});

Clean up all resources.

// Register custom providers
Runra.registerSandboxProvider(id: string, factory: () => SandboxProvider): void;
Runra.registerAgentAdapter(id: string, factory: () => AgentAdapter): void;
Runra.registerLLMProvider(id: string, factory: () => LLMProvider): void;
Runra.registerObservabilityExporter(id: string, factory: () => ObservabilityExporter): void;
interface SandboxProvider {
readonly id: string;
initialize(config: Record<string, unknown>): Promise<void>;
create(config: SandboxConfig): Promise<SandboxHandle>;
get(id: string): Promise<SandboxHandle>;
list(opts?: ListOptions): Promise<SandboxHandle[]>;
execute(id: string, command: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
pause(id: string): Promise<void>;
resume(id: string): Promise<void>;
terminate(id: string): Promise<void>;
writeFile(id: string, path: string, content: string): Promise<void>;
readFile(id: string, path: string): Promise<string>;
dispose(): Promise<void>;
}
interface AgentAdapter {
readonly id: string;
initialize(config: AgentAdapterConfig): Promise<void>;
start(params: StartParams): Promise<AgentResult>;
sendMessage?(message: string): Promise<void>;
stop?(): Promise<void>;
dispose(): Promise<void>;
}
interface LLMProvider {
readonly id: string;
initialize(config: Record<string, unknown>): Promise<void>;
chat(request: LLMRequest): Promise<LLMResponse>;
dispose(): Promise<void>;
}
interface ObservabilityExporter {
readonly id: string;
initialize(config: Record<string, unknown>): Promise<void>;
export(events: RuntimeEvent[]): Promise<void>;
flush(): Promise<void>;
dispose(): Promise<void>;
}
interface SandboxHandle {
id: string;
state: "creating" | "running" | "paused" | "terminated";
image: string;
resources?: { cpu?: number; memoryMb?: number; diskMb?: number };
env?: Record<string, string>;
metadata?: Record<string, string>;
createdAt: string;
startedAt?: string | null;
pausedAt?: string | null;
terminatedAt?: string | null;
}
interface LLMRequest {
messages: Array<{
role: "user" | "assistant" | "system";
content: string | Array<{
type: "text" | "tool_use" | "tool_result";
text?: string;
id?: string;
name?: string;
input?: unknown;
content?: string;
}>;
}>;
tools?: Array<{
name: string;
description: string;
input_schema: Record<string, unknown>;
}>;
systemPrompt?: string;
temperature?: number;
maxTokens?: number;
}
interface LLMResponse {
content: string;
toolCalls?: Array<{
id: string;
name: string;
input: unknown;
}>;
stopReason: "end_turn" | "tool_use" | "max_tokens" | "stop";
usage: {
inputTokens: number;
outputTokens: number;
};
}
interface RuntimeEvent {
id: string;
timestamp: string;
type: RuntimeEventType;
sandboxId: string;
runId: string;
data: Record<string, unknown>;
}
type RuntimeEventType =
| "sandbox.created" | "sandbox.started" | "sandbox.paused"
| "sandbox.resumed" | "sandbox.terminated" | "sandbox.error"
| "exec.started" | "exec.completed" | "exec.streamed" | "exec.error"
| "file.created" | "file.read" | "file.deleted" | "file.error"
| "port.exposed" | "port.closed"
| "agent.thinking" | "agent.tool_call" | "agent.tool_result" | "agent.error"
| "cost.runtime" | "cost.llm";
// @runra/sdk
export { Runra } from "./client";
export { RunraError } from "./errors";
export type { SandboxConfig, Sandbox, ListOptions, SandboxList } from "./types";
export type { ExecOptions, ExecutionResult } from "./types";
export type { FileOperations, FileEntry, Port } from "./types";
// @runra/runtime
export { Runra } from "./runtime";
export type { RunraOptions, StartParams, AgentResult } from "./types";
export type { SandboxProvider, AgentAdapter, LLMProvider, ObservabilityExporter } from "./providers";
export type { SandboxHandle, LLMRequest, LLMResponse, RuntimeEvent } from "./types";