Skip to content
Hoody.com

The Hoody Container Daemon supervises long-running programs through supervisord. This page documents the endpoints for listing, inspecting, creating, editing, removing, and resetting supervised programs, plus launching and managing ephemeral (Quick Start) programs. Use these endpoints whenever you need to add a custom service to a container, change an existing program’s settings, run a one-off task, or reset to a clean default configuration.

All endpoints in this page are reached through the container’s daemon-1 hostname: https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com.

Lists every configured program. Combine the filters to narrow the result by hoody_kit, lazy_load, enabled, or boot status. Use the port filters to find the program that owns a specific port or that overlaps with a port range. Pass include_status=true to attach runtime status to each entry, or include_stats=true for CPU and memory stats.

NameInTypeRequiredDescription
hoody_kitquerystringNoFilter by hoody_kit status. Use "true" for Kit programs only, "false" for user programs.
lazy_loadquerystringNoFilter by lazy_load status. Use "true" for lazy-loaded programs, "false" for auto-start programs.
enabledquerystringNoFilter by enabled status.
bootquerystringNoFilter by boot status. Use "true" for auto-start on boot, "false" for manual-start.
portqueryintegerNoFilter by a single port. Returns only programs whose port_range includes this port. Example: ?port=8042.
port_fromqueryintegerNoFilter by port range start. Must be used with port_to. Returns programs whose port ranges overlap using program.start <= port_to AND program.end >= port_from.
port_toqueryintegerNoFilter by port range end. Must be used with port_from.
include_statusquerystringNoInclude runtime status for each program. Adds a status field with the current state, instances, and process details.
include_statsquerystringNoInclude CPU and memory stats. Implies include_status=true. Adds a stats field with pid, started_at, cpu_percent, memory_rss_bytes, process_count, and a per-process breakdown. Only present for running programs.

The boolean query parameters (hoody_kit, lazy_load, enabled, boot, include_status, include_stats) are strict: only true or false (case-insensitive). Values such as 1, yes, on, or empty return HTTP 400.

Terminal window
curl -X GET "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/programs?include_status=true" \
-H "Authorization: Bearer <token>"

Retrieves detailed configuration for a single program by its numeric ID.

NameInTypeRequiredDescription
idpathintegerYesUnique numeric identifier of the program.
Terminal window
curl -X GET "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/programs/1" \
-H "Authorization: Bearer <token>"

Creates a new custom program. The program is validated and added to programs.json. It is applied to supervisord only when it is enabled AND has either boot: true or a port_range; an enabled program with neither is registered but not started.

