Execution API
One-shot Execution
Run a command and get the result.
curl -X POST https://api.nanoterm.dev/api/workspaces/ws_a1b2c3d4/exec \
-H 'Authorization: Bearer nt_xxx' \
-H 'Content-Type: application/json' \
-d '{"command": ["npm", "test"]}'
Request Body:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
command | string[] | yes | — | Command and arguments |
cwd | string | no | /workspace | Working directory inside the workspace. Must be an absolute path; .. segments are rejected. |
Response: 200 OK
{
"stdout": "PASS src/index.test.ts\nTests: 12 passed, 12 total\n",
"stderr": "",
"exitCode": 0
}
For shell pipelines (pipes, redirects, &&), pass ["bash", "-lc", "<one-liner>"] as command — the runtime executes argv directly,
not through a shell.
Interactive Terminal (WebSocket)
Attach a PTY session via WebSocket for interactive use.
ws://api.nanoterm.dev/api/workspaces/ws_a1b2c3d4/terminal
Message Protocol
All messages are JSON-framed. Binary data (stdin/stdout) is base64-encoded.
Client → Server:
// Send keyboard input
{ "type": "stdin", "data": "bHMgLWxhCg==" }
// Resize terminal
{ "type": "resize", "cols": 120, "rows": 40 }
Server → Client:
// Terminal output
{ "type": "stdout", "data": "dG90YWwgMTYK..." }
// Error
{ "type": "error", "message": "Workspace not running" }
note
The data field uses base64 encoding. Decode with atob() in browsers or Buffer.from(data, 'base64') in Node.js.