Connection URL
{instance_id} is the computer’s instance_id, returned by Create computer. It is also the last path segment of the computer’s connection_url.
Authentication
Pass the computer’s password as thetoken query parameter. It is the same password used for VNC. Retrieve it from Get VNC password before connecting. That endpoint takes the computer’s UUID, not its instance_id. You need both identifiers: the UUID to fetch the password, the instance_id to build this URL.
Send the password in ?token=, from a server or a browser. An Authorization header does not work on this socket, whether it carries an API key or the password: orgo-web accepts it, but it is not forwarded to the computer, which authenticates only ?token=. The connection opens and then closes with 1000. An API key in ?token= fails the same way, and from a browser (any connection with an Origin header) it is refused with 4001. Never put an account key in browser code.
A connection with no usable credential is closed with code 4001. See Close codes.
Query parameters
string
required
Computer password, from Get VNC password. Optional only when the request carries a signed-in orgo.ai session cookie, in which case orgo-web supplies the password for you.
number
default:"80"
Terminal width in columns. A missing or unparseable value falls back to 80.
number
default:"24"
Terminal height in rows. A missing or unparseable value falls back to 24.
string
Name of a persistent shell session. Must be 1-32 characters of
A-Z, a-z, 0-9, - or _.With a valid session, the shell survives disconnection: reconnecting with the same name re-attaches to the running session, with any long job still going. Omit it, or send a name that fails validation, and you get an ephemeral shell (bash -l on Linux, PowerShell on Windows) that is killed when the socket closes.Message protocol
Messages are JSON text frames in both directions.Client → server messages
input
input
resize
resize
ping
ping
Ask for a
pong.A text frame that is not valid JSON is written to the PTY verbatim, as raw keystrokes. This keeps older raw-mode clients working. A frame that parses as JSON but carries an unrecognised
type is discarded silently.Server → client messages
output
output
error
error
The shell could not be started.This frame is followed immediately by a normal (
string
Always
"error".string
Human-readable error description.
1000) close, not by an error close code. Watch for it in your message handler. A client that only inspects close codes sees a clean disconnect and never learns why.exit
exit
pong
pong
Response to a
ping.Examples
Integration with xterm.js
For browser-based terminal UIs, use xterm.js:Best practices
Heartbeat
Send a
ping every 30 seconds to detect a dead connection early. Each ping is a message you send, so it also counts as activity for the idle timeout.Reconnection
Reconnect with exponential backoff, starting at 2 seconds. Pair it with a
session name so the shell you reconnect to is the one you left.Resize events
Send a
resize whenever the terminal container changes size, so text wraps correctly.ANSI support
Output contains ANSI escape codes. Use a library like xterm.js that handles them.
The terminal WebSocket gives direct root shell access. To run one command programmatically, use Execute bash instead.
Idle disconnect
An idle terminal is closed with code4008. Traffic in either direction counts as activity, so a long build streaming output keeps the socket open even with nobody typing. Activity is shared per computer and caller, so input you send over a VNC connection to the same computer keeps this one alive too. In production the window is 30 minutes. Reconnect to resume; with a session name your shell is still there.
Close codes
A URL that is not a
/desktops/{instance_id}/ws/... path is refused before the WebSocket opens, so it gets no close code.