sandboxd-o

Base URL: http://localhost:8082

Common Error Response

{
    "error": "error message"
}

Health API

GET /healthz

Response

{
    "ok": true
}

Node APIs

POST /api/v1/nodes

Create or update a node object.

Request

{
    "id": "node-a",
    "spec": {
        "ip": "192.168.0.3",
        "port": 8080
    }
}

Response

{
    "node": {
        "id": "node-a",
        "ip": "192.168.0.3",
        "port": 8080,
        "state": "Unknown",
        "source": "api",
        "success_streak": 0,
        "failure_streak": 0,
        "created_at": "2026-05-15T04:30:00Z",
        "updated_at": "2026-05-15T04:30:00Z",
        "resources": {
            "capacity_cpu_milli": 4000,
            "capacity_memory_bytes": 16709799936,
            "allocatable_cpu_milli": 3600,
            "allocatable_memory_bytes": 15038819942,
            "used_cpu_milli": 0,
            "used_memory_bytes": 0,
            "available_cpu_milli": 3600,
            "available_memory_bytes": 15038819942,
            "max_alloc_percent": 90,
            "updated_at": "2026-05-15T04:30:00Z"
        },
        "sbxlet_base_url": "http://192.168.0.3:8080"
    }
}

GET /api/v1/nodes

List all registered nodes.

Response

{
    "items": [
        {
            "name": "node-a",
            "ip": "192.168.0.3",
            "port": 8080,
            "state": "Ready",
            "source": "api",
            "last_error": "",
            "success_streak": 2,
            "failure_streak": 0,
            "created_at": "2026-05-15T04:30:00Z",
            "updated_at": "2026-05-15T04:31:30Z",
            "last_heartbeat": "2026-05-15T04:31:30Z",
            "resources": {
                "capacity_cpu_milli": 4000,
                "capacity_memory_bytes": 16709799936,
                "allocatable_cpu_milli": 3600,
                "allocatable_memory_bytes": 15038819942,
                "used_cpu_milli": 100,
                "used_memory_bytes": 134217728,
                "available_cpu_milli": 3500,
                "available_memory_bytes": 14904602214,
                "max_alloc_percent": 90,
                "updated_at": "2026-05-15T04:31:30Z"
            },
            "sbxlet_base_url": "http://192.168.0.3:8080"
        }
    ]
}

GET /api/v1/nodes/{name}

Get a single node.

Response

{
    "node": {
        "name": "node-a",
        "ip": "192.168.0.3",
        "port": 8080,
        "state": "Ready",
        "source": "api",
        "success_streak": 2,
        "failure_streak": 0,
        "sbxlet_base_url": "http://192.168.0.3:8080",
        "resources": {
            "available_cpu_milli": 3500,
            "available_memory_bytes": 14904602214,
            "max_alloc_percent": 90,
            "external": "203.0.113.10"
        }
    }
}

DELETE /api/v1/nodes/{name}

Delete a node registration.

Response

{
    "deleted": "node-a"
}

Examples:

POST /api/v1/nodes/{name}/heartbeat

Trigger immediate health/resource probe against sbxlet.

Response

{
    "node": {
        "name": "node-a",
        "state": "Ready",
        "sbxlet_base_url": "http://192.168.0.3:8080"
    },
    "heartbeat": "ok",
    "resources": {
        "capacity_cpu_milli": 4000,
        "capacity_memory_bytes": 16709799936,
        "allocatable_cpu_milli": 3600,
        "allocatable_memory_bytes": 15038819942,
        "used_cpu_milli": 100,
        "used_memory_bytes": 134217728,
        "available_cpu_milli": 3500,
        "available_memory_bytes": 14904602214,
        "max_alloc_percent": 90,
        "updated_at": "2026-05-15T04:31:30Z"
    },
    "heartbeat_error": "",
    "status_error": ""
}

heartbeat values:

Control-Plane Sandbox APIs

POST /api/v1/sandboxes

Create a control-plane sandbox object for scheduling and reconciliation.

Request

{
    "id": "sbx-demo-1",
    "spec": {
        "egress": true,
        "ttl_seconds": 3600,
        "ports": [
            {
                "container_port": 80,
                "protocol": "tcp"
            }
        ],
        "readiness_probe": {
            "protocol": "http",
            "port": 80,
            "path": "/",
            "initial_delay_seconds": 1,
            "period_seconds": 1,
            "timeout_seconds": 1,
            "success_threshold": 2,
            "failure_threshold": 3
        },
        "containers": [
            {
                "name": "web",
                "image": "nginx:latest",
                "args": [],
                "env": [],
                "work_dir": "",
                "resource": {
                    "cpu": "200m",
                    "memory": "256Mi",
                    "ephemeral_storage": "96Mi"
                }
            }
        ]
    }
}

