Daemon Management
Section titled “Daemon Management”Use these endpoints to list, retrieve, create, update, and remove daemon programs. The daemon manages long-running processes through supervisord. Endpoints are split into two groups:
- Programs — permanent definitions stored in
programs.jsonand registered with supervisord. Use these for programs that must survive container reboots. - Quick Start — ephemeral (temporary) programs tracked in
ephemeral.json. They never auto-start on boot and are removed on stop, exit, or TTL expiry. Use these for one-off scripts, temporary test servers, debug tasks, or CI/CD jobs.
Programs
Section titled “Programs”GET /api/v1/daemon/programs
Section titled “GET /api/v1/daemon/programs”Retrieves a complete list of all configured daemon programs with their full configuration details. Supports multiple filters that can be combined: hoody_kit, lazy_load, enabled, boot. Optionally include runtime status and resource statistics for each program.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
hoody_kit | query | string | No | Filter by hoody_kit status. Literal values: "true", "false". |
lazy_load | query | string | No | Filter by lazy_load status. Literal values: "true", "false". |
enabled | query | string | No | Filter by enabled status. Literal values: "true", "false". |
boot | query | string | No | Filter by boot status. Literal values: "true", "false". |
port | query | integer | No | Filter programs by single port number. Returns programs whose port_range includes this specific port (e.g. ?port=8042). |
port_from | query | integer | No | Filter by port range start. Must be used with port_to. |
port_to | query | integer | No | Filter by port range end. Must be used with port_from. |
include_status | query | string | No | Include runtime status. Literal values: "true", "false". |
include_stats | query | string | No | Include resource stats (CPU, memory, process tree). Implies include_status=true. Literal values: "true", "false". |
Response
Section titled “Response”200 — Successfully retrieved list of all programs
{ "programs": [ { "id": 1, "name": "web-server", "description": "Nginx web server", "enabled": true, "command": "nginx -g \"daemon off;\"", "boot": true, "delay_seconds": 5, "autorestart": "unexpected", "user": "www-data", "environment": { "NGINX_PORT": "80" }, "directory": "/var/www", "priority": 999, "stdout_logfile": "/var/log/nginx/access.log", "stderr_logfile": "/var/log/nginx/error.log", "hoody_kit": false } ]}{ "programs": []}await client.daemon.programs.listIterator({ enabled: "true", include_status: "true"});GET /api/v1/daemon/programs/{id}
Section titled “GET /api/v1/daemon/programs/{id}”Retrieves detailed configuration for a single program by its unique numeric ID. Returns the complete program configuration including all optional fields.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | Unique numeric identifier of the program. |
Response
Section titled “Response”{ "success": true, "program": { "id": 1, "name": "web-server", "description": "Nginx web server", "enabled": true, "command": "nginx -g \"daemon off;\"", "boot": true, "delay_seconds": 5, "autorestart": "unexpected", "user": "www-data", "environment": {}, "directory": "/var/www", "priority": 999 }}{ "success": false, "error": "Program with ID 999 not found"}const program = await client.daemon.programs.get(1);POST /api/v1/daemon/programs/add
Section titled “POST /api/v1/daemon/programs/add”Creates a new daemon program from a JSON request body. The program is validated, added to the configuration, and registered with supervisord if enabled. Use for custom programs only — not system services.
Correct examples: node app.js, python my_script.py, ruby custom_server.rb, ./my-binary
Wrong examples: apache2, nginx, postgresql, mysql (use systemctl for these)
Request Body
Section titled “Request Body”{ "name": "simple-app", "command": "echo \"Hello World\"", "user": "root"}{ "name": "nodejs-app", "description": "Production Node.js application", "command": "node server.js", "user": "nodejs", "enabled": true, "boot": true, "delay_seconds": 10, "autorestart": "unexpected", "directory": "/opt/myapp", "priority": 100, "environment": { "NODE_ENV": "production", "PORT": "3000", "DATABASE_URL": "postgresql://localhost/mydb" }, "stdout_logfile": "/var/log/myapp/stdout.log", "stderr_logfile": "/var/log/myapp/stderr.log"}{ "name": "my-api-server", "description": "Custom Python Flask API", "command": "python -m flask run --host=0.0.0.0 --port=5000", "user": "appuser", "enabled": true, "boot": true, "delay_seconds": 5, "autorestart": "unexpected", "directory": "/opt/my-api", "priority": 999, "environment": { "FLASK_APP": "app.py", "FLASK_ENV": "production" }, "stdout_logfile": "/var/log/my-api/access.log", "stderr_logfile": "/var/log/my-api/error.log"}{ "name": "monitored-api", "description": "API server with webhook notifications", "command": "node server.js", "user": "nodejs", "enabled": true, "boot": true, "directory": "/opt/api", "webhooks": { "enabled": true, "urls": [ "https://monitoring.example.com/webhook", "https://pagerduty.example.com/critical" ], "events": [ "RUNNING", "FATAL", "BACKOFF" ], "headers": { "Authorization": "Bearer secret-token", "X-Service": "api" }, "timeout": 10, "retry": 3 }}Response
Section titled “Response”{ "success": true, "id": 2, "program": { "id": 2, "name": "nodejs-app", "description": "Node.js application", "enabled": true, "command": "node app.js", "boot": false, "delay_seconds": 0, "autorestart": "unexpected", "user": "nodejs", "environment": { "NODE_ENV": "production" }, "directory": "/opt/app", "priority": 999 }}{ "success": false, "error": "User \"invalid-user\" does not exist on the system"}const result = await client.daemon.programs.add({ name: "nodejs-app", command: "node server.js", user: "nodejs", enabled: true, boot: true});POST /api/v1/daemon/programs/edit/{id}
Section titled “POST /api/v1/daemon/programs/edit/{id}”Updates an existing program configuration. Only provided fields are updated — unspecified fields retain their current values.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | Unique numeric identifier of the program. |
Request Body
Section titled “Request Body”{ "enabled": false}{ "description": "Updated description", "command": "node server.js --production", "environment": { "NODE_ENV": "production", "PORT": "8080" }}{ "name": "updated-app", "description": "Completely updated application", "command": "node app.js", "user": "nodejs", "enabled": true, "boot": true, "delay_seconds": 15, "autorestart": "true", "directory": "/opt/newpath", "priority": 50, "environment": { "NODE_ENV": "production" }}Response
Section titled “Response”{ "success": true, "program": { "id": 1, "name": "updated-app", "description": "Completely updated application", "enabled": true, "command": "node app.js", "boot": true, "delay_seconds": 15, "autorestart": "true", "user": "nodejs", "environment": { "NODE_ENV": "production" }, "directory": "/opt/newpath", "priority": 50 }}{ "success": false, "error": "Validation failed: 'command' cannot be empty"}{ "success": false, "error": "Program with ID 999 not found"}const result = await client.daemon.programs.edit(1, { description: "Updated description", command: "node server.js --production", environment: { NODE_ENV: "production", PORT: "8080" }});POST /api/v1/daemon/programs/remove/{id}
Section titled “POST /api/v1/daemon/programs/remove/{id}”Permanently deletes a program from the configuration. If the program is running, it will be stopped before removal. This is a destructive operation that cannot be undone.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | integer | Yes | Unique numeric identifier of the program. |
Response
Section titled “Response”{ "success": true, "id": 1}{ "success": false, "error": "Program with ID 999 not found"}await client.daemon.programs.remove(1);POST /api/v1/daemon/programs/reset
Section titled “POST /api/v1/daemon/programs/reset”Replaces the current programs.json with the initial default snapshot (programs.default.json) created at container setup time. Stops all managed programs, removes their supervisord configs, and re-applies the default boot programs. Use this when programs have been misconfigured and a clean slate is needed.
This endpoint takes no parameters and no request body.
Response
Section titled “Response”{ "success": true}{ "success": false, "error": "Default programs file (programs.default.json) is missing or corrupt"}await client.daemon.programs.reset();Quick Start
Section titled “Quick Start”Quick Start manages ephemeral (temporary) programs. They are not saved to programs.json, are tracked in ephemeral.json for crash recovery, and are auto-cleaned on manual stop, program exit, container reboot, or TTL expiry.
GET /api/v1/daemon/quick-start
Section titled “GET /api/v1/daemon/quick-start”Returns all currently tracked ephemeral programs with their current runtime status. Shows programs that are running or pending cleanup.
This endpoint takes no parameters.
Response
Section titled “Response”200 — Successfully retrieved list of ephemeral programs
{ "success": true, "count": 2, "ephemeral_programs": [ { "temporary_id": "quick_1731605123", "name": "quick_python_1731605123", "command": "python batch-job.py", "user": "worker", "status": "running", "created_at": "2024-11-14T18:32:03Z", "uptime": "0:05:32" }, { "temporary_id": "quick_1731605456", "name": "my-temp-server", "command": "node server.js", "user": "nodejs", "status": "running", "created_at": "2024-11-14T18:37:36Z", "expires_at": "2024-11-14T19:37:36Z", "uptime": "0:00:08" } ]}{ "success": true, "count": 0, "ephemeral_programs": []}await client.daemon.quickStart.listIterator();POST /api/v1/daemon/quick-start
Section titled “POST /api/v1/daemon/quick-start”Creates and starts a temporary custom program that auto-cleans when stopped or on container reboot. Custom programs only — system services (apache2, nginx, etc.) belong under systemctl.
Key features:
- Not saved to
programs.json(temporary only) - Tracked in
ephemeral.jsonfor crash recovery - Always created with
autostart=false(does not auto-start on reboot) - Auto-cleanup on: manual stop, program exit, container reboot, TTL expiry
- Full supervisord configuration support (
autorestart,environment, logs, etc.)
Request Body
Section titled “Request Body”{ "command": "python batch-job.py", "user": "worker"}{ "command": "python process-data.py", "user": "worker", "autorestart": "unexpected", "directory": "/opt/scripts", "environment": { "MODE": "production" }}{ "command": "node test-server.js", "user": "nodejs", "name": "temp-test-server", "directory": "/opt/test", "ttl": 1800, "environment": { "PORT": "9999", "NODE_ENV": "test" }, "wait": true}{ "command": "python debug-worker.py", "user": "admin", "autorestart": "unexpected", "stdout_logfile": "/tmp/debug.log", "stderr_logfile": "/tmp/debug-error.log"}Response
Section titled “Response”{ "success": true, "temporary_id": "quick_1731605123", "name": "quick_python_1731605123", "status": "running", "pid": 12345, "uptime": "0:00:05", "created_at": "2024-11-14T18:32:03Z"}{ "success": true, "temporary_id": "quick_1731605456", "name": "quick_node_1731605456", "status": "running", "pid": 12350, "uptime": "0:00:02", "created_at": "2024-11-14T18:37:36Z"}{ "success": true, "temporary_id": "quick_1731606000", "name": "my-temp-server", "status": "running", "created_at": "2024-11-14T18:46:40Z", "expires_at": "2024-11-14T19:16:40Z"}{ "success": false, "error": "User \"invalid-user\" does not exist on the system"}const result = await client.daemon.quickStart.launch({ command: "python batch-job.py", user: "worker", ttl: 3600, wait: true});GET /api/v1/daemon/quick-start/{id}/status
Section titled “GET /api/v1/daemon/quick-start/{id}/status”Retrieves current runtime status for a specific ephemeral program by its temporary_id.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Temporary ID of the ephemeral program (format: quick_<timestamp>). |
Response
Section titled “Response”{ "success": true, "temporary_id": "quick_1731605123", "name": "quick_python_1731605123", "status": "running", "pid": 12345, "uptime": "0:15:30", "created_at": "2024-11-14T18:32:03Z"}{ "success": true, "temporary_id": "quick_1731605123", "name": "quick_python_1731605123", "status": "stopped", "created_at": "2024-11-14T18:32:03Z"}{ "success": true, "temporary_id": "quick_1731606000", "name": "my-temp-server", "status": "running", "created_at": "2024-11-14T18:46:40Z", "expires_at": "2024-11-14T19:46:40Z"}{ "success": false, "error": "Ephemeral program with ID quick_9999999999 not found"}const status = await client.daemon.quickStart.getStatus("quick_1731605123");POST /api/v1/daemon/quick-start/{id}/stop
Section titled “POST /api/v1/daemon/quick-start/{id}/stop”Stops the ephemeral program and removes its configuration completely.
Actions performed:
- Stop program via supervisorctl
- Delete supervisord config file
- Remove from
ephemeral.jsontracking - Update supervisord
The program is completely removed from the system and cannot be restarted.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Temporary ID of the ephemeral program to stop. |
Response
Section titled “Response”{ "success": true, "temporary_id": "quick_1731605123", "cleaned_up": true, "message": "Program stopped and configuration removed"}{ "success": false, "error": "Ephemeral program with ID quick_9999999999 not found"}await client.daemon.quickStart.stop("quick_1731605123");GET /api/v1/daemon/quick-start/{id}/logs
Section titled “GET /api/v1/daemon/quick-start/{id}/logs”Retrieve the last N lines from an ephemeral program’s stdout or stderr log file.
Parameters
Section titled “Parameters”| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | Yes | Ephemeral program temporary ID. |
type | query | string | No | Log stream. Allowed values: stdout, stderr. Default: "stdout". |
lines | query | integer | No | Number of lines to return from end of file. Default: 100. |
Response
Section titled “Response”{ "success": true, "logs": "[2024-11-14 18:32:03] Starting batch job...\n[2024-11-14 18:32:05] Processing 100 records\n[2024-11-14 18:32:08] Complete", "type": "stdout", "lines": 3, "log_file": "/var/log/quick_python_1731605123.stdout.log"}{ "success": false, "error": "Invalid 'type' parameter: must be 'stdout' or 'stderr'"}{ "success": false, "error": "Ephemeral program with ID quick_9999999999 not found"}const logs = await client.daemon.quickStart.getEphemeralLogs( "quick_1731605123", { type: "stdout", lines: 50 });