Skip to content
Hoody.com

Use these endpoints to list, inspect, attach to, capture, and tear down terminal sessions running inside a Hoody container. The endpoints in this section reach the terminal service through the container-scoped subdomain of the Hoody platform, not the control plane at api.hoody.com. Each session can be inspected through its command history and raw output buffer, driven through a real-time WebSocket, snapshotted as an image, or created and deleted on demand.

All endpoints in this section target https://{projectId}-{containerId}-terminal-1.{server}.containers.hoody.com. Replace {projectId}, {containerId}, and {server} with the identifiers of your container and the Hoody node it runs on. Every request requires an authenticated session token.

Return every terminal session known to the terminal service, including the session’s metadata, recent command history, and the daemon-program metadata when the terminal id is claimed by a hoody-daemon program. Daemon-program terminals have daemon_program: true with a populated daemon object describing the program, no shell, and no command history. Local sessions carry daemon_program: false.

NameInTypeRequiredDescription
history_limitqueryintegerNoMax command_history entries to include per session (default: 50, max: 1000)
history_linesqueryintegerNoAlias of history_limit
[
{
"id": "123",
"terminal_id": "123",
"pid": 5678,
"shell_pid": 5678,
"created_at": 1698765432,
"shell": "bash",
"is_active": true,
"cols": 120,
"rows": 40,
"daemon_program": false,
"daemon": null,
"is_ephemeral": false,
"desktop_mode": true,
"is_ssh": false,
"client_count": 1,
"last_activity": 1698765440,
"display_id": 7,
"cwd": "/home/user",
"initial_cwd": "/home/user",
"ssh_host": null,
"ssh_user": null,
"ssh_port": null,
"dbus_address": "unix:path=/tmp/dbus-abc,guid=deadbeef",
"command_history": [
[1698765432000, "ls -la"],
[1698765440000, "pwd"]
]
},
{
"id": "5000",
"terminal_id": "5000",
"pid": 4321,
"shell_pid": null,
"created_at": 1698765500,
"shell": null,
"is_active": true,
"cols": 100,
"rows": 30,
"daemon_program": true,
"daemon": {
"program_id": 12,
"program_name": "console",
"user": "root",
"enabled": true,
"running": true,
"connected": true,
"ended": false
},
"is_ephemeral": false,
"desktop_mode": false,
"is_ssh": false,
"client_count": 2,
"last_activity": 1698765510,
"display_id": null,
"cwd": "/opt/console",
"initial_cwd": null,
"ssh_host": null,
"ssh_user": null,
"ssh_port": null,
"dbus_address": null,
"command_history": []
},
{
"id": "5001",
"terminal_id": "5001",
"pid": 0,
"shell_pid": null,
"created_at": null,
"shell": null,
"is_active": false,
"cols": null,
"rows": null,
"daemon_program": true,
"daemon": {
"program_id": 13,
"program_name": "worker",
"user": "app",
"enabled": true,
"running": true,
"connected": false,
"ended": false
},
"is_ephemeral": false,
"desktop_mode": false,
"is_ssh": false,
"client_count": 0,
"last_activity": null,
"display_id": null,
"cwd": null,
"initial_cwd": null,
"ssh_host": null,
"ssh_user": null,
"ssh_port": null,
"dbus_address": null,
"command_history": []
}
]
Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-example-1.containers.hoody.com/api/v1/terminal/sessions" \
-H "Authorization: Bearer $HOODY_TOKEN"

GET /api/v1/terminal/history/{terminal_id}

Section titled “GET /api/v1/terminal/history/{terminal_id}”

Retrieve the execution history for a single terminal session, including every command run in that session and its status.