NameTypeRequiredDescription
idintegerNoSpecific ID to assign (auto-assigned if omitted).
namestringYesProgram name (must be unique; cannot contain quotes).
descriptionstringNoHuman-readable description.
commandstringYesCommand to execute with full arguments for your custom program. Use only for custom code; system services belong under systemctl.
userstringYesSystem user (must exist on the system).
enabledbooleanNoEnable the program immediately. Default: true.
bootbooleanNoStart automatically on system boot. Default: false. Cannot be true when lazy_load is true.
delay_secondsintegerNoSeconds the program must stay running for supervisord to consider the start successful (supervisord’s startsecs). Default: 0.
autorestartstringNoRestart policy: "true", "false", or "unexpected". Default: "unexpected".
directorystringNoWorking directory path (defaults to user home if omitted).
priorityintegerNoStart priority (1-999, lower starts first). Default: 999.
stdout_logfilestringNoAbsolute path for standard output log. Must be under /hoody/storage/hoody-daemon/logs. Example: /hoody/storage/hoody-daemon/logs/<name>/stdout.log.
stderr_logfilestringNoAbsolute path for standard error log. Must be under /hoody/storage/hoody-daemon/logs. Example: /hoody/storage/hoody-daemon/logs/<name>/stderr.log.
logs_enabledbooleanNoWhether logging is enabled. Default: true.
log_max_bytesintegerNoMaximum size of each log file in bytes before rotation. Default: 5242880 (5MB).
log_backupsintegerNoNumber of rotated backup log files to keep. Default: 2.
environmentobjectNoEnvironment variables as key-value pairs (string values).
port_rangeobjectNoPort range for multi-instance programs. Each port in the range creates a separate instance. Object with start and end (1-65535, max 4096 ports). Ranges must not overlap other programs’ ranges.
port_paramstringNoCLI flag used to pass the port to the command (server default --port). Valid only together with port_range; an empty string is rejected.
lazy_loadbooleanNoWhen true, the program is not started automatically. Default: false. Requires port_range for proxy-driven activation. Cannot be combined with boot: true.
displaystringNoX11 DISPLAY number for GUI programs (e.g. ":1" or "1").
terminal_idintegerNoHoody Terminal integration: Session ID (1-65535).
terminal_shellstringNoHoody Terminal integration: shell. One of bash, zsh, fish, sh, tmux. Requires terminal_id.
terminal_interactivebooleanNoHoody Terminal integration: override auto-detection. true = interactive, false = service, omitted = auto-detect.
webhooksobjectNoWebhook notification configuration. Object with enabled, urls, events, headers, timeout, retry.
hoody_kitbooleanNoRead-only. Server-derived: true when the program’s working directory is under /hoody/plugins, OR when it carries an official Kit name and its executable lives under /hoody/plugins (this is what classifies hoody-agent). Any value supplied in the body is ignored.
Terminal window
curl -X POST "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/programs/add" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"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"
},
"stdout_logfile": "/hoody/storage/hoody-daemon/logs/nodejs-app/stdout.log",
"stderr_logfile": "/hoody/storage/hoody-daemon/logs/nodejs-app/stderr.log"
}'

Updates an existing program configuration. Only provided fields are updated; unspecified fields retain their current values.

NameInTypeRequiredDescription
idpathintegerYesUnique numeric identifier of the program.
NameTypeRequiredDescription
idintegerNoSpecific ID to assign.
namestringNoProgram name (must be unique; cannot contain quotes).
descriptionstringNoHuman-readable description.
commandstringNoCommand to execute with full arguments for your custom program.
userstringNoSystem user (must exist on the system).
enabledbooleanNoEnable the program immediately.
bootbooleanNoStart automatically on system boot. Cannot be true when lazy_load is true.
delay_secondsintegerNoSeconds the program must stay running for supervisord to consider the start successful (supervisord’s startsecs).
autorestartstringNoRestart policy: "true", "false", or "unexpected".
directorystringNoWorking directory path.
priorityintegerNoStart priority (1-999, lower starts first).
stdout_logfilestringNoAbsolute path for standard output log. Must be under /hoody/storage/hoody-daemon/logs.
stderr_logfilestringNoAbsolute path for standard error log. Must be under /hoody/storage/hoody-daemon/logs.
logs_enabledbooleanNoWhether logging is enabled.
log_max_bytesintegerNoMaximum size of each log file in bytes before rotation.
log_backupsintegerNoNumber of rotated backup log files to keep.
environmentobjectNoEnvironment variables as key-value pairs (string values).
port_rangeobjectNoPort range for multi-instance programs. Object with start and end (1-65535, max 4096 ports). The program’s own range is excluded from overlap checks.
port_paramstringNoCLI flag used to pass the port to the command. Valid only together with port_range.
lazy_loadbooleanNoWhen true, the program is not started automatically. Cannot be combined with boot: true.
displaystringNoX11 DISPLAY number for GUI programs.
terminal_idintegerNoHoody Terminal integration: Session ID (1-65535).
terminal_shellstringNoHoody Terminal integration: shell. One of bash, zsh, fish, sh, tmux. Requires terminal_id.
terminal_interactivebooleanNoHoody Terminal integration: override auto-detection.
webhooksobjectNoWebhook notification configuration.
hoody_kitbooleanNoRead-only. Server-derived; any value supplied is ignored.
Terminal window
curl -X POST "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/programs/edit/1" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"description": "Updated description",
"command": "node server.js --production",
"environment": {
"NODE_ENV": "production",
"PORT": "8080"
}
}'

