Skip to main content
Base URL: http://localhost:9090 (TCP) or http://boxrun (Unix socket) All endpoints return JSON. Error responses use the format:
{"code": "ERROR_CODE", "message": "Human-readable message"}

Boxes

MethodPathDescription
POST/v1/boxesCreate a box
GET/v1/boxesList boxes
GET/v1/boxes/{id}Get box by ID or name
POST/v1/boxes/{id}:stopStop (preserves disk)
POST/v1/boxes/{id}:startRestart a stopped box
DELETE/v1/boxes/{id}Remove a box

POST /v1/boxes

Create a new box.
Request
{
  "image": "ubuntu:24.04",
  "name": "dev",
  "cpu": 2,
  "memory_mb": 1024,
  "disk_size_gb": 8,
  "network": false,
  "workdir": "/root",
  "env": {"KEY": "value"},
  "volumes": [
    {"host_path": "/src", "guest_path": "/root/src", "readonly": false}
  ]
}
All fields except image are optional. Image aliases (e.g. "ubuntu" for "ubuntu:24.04") are accepted.
Response (201)
{
  "id": "box_abc123",
  "name": "dev",
  "status": "running",
  "image": "ubuntu:24.04",
  "cpu": 2,
  "memory_mb": 1024,
  "disk_size_gb": 8,
  "network": false,
  "workdir": "/root",
  "env": null,
  "volumes": null,
  "boxlite_id": "litevm-abc123",
  "error_code": null,
  "error_message": null,
  "created_at": "2025-01-01T00:00:00Z",
  "started_at": "2025-01-01T00:00:00Z",
  "stopped_at": null
}

GET /v1/boxes

List all boxes. Optional query parameter: ?status=running or ?status=stopped.

DELETE /v1/boxes/

Remove a box. Use ?force=true to remove a running box without stopping first.

Exec

MethodPathDescription
POST/v1/boxes/{id}/execStart a command
GET/v1/boxes/{id}/execsList executions for a box
GET/v1/boxes/{id}/exec/{eid}Get exec status
GET/v1/boxes/{id}/exec/{eid}/eventsSSE output stream
POST/v1/boxes/{id}/exec/{eid}:cancelCancel execution

POST /v1/boxes//exec

Start a command in a box. Only cmd is required.
Request
{
  "cmd": ["echo", "hello"],
  "env": {"KEY": "value"},
  "workdir": "/root/project",
  "timeout_ms": 30000
}
Response (201)
{
  "id": "exec_xyz789",
  "box_id": "box_abc123",
  "status": "running",
  "cmd": ["echo", "hello"],
  "env": null,
  "workdir": null,
  "timeout_ms": null,
  "exit_code": null,
  "error_message": null,
  "created_at": "2025-01-01T00:00:00Z",
  "finished_at": null
}

GET /v1/boxes//exec//events

Stream execution output in real time using Server-Sent Events (SSE). Event types: log — output from the command:
event: log
data: {"stream": "stdout", "data": "hello\n", "seq": 1}
exit — command finished:
event: exit
data: {"stream": null, "data": "{\"exit_code\": 0}", "seq": 5}
The stream replays past events first, then streams live events, and closes after the exit event.

Files

MethodPathDescription
POST/v1/boxes/{id}/files/uploadUpload a file
POST/v1/boxes/{id}/files/downloadDownload a file

POST /v1/boxes//files/upload

Upload a file to the box. Uses multipart form data. Form fields:
  • file — the file content (multipart file)
  • dest — destination path inside the box (string)
Response
{"ok": true, "dest": "/root/data.csv"}

POST /v1/boxes//files/download

Download a file from the box.
Request
{"path": "/root/results.csv"}
Response: raw file bytes with Content-Type: application/octet-stream.

Interactive terminal (WebSocket)

WS /v1/boxes/{id}/attach?shell=/bin/bash&cols=80&rows=24&term=xterm-256color
Opens an interactive terminal session inside the box.
ParameterDefaultDescription
shell/bin/bashShell to run
cols80Terminal columns
rows24Terminal rows
termxterm-256colorTERM environment variable
Protocol:
  • Binary frames = raw terminal I/O (stdin/stdout)
  • Text frames = JSON control messages
Client to server:
{"type": "resize", "cols": 120, "rows": 40}
Server to client:
{"type": "exit", "code": 0}

Convenience endpoints

MethodPathDescription
GET/v1/infoServer info and resource limits
POST/v1/runEphemeral one-shot run
POST/v1/gcGarbage collect stopped boxes

POST /v1/run

Create a box, run a command, return output, destroy the box. Only image and cmd are required.
Request
{
  "image": "ubuntu:24.04",
  "cmd": ["echo", "hello"],
  "timeout_ms": 30000
}
Response
{
  "exit_code": 0,
  "stdout": "hello\n",
  "stderr": "",
  "error_message": null
}

GET /v1/info

Response
{"max_cpu": 8, "max_memory_mb": 16384}

POST /v1/gc

Request
{"older_than": 3600}
Response
{"removed": 2}