NameInTypeRequiredDescription
terminal_idpathstringYesTerminal session ID (numeric 1-65535, can also be provided as query parameter). The containers proxy injects only the query form on hostname-routed calls, so this path segment must always be supplied explicitly, and it must name the host’s terminal.
{
"terminal_id": "1",
"command_count": 2,
"commands": [
{
"command_id": "45678",
"command": "echo hello",
"status": "completed",
"start_time": 1758805971,
"exit_code": 0,
"timed_out": false
}
]
}
Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-example-1.containers.hoody.com/api/v1/terminal/history/1" \
-H "Authorization: Bearer $HOODY_TOKEN"

Retrieve the raw terminal output buffer for a session. The response supports multiple formats via the format query parameter and defaults to a downloadable text file when no format is supplied.

NameInTypeRequiredDescription
terminal_idquerystringNoTerminal session ID (numeric 1-65535, defaults to "1" if not provided). On calls routed through a terminal-N containers-proxy hostname, the proxy sets this from the hostname label and overwrites any value you send.
formatquerystringNoOutput format: download, text, or html (defaults to "download" if not provided).
tailqueryintegerNoReturn only the last N lines of output.

The response body is the raw terminal output as a downloadable file (application/octet-stream). Clients receive the bytes of the output buffer; on format=html the body is an HTML rendering of the buffer.

Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-example-1.containers.hoody.com/api/v1/terminal/raw?terminal_id=1&format=text" \
-H "Authorization: Bearer $HOODY_TOKEN"

