Overview
A PTY (pseudo-terminal) session gives you an interactive, line-disciplined shell on a Devbox — the same kind of terminal you would get fromssh. PTY sessions are the right primitive when a program needs to behave as if it is attached to a real terminal: full-screen TUIs (vim, htop, less), interactive REPLs that detect a TTY, anything that responds to window-size changes, and anything that needs to receive signals like SIGINT or SIGWINCH.
A PTY session has two surfaces:
- Control plane (HTTP) — bootstrap or reconnect to a session, resize the terminal, send signals, and close the session. Available through the SDK.
- Data plane (WebSocket) — the interactive byte stream. Raw binary frames in both directions. Connect directly with a WebSocket client.
For non-interactive command execution where you do not need a TTY, prefer Execute Commands or Named Shells. PTY sessions are heavier and are intended for true interactive use.
Connecting to a session
pty.connect looks up a session by session_name and either reconnects to it or creates it. A newly created session starts an interactive bash shell on the Devbox. The response includes connect_url — a server-relative path to the WebSocket data plane.
Session names
session_name is client-chosen — it is an identifier you pick, not an opaque server-issued ID. It must:
- Be 1–256 characters long
- Use only ASCII letters, digits,
-, and_
close, or after a Devbox lifecycle event replaces the PTY process (such as suspend/resume), the next connect with that name starts a fresh shell.
Initial terminal size
You can request an initial terminal size at connect time with thecols and rows query parameters. Both must be present and in the range 1–1000; otherwise they are ignored and the session uses the defaults (80×24).
Streaming terminal I/O
The interactive terminal stream is exchanged over a WebSocket at the path returned inconnect_url. The protocol is intentionally simple:
- Frames are raw binary in both directions.
- Bytes the client sends are written to the PTY master (keystrokes, paste, control characters).
- Bytes the server sends are bytes the shell wrote (stdout/stderr from the PTY slave side).
websockets library; the same pattern applies in any language.
Single-attach contract
Only one WebSocket client may be attached to a session at a time. A second concurrent attach is rejected at WebSocket upgrade time with HTTP 400. Theconnect control call itself always succeeds for a valid session_name, even if another client is currently attached — single-attach is enforced when you actually open the WebSocket.
Close codes
When the server closes the WebSocket it uses application-defined close codes so the client can distinguish reasons:
Browsers automatically respond to WebSocket pings and will not normally trip
4001. If you are writing a non-browser client, make sure your WebSocket library handles ping frames or sends periodic traffic.
Disconnect does not terminate the session
Closing the WebSocket does not terminate the PTY session. The session is retained foridle_ttl_seconds, so a later pty.connect using the same session_name resumes the same shell with its environment, working directory, and running processes intact. After the TTL expires the next connect creates a fresh shell.
Controlling a session
The control endpoint applies operations to an existing session. It accepts anaction field plus the parameters that action requires.
Resize
Tell the PTY about a new terminal size. Bothcols and rows are required and must each be in the range 1–1000. The new winsize is applied to the PTY master and the kernel delivers SIGWINCH to the foreground process group, so programs like vim redraw correctly.
Signal
Deliver a POSIX signal to the slave’s foreground process group viakillpg(2). Pass the signal name as a string — for example SIGINT, SIGTERM, SIGHUP, SIGUSR1. Unknown names return 400. If the shell has already exited and there is no foreground process group, the call returns 400.
Close
Terminate the session. SendsSIGHUP to the foreground process group (best-effort; ignored if the shell has already exited) and drops the session from the server’s session cache. A later pty.connect with the same session_name will create a fresh PTY session.
When to use PTY sessions
Use a PTY session when:- A program detects whether stdin/stdout is a TTY and behaves differently when it is (
python -i,node, many language REPLs). - You want to drive a full-screen TUI (
vim,nano,htop,less,k9s). - You need real signal semantics —
Ctrl-Cinterrupting the foreground process group,SIGWINCHon resize. - You are building an in-browser terminal or any human-facing shell.
