Containers
All container endpoints are under https://api.hzel.org/api/v1/containers. Mutating endpoints (POST) require an x-csrf-token header when called from a browser session. PAT and OAuth Bearer tokens are exempt from CSRF.
GET /api/v1/containers
Section titled “GET /api/v1/containers”List containers visible to the authenticated user. Admins see all containers; regular users see only their own.
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
Success 200
{ "data": [ { "id": "01942cf7-…", "user_id": "01942cf6-…", "hostname": "my-box", "state": "running", "cpu_cores": 1, "memory_mb": 512, "disk_gb": 18, "created_at": "2026-03-28T00:00:00Z" } ]}Errors
| Status | error.code | Reason |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid auth |
POST /api/v1/containers
Section titled “POST /api/v1/containers”Create a new container.
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
Content-Type | application/json | Yes |
x-csrf-token | <csrf_token> | Yes, for session auth only |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
hostname | string | Yes | Unique name for the container |
cpu_cores | integer | No | Default: 1 |
memory_mb | integer | No | Default: 512 |
disk_gb | integer | No | 18–32, default: 18 |
Success 200
{ "data": { "id": "01942cf7-…", "user_id": "01942cf6-…", "hostname": "my-box", "state": "provisioning", "cpu_cores": 1, "memory_mb": 512, "disk_gb": 18, "created_at": "2026-03-28T00:00:00Z" }}Errors
| Status | error.code | Reason |
|---|---|---|
400 | BAD_REQUEST | Missing or invalid fields |
401 | UNAUTHORIZED | Missing or invalid auth |
403 | CSRF_REJECTED | Session auth missing x-csrf-token |
GET /api/v1/containers/{container_id}
Section titled “GET /api/v1/containers/{container_id}”Fetch a single container by UUID.
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
Success 200 — { "data": <ContainerRecord> }
Errors
| Status | error.code | Reason |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid auth |
404 | NOT_FOUND | Container not found or not owned by user |
POST /api/v1/containers/{container_id}/start
Section titled “POST /api/v1/containers/{container_id}/start”Start a stopped container. Polls until the state is confirmed running.
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
x-csrf-token | <csrf_token> | Yes, for session auth only |
Success 200 — { "data": <ContainerRecord> } with state: "running"
Errors
| Status | error.code | Reason |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid auth |
403 | CSRF_REJECTED | Session auth missing x-csrf-token |
404 | NOT_FOUND | Container not found |
POST /api/v1/containers/{container_id}/stop
Section titled “POST /api/v1/containers/{container_id}/stop”Stop a running container.
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
x-csrf-token | <csrf_token> | Yes, for session auth only |
Success 200 — { "data": <ContainerRecord> } with state: "stopped"
Errors
| Status | error.code | Reason |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid auth |
403 | CSRF_REJECTED | Session auth missing x-csrf-token |
404 | NOT_FOUND | Container not found |
POST /api/v1/containers/{container_id}/restart
Section titled “POST /api/v1/containers/{container_id}/restart”Restart a container.
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
x-csrf-token | <csrf_token> | Yes, for session auth only |
Success 200 — { "data": <ContainerRecord> } with state: "running"
Errors
| Status | error.code | Reason |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid auth |
403 | CSRF_REJECTED | Session auth missing x-csrf-token |
404 | NOT_FOUND | Container not found |
GET /api/v1/containers/{container_id}/metrics
Section titled “GET /api/v1/containers/{container_id}/metrics”Fetch current CPU, memory, and disk utilization.
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
Success 200
{ "data": { "cpu_percent": 12.4, "memory_used_mb": 203, "memory_total_mb": 512, "disk_used_gb": 4.1, "disk_total_gb": 18 }}Errors
| Status | error.code | Reason |
|---|---|---|
401 | UNAUTHORIZED | Missing or invalid auth |
404 | NOT_FOUND | Container not found |
ContainerRecord
Section titled “ContainerRecord”{ "id": "01942cf7-…", "user_id": "01942cf6-…", "hostname": "my-box", "state": "running", "cpu_cores": 1, "memory_mb": 512, "disk_gb": 18, "created_at": "2026-03-28T00:00:00Z"}state values: "running" | "stopped" | "provisioning" | "failed"