Permanently deletes a program from the configuration. If the program is running, it is stopped before removal. This is a destructive operation that cannot be undone.

NameInTypeRequiredDescription
idpathintegerYesUnique numeric identifier of the program.
Terminal window
curl -X POST "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/programs/remove/1" \
-H "Authorization: Bearer <token>"

Replaces the current programs.json with the initial default snapshot (/hoody/storage/hoody-daemon/config/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.

Terminal window
curl -X POST "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/programs/reset" \
-H "Authorization: Bearer <token>"

lazy_load: true (boolean, default false) tells the daemon to register a program without starting it. The program stays in programs.json and costs nothing until something asks for it. This is how most of the Hoody Kit behaves already — a container is not running fourteen daemons, it is running the ones someone has actually opened. Of the 18 Kit programs shipped, 13 are registered with lazy_load: true: hoody-browser, hoody-code, hoody-curl, hoody-display, hoody-exec, hoody-files, hoody-notes, hoody-notifications, hoody-pipe, hoody-run, hoody-sqlite, hoody-tunnel, and hoody-workspaces. The remaining 5 (hoody-agent, hoody-cron, hoody-egress, hoody-watch, and hoody-terminal when the terminal kit is enabled) are registered eagerly.

The mechanism differs by program shape:

  • With port_range: lazy_load explicitly renders autostart=false, and every port in the range becomes its own registered-but-not-running instance. Hoody Proxy can then ask the daemon for the program owning a given port and start it.
  • Without port_range: supervisord’s autostart follows boot directly. The API’s rejection of lazy_load: true + boot: true is what forces autostart to false in this case.

What happens on the first request:

  1. A user (or agent) opens https://{projectId}-{containerId}-notes-1.{server}.containers.hoody.com. Nothing is listening yet because hoody-notes is registered lazy_load: true.
  2. The proxy resolves the port from the hostname, then queries the daemon: GET /api/v1/daemon/programs?lazy_load=true&port={port}&include_status=true.
  3. If a matching enabled program is not RUNNING, the proxy calls POST /api/v1/daemon/programs/{id}/start with { "if_not_running": true, "wait": true, "timeout": 30 } (plus "port" for a port-range program). The proxy HOLDS the client request until the process reaches RUNNING, then proxies it. The caller sees one slow request, not an error. If the start fails or the wait times out, the proxy does NOT fail the request — it continues with normal proxying.
  4. Later requests hit a short per-port cache and pay nothing. The 30-second start timeout and the 5-second cache are defaults an operator can change (SOCKET_ACTIVATION_START_TIMEOUT / SOCKET_ACTIVATION_CACHE_LIFETIME).

lazy_load: true together with boot: true is rejected on create and edit with HTTP 400. The daemon returns the validator’s message verbatim:

Programs with lazy_load enabled cannot have boot enabled. Lazy-loaded programs are started on-demand by Hoody Proxy.

Quick Start launches ephemeral (temporary) programs that are NOT saved to programs.json. They live in ephemeral.json for crash recovery and are reaped automatically.

Ephemeral IDs have the format quick_<milliseconds>_<sequence> (for example, quick_1731605123000_0). Default ephemeral log paths are keyed on the program NAME: /hoody/storage/hoody-daemon/logs/<name>/stdout.log.

Cleanup is NOT simply “on exit”. STOPPED and FATAL are always reaped, but EXITED is reaped only when restart is disabled. Under the default autorestart: "unexpected", an exited job is retained until TTL, manual stop, or reboot.

Creates and starts a temporary custom program that auto-cleans when stopped or on container reboot.

NameTypeRequiredDescription
commandstringYesCommand to execute with full arguments for your custom program or script. Custom code only; system services belong under systemctl.
userstringYesSystem user to run as (must exist on the system).
namestringNoCustom name (auto-generated if omitted). Cannot contain quotes.
autorestartstringNoRestart policy while running: "true" (always), "false" (never), "unexpected" (only on crashes). Default: "unexpected".
directorystringNoWorking directory (defaults to user home if not specified).
environmentobjectNoEnvironment variables as key-value pairs (string values).
priorityintegerNoStart priority (1-999, lower starts first). Default: 999.
delay_secondsintegerNoSeconds the program must stay running for supervisord to consider the start successful. Default: 0.
stdout_logfilestringNoAbsolute path for standard output log. Must be under /hoody/storage/hoody-daemon/logs. Example: /hoody/storage/hoody-daemon/logs/<name>/stdout.log.
stderr_logfilestringNoAbsolute path for standard error log. Must be under /hoody/storage/hoody-daemon/logs. Example: /hoody/storage/hoody-daemon/logs/<name>/stderr.log.
logs_enabledbooleanNoWhether logging is enabled. Default: true.
log_max_bytesintegerNoMaximum size of each log file in bytes before rotation. Default: 5242880 (5MB).
log_backupsintegerNoNumber of rotated backup log files to keep. Default: 2.
ttlintegerNoTime-to-live in seconds. Program auto-stops after this duration.
waitbooleanNoWait for program to reach RUNNING state before returning. Default: false.
timeoutintegerNoTimeout in seconds when wait=true. Default: 30. Clamped to 300.
displaystringNoX11 DISPLAY number for GUI programs. Accepts both "1" and ":1" formats.
terminal_idintegerNoHoody Terminal integration: Session ID (1-65535).
terminal_shellstringNoHoody Terminal integration: shell. One of bash, zsh, fish, sh, tmux.
terminal_interactivebooleanNoHoody Terminal integration: override auto-detection.
Terminal window
curl -X POST "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/quick-start" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"command": "node test-server.js",
"user": "nodejs",
"name": "temp-test-server",
"directory": "/opt/test",
"ttl": 1800,
"environment": {
"PORT": "9999",
"NODE_ENV": "test"
},
"wait": true
}'

