Skip to main content
Connect to an interactive terminal session on a computer via WebSocket. This provides a full PTY (pseudo-terminal) interface, enabling real-time bidirectional communication with the computer’s shell.

Connection URL

wss://{computer_id}.orgo.dev/terminal

Query Parameters

cols
number
default:"80"
Number of columns for the terminal.
rows
number
default:"24"
Number of rows for the terminal.

Message Protocol

All messages are JSON-encoded. The WebSocket uses a simple request/response protocol with the following message types.

Client → Server Messages

Send keyboard input to the terminal.
{
  "type": "input",
  "data": "ls -la\r"
}
type
string
required
Must be "input".
data
string
required
The input string to send. Use \r for Enter key.
Resize the terminal dimensions.
{
  "type": "resize",
  "cols": 120,
  "rows": 40
}
type
string
required
Must be "resize".
cols
number
required
New number of columns.
rows
number
required
New number of rows.
Send a heartbeat ping to keep the connection alive.
{
  "type": "ping"
}

Server → Client Messages

Terminal output data.
{
  "type": "output",
  "data": "user@computer:~$ "
}
type
string
Always "output".
data
string
The terminal output. May contain ANSI escape codes for colors and formatting.
Error message from the server.
{
  "type": "error",
  "message": "Connection failed"
}
type
string
Always "error".
message
string
Human-readable error description.
The shell process has exited.
{
  "type": "exit",
  "code": 0
}
type
string
Always "exit".
code
number
Exit code of the shell process.
Response to a ping message.
{
  "type": "pong"
}

Examples

const computerId = 'orgo-a3bb189e-8bf9-3888-9912-ace4e6543002';
const ws = new WebSocket(`wss://${computerId}.orgo.dev/terminal?cols=80&rows=24`);

ws.onopen = () => {
  console.log('Connected to terminal');
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);

  switch (message.type) {
    case 'output':
      // Append to your terminal display
      terminal.write(message.data);
      break;
    case 'error':
      console.error('Terminal error:', message.message);
      break;
    case 'exit':
      console.log('Shell exited with code:', message.code);
      break;
  }
};

// Send a command
function sendCommand(command) {
  ws.send(JSON.stringify({
    type: 'input',
    data: command + '\r'  // \r for Enter key
  }));
}

// Resize terminal
function resizeTerminal(cols, rows) {
  ws.send(JSON.stringify({
    type: 'resize',
    cols,
    rows
  }));
}

// Example: Run a command
sendCommand('echo "Hello, World!"');

Integration with xterm.js

For browser-based terminal UIs, we recommend using xterm.js:
import { Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import '@xterm/xterm/css/xterm.css';

// Initialize xterm.js
const terminal = new Terminal({
  cursorBlink: true,
  fontFamily: 'monospace',
  fontSize: 14,
});

const fitAddon = new FitAddon();
terminal.loadAddon(fitAddon);
terminal.open(document.getElementById('terminal'));
fitAddon.fit();

// Connect to Orgo terminal
const computerId = 'orgo-a3bb189e-8bf9-3888-9912-ace4e6543002';
const ws = new WebSocket(
  `wss://${computerId}.orgo.dev/terminal?cols=${terminal.cols}&rows=${terminal.rows}`
);

// Handle output from server
ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  if (message.type === 'output') {
    terminal.write(message.data);
  }
};

// Send user input to server
terminal.onData((data) => {
  ws.send(JSON.stringify({ type: 'input', data }));
});

// Handle terminal resize
window.addEventListener('resize', () => {
  fitAddon.fit();
  ws.send(JSON.stringify({
    type: 'resize',
    cols: terminal.cols,
    rows: terminal.rows
  }));
});

Best Practices

Heartbeat

Send periodic ping messages (every 30 seconds) to keep the connection alive and detect disconnections early.

Reconnection

Implement automatic reconnection with exponential backoff. Start with 2 seconds and increase up to 30 seconds.

Resize Events

Send resize messages whenever the terminal container size changes to ensure proper text wrapping.

ANSI Support

The terminal output may contain ANSI escape codes. Use a library like xterm.js that handles these automatically.
The terminal WebSocket provides direct shell access. For running individual commands programmatically, consider using the Execute Bash endpoint instead.