Response

{
    "sandbox": {
        "id": "sbx-demo-1",
        "spec": {
            "egress": true,
            "ttl_seconds": 3600,
            "ports": [
                {
                    "container_port": 80,
                    "protocol": "tcp"
                }
            ],
            "containers": [
                {
                    "name": "web",
                    "image": "nginx:latest",
                    "resource": {
                        "cpu": "200m",
                        "memory": "256Mi"
                    }
                }
            ]
        },
        "status": {
            "phase": "Pending",
            "expire_at": "2026-05-15T05:31:30Z"
        },
        "created_at": "2026-05-15T04:31:30Z",
        "updated_at": "2026-05-15T04:31:30Z"
    }
}

GET /api/v1/sandboxes

List all control-plane sandbox objects.

Response

{
    "items": [
        {
            "id": "sbx-demo-1",
            "spec": {
                "egress": true,
                "ports": [
                    {
                        "container_port": 80,
                        "protocol": "tcp"
                    }
                ],
                "containers": [
                    {
                        "name": "web",
                        "image": "nginx:latest",
                        "resource": {
                            "cpu": "200m",
                            "memory": "256Mi",
                            "ephemeral_storage": "96Mi"
                        }
                    }
                ]
            },
            "status": {
                "phase": "Running",
                "node_name": "node-a",
                "external": "203.0.113.10",
                "assigned_ports": [
                    {
                        "host_port": 10000,
                        "container_port": 80,
                        "protocol": "tcp"
                    }
                ]
            },
            "created_at": "2026-05-15T04:31:30Z",
            "updated_at": "2026-05-15T04:31:34Z"
        }
    ]
}

GET /api/v1/sandboxes/{id}

Get one control-plane sandbox object.

Response

{
    "sandbox": {
        "id": "sbx-demo-1",
        "status": {
            "phase": "Running",
            "node_name": "node-a",
            "external": "203.0.113.10",
            "assigned_ports": [
                {
                    "host_port": 10000,
                    "container_port": 80,
                    "protocol": "tcp"
                }
            ]
        },
        "created_at": "2026-05-15T04:31:30Z",
        "updated_at": "2026-05-15T04:31:34Z"
    }
}

DELETE /api/v1/sandboxes/{id}

Delete one control-plane sandbox object.

Response

{
    "deleted": "sbx-demo-1"
}

Node Proxy APIs (Pass-through to sbxlet)

All endpoints below require {name} to be an existing node in orchestrator.

If node lookup fails: 404 Not Found.

If upstream sbxlet call fails or returns invalid data: 502 Bad Gateway.

GET /api/v1/nodes/{name}/sandboxes

Query params:

Response Example

{
    "items": [
        {
            "id": "sbx-demo-1",
            "phase": "running"
        }
    ],
    "next_cursor": "sbx-demo-1",
    "external": "203.0.113.10"
}

GET /api/v1/nodes/{name}/sandboxes/{id}

Response Example

{
    "sandbox": {
        "id": "sbx-demo-1",
        "phase": "running"
    },
    "external": "203.0.113.10"
}

POST /api/v1/nodes/{name}/sandboxes

Create sandbox directly on selected node (sbxlet API pass-through).

Request

{
    "id": "sbx-direct-1",
    "egress": true,
    "ports": [
        {
            "host_port": 30080,
            "container_port": 80,
            "protocol": "tcp"
        }
    ],
    "containers": [
        {
            "name": "web",
            "image": "nginx:latest",
            "resource": {
                "cpu": "200m",
                "memory": "256Mi",
                "ephemeral_storage": "96Mi"
            }
        }
    ]
}

Response Example

{
    "sandbox": {
        "id": "sbx-direct-1",
        "phase": "creating"
    }
}

DELETE /api/v1/nodes/{name}/sandboxes/{id}

Response Example

{
    "id": "sbx-direct-1",
    "phase": "deleted"
}

GET /api/v1/nodes/{name}/sandboxes/{id}/logs

Response Example

{
    "sandbox_id": "sbx-demo-1",
    "logs": {
        "lines": ["[app] line1", "[db] line2"]
    }
}

The older /api/v1/nodes/{name}/sandboxes/{id}/containers/{container}/logs proxy remains available for per-container compatibility.

POST /api/v1/nodes/{id}/reconcile

Trigger sbxlet reconcile on selected node.

Response Example

{
    "ok": true
}

Field Semantics

Node state

Sandbox status.phase

Sandbox status.assigned_ports

Resolved host port mapping used by scheduler and runtime provisioning:

Node resources.external and Sandbox status.external

Sandbox Private IP Sync

Readiness Probe Semantics

Configuration