Returns all currently tracked ephemeral programs with their current runtime status.

Terminal window
curl -X GET "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/quick-start" \
-H "Authorization: Bearer <token>"

GET /api/v1/daemon/quick-start/{id}/status

Section titled “GET /api/v1/daemon/quick-start/{id}/status”

Retrieves the current runtime status for a specific ephemeral program by its temporary_id.

NameInTypeRequiredDescription
idpathstringYesTemporary ID of the ephemeral program (format: quick_<milliseconds>_<sequence>).
Terminal window
curl -X GET "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/quick-start/quick_1731605123000_0/status" \
-H "Authorization: Bearer <token>"

Retrieves the last N lines from an ephemeral program’s stdout or stderr log file. Default ephemeral log paths are keyed on the program NAME: /hoody/storage/hoody-daemon/logs/<name>/stdout.log.

NameInTypeRequiredDescription
idpathstringYesEphemeral program temporary ID.
typequerystringNoLog stream: stdout or stderr. Default: stdout.
linesqueryintegerNoNumber of lines to return from end of file. Default: 100.
Terminal window
curl -X GET "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/quick-start/quick_1731605123000_0/logs?type=stdout&lines=50" \
-H "Authorization: Bearer <token>"

Stops the ephemeral program and removes its configuration completely. The program cannot be restarted — to run the same command again, create a new ephemeral program.

NameInTypeRequiredDescription
idpathstringYesTemporary ID of the ephemeral program to stop.
Terminal window
curl -X POST "https://{projectId}-{containerId}-daemon-1.{server}.containers.hoody.com/api/v1/daemon/quick-start/quick_1731605123000_0/stop" \
-H "Authorization: Bearer <token>"