Base URL: http://localhost:8082
{
"error": "error message"
}
200 OKResponse
{
"ok": true
}
Create or update a node object.
200 OK400 Bad Request (invalid request body or invalid id/ip/port)500 Internal Server Error (storage or internal error)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"
}
}
List all registered nodes.
200 OK500 Internal Server ErrorResponse
{
"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 a single node.
200 OK404 Not Found (node not found)500 Internal Server ErrorResponse
{
"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 a node registration.
force (optional, boolean)
false or omitted: orchestrator calls node APIs (sandbox delete/reconcile) and fails node deletion if those calls fail.true: orchestrator skips node API failures and force-deletes node metadata.force=true only when the node is already confirmed gone/unreachable.200 OK400 Bad Request (empty/invalid name)500 Internal Server ErrorResponse
{
"deleted": "node-a"
}
Examples:
DELETE /api/v1/nodes/node-aDELETE /api/v1/nodes/node-a?force=trueTrigger immediate health/resource probe against sbxlet.
200 OK404 Not Found (node not found)500 Internal Server ErrorResponse
{
"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:
okfailedCreate a control-plane sandbox object for scheduling and reconciliation.
201 Created400 Bad Request (validation)500 Internal Server ErrorRequest
{
"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"
}
}
]
}
}
spec.readiness_probe is optional.protocol supports tcp and http. If http is used, path is required and must start with /.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"
}
}
List all control-plane sandbox objects.
200 OK500 Internal Server ErrorResponse
{
"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 one control-plane sandbox object.
200 OK404 Not Found (sandbox not found)500 Internal Server ErrorResponse
{
"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 one control-plane sandbox object.
200 OK400 Bad Request (invalid id)404 Not Found (sandbox not found)500 Internal Server ErrorResponse
{
"deleted": "sbx-demo-1"
}
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.
Query params:
cursor (optional)limit (optional, default 20)
200 OKResponse Example
{
"items": [
{
"id": "sbx-demo-1",
"phase": "running"
}
],
"next_cursor": "sbx-demo-1",
"external": "203.0.113.10"
}
200 OKResponse Example
{
"sandbox": {
"id": "sbx-demo-1",
"phase": "running"
},
"external": "203.0.113.10"
}
Create sandbox directly on selected node (sbxlet API pass-through).
200 OK400 Bad Request (invalid JSON body)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"
}
}
200 OKResponse Example
{
"id": "sbx-direct-1",
"phase": "deleted"
}
200 OKResponse 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.
Trigger sbxlet reconcile on selected node.
200 OKResponse Example
{
"ok": true
}
stateUnknown: node exists but readiness not yet convergedReady: heartbeat success streak reached thresholdNotReady: heartbeat failure streak reached thresholdstatus.phasePending: object created, not yet scheduledScheduled: node and host ports assigned; sbxlet runtime creation/readiness in progressRunning: sbxlet reports sandbox running (including readiness probe success when configured)Failed: scheduling/runtime operation failedDeleting: delete flow in progressstatus.assigned_portsResolved host port mapping used by scheduler and runtime provisioning:
host_port: orchestrator-assigned host-side port (automatically selected within configured range)
spec.ports, client-sent host_port is accepted for backward compatibility but ignored.container_port: target container portprotocol: tcp or udpresources.external and Sandbox status.externalresources.external: value from External object bound to node (POST /api/v1/externals).status.external: snapshot copied from node resources during scheduling/status sync.(none).external field.sandbox.status.ip during status sync.ip can appear before Running.spec.readiness_probe is forwarded to sbxlet as runtime readiness configuration.readiness_probe is omitted, sbxlet transitions to running immediately after provisioning is complete.readiness_probe is set, sbxlet stays creating until probe success threshold is met; failures beyond threshold transition sbxlet to error, which syncs to orchestrator Failed.sandboxIP:port). This does not guarantee external/published host-port reachability from every client network path./var/lib/sandboxd/sbxorch_config.jsonconfigs/sbxorch_config.jsonORCH_NODE_PROBE_TIMEOUT, ORCH_SANDBOX_OP_TIMEOUT, ORCH_CREATE_RPS, and ORCH_CREATE_BURST, but JSON config is the recommended mechanism.