# Terminal: Session Management

**Page:** api/terminal/sessions

[Download Raw Markdown](./api/terminal/sessions.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



## Terminal: Session Management

The Terminal Session Management API provides endpoints for listing, creating, inspecting, and destroying terminal sessions, connecting to them via WebSocket, retrieving command history and raw output, and capturing screenshots of the terminal buffer.

---

### `GET` `/api/v1/terminal/sessions`

Returns a JSON array of all active terminal sessions with session metadata and recent command history (best-effort).

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `history_limit` | query | integer | No | Max `command_history` entries to include per session (default: 50, max: 1000) |
| `history_lines` | query | integer | No | Alias of `history_limit` |

#### SDK Usage

```python
sessions = client.terminal.sessions.listIterator(
    history_limit=50,
)
```

#### Response



```json
[
  {
    "id": 1,
    "shell": "bash",
    "cwd": "/home/user",
    "started_at": "2025-01-15T10:30:00Z",
    "command_history": [
      "ls -la",
      "cd projects",
      "git status"
    ]
  },
  {
    "id": 2,
    "shell": "zsh",
    "cwd": "/var/log",
    "started_at": "2025-01-15T11:00:00Z",
    "command_history": [
      "tail -f syslog"
    ]
  }
]
```



---

### `POST` `/api/v1/terminal/create`

Create a new terminal session or return success if it already exists. By default, when a Hoody Display is configured, the endpoint blocks until the display TCP port (`4000 + display_number`) is accepting connections, ensuring the caller can immediately use the display after the response.

#### Request Body

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `terminal_id` | string | No | Terminal session ID (numeric 1-65535). Required unless `ephemeral` is true, in which case it is auto-generated (range 40000-65535). |
| `ephemeral` | boolean | No | Auto-generate terminal ID and enable ephemeral session mode. Ephemeral sessions auto-clean after idle timeout and strip DISPLAY environment. (default: `false`) |
| `display` | string | No | X11 display number (e.g., `"1"` or `":1"`). Sets the `DISPLAY` env var and enables Hoody Display readiness waiting. |
| `shell` | string | No | Shell to use (bash/zsh/fish/sh). Ignored for SSH sessions. |
| `user` | string | No | System user to spawn the shell as. Ignored for SSH sessions. |
| `cwd` | string | No | Working directory for the terminal. Ignored for SSH sessions. |
| `startup_script` | string | No | Path to startup script to run |
| `welcome` | boolean | No | Show welcome message on startup (default: `false`) |
| `debug` | boolean | No | Enable debug output in wrapper script (default: `false`) |
| `desktop` | boolean | No | Enable Hoody Display desktop mode. Provides a full desktop environment instead of seamless individual windows (default: `false`) |
| `desktop_env` | string | No | Desktop environment to launch (implies `desktop=true`). Valid values: `xfce`, `mate` |
| `cols` | integer | No | Terminal columns (default: `80`) |
| `rows` | integer | No | Terminal rows (default: `24`) |
| `wait_until_display` | boolean | No | Whether to wait for Hoody Display readiness (default: `true` when display is configured) |
| `wait_timeout` | integer | No | Timeout in seconds for waiting (default: `300`) |
| `ssh_host` | string | No | SSH hostname/IP. Required together with `ssh_user` for SSH sessions. |
| `ssh_user` | string | No | SSH username. Required together with `ssh_host` for SSH sessions. |
| `ssh_port` | string | No | SSH port (default: `22`) |
| `ssh_password` | string | No | SSH password. Cannot contain shell-dangerous characters. |
| `ssh_key` | string | No | Base64-encoded SSH private key (PEM format) |
| `socks5_host` | string | No | SOCKS5 proxy hostname/IP for routing SSH connections |
| `socks5_port` | string | No | SOCKS5 proxy port (default: `1080`) |
| `socks5_user` | string | No | SOCKS5 proxy authentication username |
| `socks5_pass` | string | No | SOCKS5 proxy authentication password |

```json
{
  "terminal_id": "5",
  "display": "5",
  "shell": "bash",
  "user": "user",
  "cwd": "/home/user",
  "welcome": false,
  "cols": 80,
  "rows": 24
}
```

#### SDK Usage

```python
session = client.terminal.sessions.create(
    data={
        "terminal_id": "5",
        "display": "5",
        "shell": "bash",
        "cwd": "/home/user",
    }
)
```

#### Response



```json
{
  "status": "created",
  "terminal_id": 5,
  "display": ":5",
  "shell": "bash"
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid terminal_id"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MISSING_TERMINAL_ID` | `terminal_id` field is required | `terminal_id` field is required | Contact support |
| `INVALID_TERMINAL_ID` | Terminal ID must be numeric 1-65535 | Terminal ID must be numeric 1-65535 | Contact support |


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Cannot create requested working directory"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `CWD_PERMISSION_DENIED` | Requested working directory could not be created | Choose a writable path or disable `cwd_auto_create` | Choose a writable path or disable `cwd_auto_create` |


```json
{
  "statusCode": 405,
  "error": "Method Not Allowed",
  "message": "method_not_allowed"
}
```


```json
{
  "statusCode": 500,
  "error": "Internal Server Error",
  "message": "Failed to create terminal process"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SPAWN_FAILED` | Failed to create terminal process | Failed to create terminal process | Contact support |



---

### `DELETE` `/api/v1/terminal/{terminal_id}`

Completely destroy and remove a terminal session. This kills any running process, frees all resources, and removes the session from memory. Clients will be disconnected. Use this to cleanly terminate sessions without waiting for idle timeout.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `terminal_id` | path | string | Yes | Terminal session ID to delete (numeric 1-65535) |

#### SDK Usage

```python
result = client.terminal.sessions.delete(terminal_id="5")
```

#### Response



```json
{
  "status": "deleted",
  "terminal_id": 5
}
```


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Terminal session not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SESSION_NOT_FOUND` | Terminal session does not exist | Verify terminal ID | Verify terminal ID |



---

### `GET` `/api/v1/terminal/ws`

Establishes a WebSocket connection for real-time bidirectional terminal I/O. Multiple clients can share the same terminal session using the same `terminal_id`. The protocol uses efficient binary framing where the first byte indicates message type (0-4 for commands, specific bytes for data). Supports session sharing, read-only mode, SSH connections, PID attachment, and comprehensive terminal features.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `terminal_id` | query | string | No | Terminal session ID (numeric 1-65535, auto-generated if not provided) - Multiple clients can share by using same ID |
| `readonly` | query | boolean | No | Enable read-only mode for this client (blocks keyboard input) - Use `'true'`, `'1'`, or no value |
| `cwd` | query | string | No | Working directory for new sessions |
| `cwd_auto_create` | query | boolean | No | Auto-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`) |
| `shell` | query | string | No | Shell to use (bash, zsh, fish, tmux, ssh, etc.) |
| `user` | query | string | No | System user to spawn shell as (requires permissions) |
| `cmd` | query | string | No | Base64-encoded command to auto-execute on spawn |
| `env` | query | string | No | Environment variable `KEY=VALUE` (repeatable) |
| `display` | query | string | No | DISPLAY variable for X11 apps (auto-formats `:N`) |
| `pid` | query | integer | No | Attach to existing process PID for monitoring |
| `ssh_host` | query | string | No | SSH server hostname/IP for remote connections |
| `ssh_user` | query | string | No | SSH username (required if `ssh_host` provided) |
| `ssh_port` | query | string | No | SSH port (default: `22`) |
| `ssh_password` | query | string | No | SSH password (use with caution) |
| `socks5_host` | query | string | No | SOCKS5 proxy for SSH |
| `socks5_port` | query | string | No | SOCKS5 port (default: `1080`) |


