{"openapi":"3.1.0","info":{"title":"Sandbox Manager API","description":"Web-based orchestration platform for Claude Code containers with terminal access,\nMCP configuration, and LLM routing through LiteLLM.\n","version":"1.0.0","contact":{"name":"Haiven Infrastructure Team","url":"https://home.haiven.site"}},"servers":[{"url":"https://sandbox.haiven.site","description":"Production (public)"},{"url":"http://sandbox-manager:8900","description":"Internal (Docker network)"}],"tags":[{"name":"Health","description":"Service health endpoints"},{"name":"Authentication","description":"User authentication"},{"name":"Containers","description":"Container lifecycle management"},{"name":"Files","description":"File system browsing"}],"paths":{"/api/health":{"get":{"tags":["Health"],"summary":"Health check","operationId":"getHealth","responses":{"200":{"description":"Service healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"503":{"description":"Service unhealthy"}}}},"/api/auth/login":{"post":{"tags":["Authentication"],"summary":"Authenticate user","operationId":"login","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"Login successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/auth/logout":{"post":{"tags":["Authentication"],"summary":"Logout user","operationId":"logout","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Logout successful"}}}},"/api/containers":{"get":{"tags":["Containers"],"summary":"List containers","operationId":"listContainers","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["running","stopped","all"],"default":"all"}}],"responses":{"200":{"description":"Container list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Containers"],"summary":"Create container","operationId":"createContainer","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContainerRequest"}}}},"responses":{"201":{"description":"Container created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/containers/{id}":{"get":{"tags":["Containers"],"summary":"Get container details","operationId":"getContainer","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/ContainerId"}],"responses":{"200":{"description":"Container details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerDetailResponse"}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Containers"],"summary":"Delete container","operationId":"deleteContainer","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/ContainerId"}],"responses":{"204":{"description":"Container deleted"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/containers/{id}/start":{"post":{"tags":["Containers"],"summary":"Start container","operationId":"startContainer","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/ContainerId"}],"responses":{"200":{"description":"Container started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerActionResponse"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/containers/{id}/stop":{"post":{"tags":["Containers"],"summary":"Stop container","operationId":"stopContainer","security":[{"bearerAuth":[]}],"parameters":[{"$ref":"#/components/parameters/ContainerId"}],"responses":{"200":{"description":"Container stopped","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContainerActionResponse"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/files/browse":{"get":{"tags":["Files"],"summary":"Browse file system","operationId":"browseFiles","security":[{"bearerAuth":[]}],"parameters":[{"name":"path","in":"query","schema":{"type":"string","default":"/"}}],"responses":{"200":{"description":"Directory contents","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileBrowseResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"parameters":{"ContainerId":{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Container ID"}},"schemas":{"HealthResponse":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"]},"service":{"type":"string"},"version":{"type":"string"},"uptime_seconds":{"type":"integer"},"checks":{"type":"object","properties":{"database":{"type":"string"},"docker":{"type":"string"},"litellm":{"type":"string"}}}}},"LoginRequest":{"type":"object","required":["username","password"],"properties":{"username":{"type":"string"},"password":{"type":"string","format":"password"}}},"LoginResponse":{"type":"object","properties":{"success":{"type":"boolean"},"token":{"type":"string"},"expires_at":{"type":"string","format":"date-time"}}},"ContainerListResponse":{"type":"object","properties":{"containers":{"type":"array","items":{"$ref":"#/components/schemas/ContainerSummary"}},"total":{"type":"integer"}}},"ContainerSummary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["running","stopped","error"]},"model":{"type":"string"},"project_path":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"CreateContainerRequest":{"type":"object","required":["name","project_path"],"properties":{"name":{"type":"string"},"project_path":{"type":"string"},"model":{"type":"string","default":"claude-sonnet-4-5-20250929"},"mcp_preset":{"type":"string","enum":["none","documentation","development","custom"]},"mcp_config":{"type":"object"}}},"ContainerResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string"},"model":{"type":"string"},"project_path":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"ContainerDetailResponse":{"allOf":[{"$ref":"#/components/schemas/ContainerResponse"},{"type":"object","properties":{"container_id":{"type":"string"},"mcp_config":{"type":"object"},"started_at":{"type":"string","format":"date-time"},"cpu_usage":{"type":"number"},"memory_usage_mb":{"type":"integer"}}}]},"ContainerActionResponse":{"type":"object","properties":{"id":{"type":"string"},"action":{"type":"string","enum":["start","stop"]},"status":{"type":"string"},"message":{"type":"string"}}},"FileBrowseResponse":{"type":"object","properties":{"path":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string","enum":["file","directory"]},"size":{"type":"integer"}}}}}},"ErrorResponse":{"type":"object","properties":{"error":{"type":"string"},"code":{"type":"string"},"details":{"type":"object"}}}},"responses":{"BadRequest":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Unauthorized":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}