Establish a WebSocket connection for real-time bidirectional terminal I/O. Multiple clients can share the same session by using the same terminal_id; a client that omits terminal_id joins the shared terminal 1 unless it asks for ephemeral=true. The protocol uses binary framing where the first byte indicates message type. After the upgrade the client must request the tty subprotocol, then send the JSON_DATA handshake frame (a JSON object starting with {, carrying columns and rows). The server spawns the session’s process only once that frame arrives, so a client that never sends it gets no shell.

NameInTypeRequiredDescription
terminal_idquerystringNoTerminal session ID (numeric 1-65535). Omitted, the connection joins the shared terminal 1 that every client without a terminal_id uses; with ephemeral=true it instead gets a fresh id in 40000-65535, reported in the SET_TERMINAL_ID frame. A value that is present but malformed is refused, never mapped to 1. Multiple clients can share by using the same id. On connections routed through a terminal-N containers-proxy hostname, the proxy sets this from the hostname label and overwrites any value you send.
readonlyquerybooleanNoEnable read-only mode for this client (blocks keyboard input). Use true, 1, or no value.
cwdquerystringNoWorking directory for new sessions.
cwd_auto_createquerybooleanNoAuto-create cwd when the requested working directory does not exist yet. Only applies when cwd is explicitly provided for a new local session. Enable with true, 1, or no value (default: false).
shellquerystringNoShell to use (bash, zsh, fish, tmux, ssh, etc.).
userquerystringNoSystem user to spawn shell as (requires permissions).
cmdquerystringNoBase64-encoded command to auto-execute on spawn.
envquerystringNoEnvironment variable KEY=VALUE (repeatable).
displayquerystringNoDISPLAY variable for X11 apps (auto-formats :N).
pidqueryintegerNoAttach to existing process PID for monitoring.
ssh_hostquerystringNoSSH server hostname/IP for remote connections.
ssh_userquerystringNoSSH username (required if ssh_host provided).
ssh_portquerystringNoSSH port (default: 22).
ssh_passwordquerystringNoSSH password (use with caution).
socks5_hostquerystringNoSOCKS5 proxy for SSH.
socks5_portquerystringNoSOCKS5 port (default: 1080).
socks5_userquerystringNoSOCKS5 proxy username (alphanumeric with _-. characters).
socks5_passquerystringNoSOCKS5 proxy password (shell-dangerous characters are refused).
ssh_keyquerystringNoBase64-encoded SSH private key for key authentication (alternative to ssh_password).
display_idquerystringNoAlias of display; when both are sent, display wins.
ephemeralquerybooleanNoThrowaway session: without a terminal_id a fresh id in 40000-65535 is allocated instead of joining shared terminal 1; the display environment is not inherited, a cmd= command exits the shell when it finishes, and the idle session is cleaned up. Accepts true, 1, or yes (default: false). Ignored with agent=true.
resetquerybooleanNoTear down the session’s running process (or SSH / PID attachment) and start a fresh one before this client joins. Accepts true, 1, or a bare flag (default: false).
startup_scriptquerystringNoAbsolute path of a script to run before the shell starts; relative paths and paths containing .. are ignored. Ignored with agent=true.
env_injectquerybooleanNoInject the HOODY_* environment variables into the spawned shell (default: true; only false or 0 disables it).
desktopquerybooleanNoDesktop mode: sets TTYD_DESKTOP_MODE=true in the shell environment (default: false). Ignored with agent=true.
desktop_envquerystringNoDesktop environment for desktop mode; implies desktop=true. Allowed values: xfce, mate. Other values are ignored. Not started again when a window manager already runs on the display; it keeps running after the session is deleted (POST /api/v1/system/displays/{display}/stop ends it).
debugquerybooleanNoSets TTYD_DEBUG=true in the shell environment (default: false).
welcomequerybooleanNoShow the Hoody welcome banner when the shell starts (default: false).
agentquerybooleanNoLaunch the server-configured Hoody Agent TUI instead of a shell. A locked-down mode: shell, cmd, user, ssh_*, pid, startup_script, desktop, and ephemeral are ignored (default: false).
onboardingquerybooleanNoWith agent=true, start the agent’s first-run onboarding (default: false).
argquerystringNoCommand-line argument for the shell, repeatable and kept in order. Accepted only when URL arguments are enabled on this server; ignored otherwise.
Switching Protocols

The WebSocket upgrade succeeded. The body content type is text/plain and carries the literal Switching Protocols text shown above.

Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-example-1.containers.hoody.com/api/v1/terminal/ws?terminal_id=1&shell=bash" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Upgrade: websocket" \
-H "Connection: Upgrade" \
-H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
-H "Sec-WebSocket-Version: 13" \
-H "Sec-WebSocket-Protocol: tty"

Render the terminal’s ANSI output buffer to an image. Screenshots are automatically saved to /hoody/storage/hoody-terminal/screenshots/{terminal_id}/ with a timestamp as the filename. The save query parameter controls whether the image is also persisted to that directory.

NameInTypeRequiredDescription
terminal_idquerystringYesTerminal session ID (numeric 1-65535). On calls routed through a terminal-N containers-proxy hostname, the proxy sets this from the hostname label and overwrites any value you send, so pick the terminal via the hostname and supply this directly only when calling the terminal service without the proxy.
formatquerystringNoOutput format: png, jpeg, gif (default: png).
foregroundquerystringNoForeground color: black, red, green, yellow, blue, magenta, cyan, white, or RGB R,G,B,A (default: white).
backgroundquerystringNoBackground color: same as foreground options (default: black).
fontsizequeryintegerNoFont size in pixels (default: 20).
savequerybooleanNoSave to storage directory (default: true).

The response body is the rendered screenshot image (image/gif). The response also carries an X-Screenshot-Path header pointing to the saved file when persistence is enabled.

Terminal window
curl "https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-example-1.containers.hoody.com/api/v1/terminal/screenshot?terminal_id=1&format=png&fontsize=18" \
-H "Authorization: Bearer $HOODY_TOKEN" \
--output screenshot.png

Create a new terminal session, or return success if a session with the same terminal_id already exists (the running session keeps its original configuration). A running ephemeral session is not returned for a request that does not ask for one; that response is a 409 EPHEMERAL_SESSION. When a Hoody Display is configured, the endpoint blocks until the display server is accepting connections by default, so the caller can immediately use the display after the response.

This endpoint takes no URL parameters.

NameTypeRequiredDescription
terminal_idstringNoTerminal session ID (numeric 1-65535). Required unless ephemeral is true, in which case it is auto-generated (range 40000-65535). On a terminal-N host, the proxy sets the query terminal_id to N; a body terminal_id that differs from it is refused with 400 TERMINAL_ID_MISMATCH.
ephemeralbooleanNoAuto-generate terminal ID and enable ephemeral session mode. Ephemeral sessions auto-clean after idle timeout and strip DISPLAY environment (default: false).
displaystringNoX11 display number (for example "1" or ":1"). Sets the DISPLAY env var and enables Hoody Display readiness waiting. The display is started if it is not running and reused if it is; it keeps running after the session is deleted (stop it with POST /api/v1/system/displays/{display}/stop).
shellstringNoShell to use (bash, zsh, fish, sh). Ignored for SSH sessions.
userstringNoSystem user to spawn the shell as. Ignored for SSH sessions.
cwdstringNoWorking directory for the terminal. Ignored for SSH sessions.
startup_scriptstringNoPath to startup script to run.
welcomebooleanNoShow welcome message on startup (default: false).
debugbooleanNoEnable debug output in wrapper script (default: false).
desktopbooleanNoEnable Hoody Display desktop mode. Provides a full desktop environment instead of seamless individual windows (default: false).
desktop_envstringNoDesktop environment to launch (implies desktop=true). Valid values: xfce, mate. Not started again when a window manager already runs on the display. It belongs to the display and keeps running after the session is deleted.
colsintegerNoTerminal columns (default: 80).
rowsintegerNoTerminal rows (default: 24).
wait_until_displaybooleanNoWhether to wait for Hoody Display readiness (default: true when display is configured).
wait_timeoutintegerNoTimeout in seconds for waiting (default: 300).
ssh_hoststringNoSSH hostname/IP. Required together with ssh_user for SSH sessions.
ssh_userstringNoSSH username. Required together with ssh_host for SSH sessions.
ssh_portstringNoSSH port (default: 22).
ssh_passwordstringNoSSH password. Cannot contain shell-dangerous characters.
ssh_keystringNoBase64-encoded SSH private key (PEM format).
socks5_hoststringNoSOCKS5 proxy hostname/IP for routing SSH connections.
socks5_portstringNoSOCKS5 proxy port (default: 1080).
socks5_userstringNoSOCKS5 proxy authentication username.
socks5_passstringNoSOCKS5 proxy authentication password.
{
"status": "ok",
"terminal_id": "1",
"pid": 12345,
"display_ready": true,
"message": "Terminal session created"
}
Terminal window
curl -X POST "https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-example-1.containers.hoody.com/api/v1/terminal/create" \
-H "Authorization: Bearer $HOODY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"terminal_id": "1",
"shell": "bash",
"cwd": "/home/user",
"cols": 120,
"rows": 40
}'

Completely destroy and remove a terminal session. The call kills the session’s processes, frees its resources, and removes the session from memory. Attached WebSocket clients are closed with code 4410 and reason session deleted, a code the SDK and the web client do not reconnect on by themselves; an attach creates the session it names, so a reconnect would start a fresh shell under the deleted id. A display the session started (its display and any desktop environment) is not part of the session and keeps running. Stop it with POST /api/v1/system/displays/{display}/stop.

NameInTypeRequiredDescription
terminal_idpathstringYesTerminal session ID to delete (numeric 1-65535). The containers proxy cannot fill this path segment, so supply it explicitly even on hostname-routed calls, and it must name the host’s terminal.
{
"message": "Terminal session deleted",
"terminal_id": "1"
}
Terminal window
curl -X DELETE "https://67e89abc123def456789abcd-890abcdef12345678901cdef-terminal-1.node-example-1.containers.hoody.com/api/v1/terminal/1" \
-H "Authorization: Bearer $HOODY_TOKEN"