This endpoint upgrades the HTTP connection to a WebSocket. Use a WebSocket client (e.g., `websocat`, browser `WebSocket API`, or the SDK) rather than a plain HTTP client.


#### SDK Usage

```python
ws = client.terminal.sessions.connectWebSocket(
    terminal_id="5",
    shell="bash",
    cwd="/home/user",
)
```

#### Response



```json
"Switching Protocols"
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Invalid parameters"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `INVALID_TERMINAL_ID` | Terminal ID must be numeric 1-65535 | Provide valid `terminal_id` | Provide valid `terminal_id` |
| `INVALID_PARAMETERS` | Invalid URL parameters | Check parameter format | Check parameter format |


```json
{
  "statusCode": 403,
  "error": "Forbidden",
  "message": "Access denied"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MAX_CLIENTS_REACHED` | Server at capacity | Try again later | Try again later |
| `ORIGIN_CHECK_FAILED` | Origin validation failed | Connect from allowed origin | Connect from allowed origin |


```json
{
  "statusCode": 503,
  "error": "Service Unavailable",
  "message": "Terminal service unavailable"
}
```



---

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

Retrieve the execution history for a specific terminal session, including all commands executed and their status.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `terminal_id` | path | string | Yes | Terminal session ID (numeric 1-65535, can also be provided as query parameter) |

#### SDK Usage

```python
history = client.terminal.sessions.listHistoryIterator(terminal_id="5")
```

#### Response



```json
{
  "description": "Command history for the terminal session"
}
```


```json
{
  "statusCode": 400,
  "error": "Bad Request",
  "message": "Missing terminal_id"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `MISSING_TERMINAL_ID` | Terminal ID required | Provide `terminal_id` in path or query | Provide `terminal_id` in path or query |


```json
{
  "statusCode": 404,
  "error": "Not Found",
  "message": "Terminal session not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `SESSION_NOT_FOUND` | Terminal session does not exist | Check session ID or create new session | Check session ID or create new session |



---

### `GET` `/api/v1/terminal/raw`

Retrieve the raw terminal output buffer for a terminal session. Supports multiple output formats via the `format` query parameter. Defaults to text/download format if `format` parameter is not provided.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `terminal_id` | query | string | No | Terminal session ID (numeric 1-65535, defaults to `"1"` if not provided) |
| `format` | query | string | No | Output format: `download`, `text`, or `html` (defaults to `"download"` if not provided) |
| `tail` | query | integer | No | Return only the last N lines of output |

#### SDK Usage

```python
output = client.terminal.sessions.getRawOutput(
    terminal_id="5",
    format="text",
    tail=100,
)
```

#### Response



```json
{
  "type": "application/octet-stream",
  "content": "Terminal output buffer as binary text"
}
```


```json
{
  "type": "text/plain",
  "content": "Terminal session not found"
}
```



---

### `GET` `/api/v1/terminal/screenshot`

Convert the terminal's ANSI output buffer to an image with customizable styling. Screenshots are automatically saved to `/hoody/storage/hoody-terminal/screenshots/{terminal_id}/` with timestamp as filename.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `terminal_id` | query | string | Yes | Terminal session ID (numeric 1-65535) |
| `format` | query | string | No | Output format: `png`, `jpeg`, `gif` (default: `png`) |
| `foreground` | query | string | No | Foreground color: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, or RGB `(R,G,B,A)` (default: `white`) |
| `background` | query | string | No | Background color: same as foreground options (default: `black`) |
| `fontsize` | query | integer | No | Font size in pixels (default: `20`) |
| `save` | query | boolean | No | Save to storage directory (default: `true`) |

#### SDK Usage

```python
screenshot = client.terminal.sessions.captureScreenshot(
    terminal_id="5",
    format="png",
    foreground="white",
    background="black",
    fontsize=20,
    save=True,
)
```

#### Response



```json
{
  "type": "image/gif",
  "X-Screenshot-Path": "/hoody/storage/hoody-terminal/screenshots/5/2025-01-15_10-30-45.gif"
}
```


```json
{
  "statusCode": 500,
  "error": "Internal Server Error",
  "message": "Screenshot tool not available"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `TOOL_NOT_AVAILABLE` | Screenshot tool (`textimg`) not installed | Install with: `go install github.com/jiro4989/textimg@latest` | Install with: `go install github.com/jiro4989/textimg@latest` |