Skip to main content
Version: 1.0

Boxer API

Boxer is a sandboxed container execution service backed by gVisor. Send an HTTP request with an image and command - Boxer pulls the image, runs the command inside an isolated gVisor sandbox, and returns stdout, stderr, exit code, and wall time.

Base URL

http://localhost:8080

By default the server listens on :8080. Override with listen_addr in your config or the $BOXER_CONFIG environment variable.

Authentication

No authentication is required. Boxer is designed to run as a local or internal service - network-level access control is left to the operator.

Endpoints

MethodPathDescription
POST/runExecute a command in a sandboxed container
POST/filesUpload a file to the file store
GET/filesDownload a file from the file store
GET/healthzHealth check

Quick Start

Run a Python one-liner in an isolated sandbox:

curl -s http://localhost:8080/run \
-H 'Content-Type: application/json' \
-d '{
"image": "python:3.12-slim",
"cmd": ["python3", "-c", "print(42)"]
}'
{
"exec_id": "boxer-abc123",
"exit_code": 0,
"stdout": "42\n",
"stderr": "",
"wall_ms": 312
}

File Workflow

To pass files into a container, upload them first then reference them in /run:

# 1. Upload a script
curl -s http://localhost:8080/files \
-F 'file=@script.py' \
-F 'path=workspace/script.py'

# 2. Run it - the file is bind-mounted read-only at /workspace/script.py
curl -s http://localhost:8080/run \
-H 'Content-Type: application/json' \
-d '{
"image": "python:3.12-slim",
"cmd": ["python3", "/workspace/script.py"],
"files": ["workspace/script.py"]
}'

To capture output files written by the container, set persist: true and retrieve them via GET /files?path=output/{exec_id}/{filename}.

Error Handling

All errors return a JSON body with an error field:

{ "error": "image pull failed: not found" }
StatusMeaning
400Invalid request body or referenced file not found
408Wall-clock timeout exceeded
413Upload exceeds configured size limit
500Internal error - image pull failed, runsc error
507stdout or stderr exceeded the configured output limit

A 200 response does not imply the command succeeded - always check exit_code.

License

Apache 2.0