Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.tensorlake.ai/llms.txt

Use this file to discover all available pages before exploring further.

There are two ways to drive an interactive shell inside a sandbox:
  • SSH — connect with ssh, scp, sftp, rsync, VS Code Remote-SSH, JetBrains Gateway, and any other tool that speaks SSH. Use this when you want a normal terminal, file transfer, or port forwarding.
  • PTY sessions — create a PTY over HTTPS, attach to it over a WebSocket, and drive terminal I/O programmatically. Use this when you’re building a UI or browser app that needs a shell, when you need WebSocket-only access, or when you want a session you can disconnect and reattach by token.

SSH

The Tensorlake sandbox proxy exposes a standard SSH endpoint at sandbox.tensorlake.ai. The username is the sandbox id (or name); your laptop’s SSH key, registered once with your Tensorlake account, authenticates the connection.

One-time setup

tl login                                          # if you aren't already logged in
tl ssh-keys add --name laptop ~/.ssh/id_ed25519.pub
tl ssh-keys ls
The key is associated with your user across every project you’re a member of — there’s no per-sandbox or per-project re-registration.

Connect

ssh <sandbox-id>@sandbox.tensorlake.ai
You land in /home/tl-user as the tl-user POSIX account, which is in the sudo group. The sandbox’s hostname inside the session is tl-sbx. To target a specific port (default is the SSH server on 22), prefix the username with the port:
ssh 8080-<sandbox-id>@sandbox.tensorlake.ai

File transfer

scp, sftp, and rsync ride the same connection:
# Push a file in
scp ./script.py <sandbox-id>@sandbox.tensorlake.ai:/workspace/

# Pull a directory out
scp -r <sandbox-id>@sandbox.tensorlake.ai:/workspace/results ./

# Interactive sftp browser
sftp <sandbox-id>@sandbox.tensorlake.ai

# Mirror with rsync
rsync -avz ./src/ <sandbox-id>@sandbox.tensorlake.ai:/workspace/src/

Port forwarding

All four standard forwarding modes are supported — TCP and UNIX-socket, each direction. Local forward (-L) — reach a service running inside the sandbox from your laptop:
# Web server on :8000 inside the sandbox → localhost:8888 on your laptop
ssh -L 8888:localhost:8000 <sandbox-id>@sandbox.tensorlake.ai
Dynamic SOCKS (-D) — route arbitrary traffic through the sandbox’s network namespace:
ssh -D 1080 -N -f <sandbox-id>@sandbox.tensorlake.ai
curl --socks5 localhost:1080 https://example.com
Remote forward (-R) — let processes inside the sandbox reach a service running on your laptop:
# Service on your laptop's :9000 → reachable from inside the sandbox at localhost:9000
ssh -R 9000:localhost:9000 <sandbox-id>@sandbox.tensorlake.ai
UNIX-socket forwards — same shapes with socket paths instead of ports:
ssh -L /tmp/local.sock:/tmp/remote.sock <sandbox-id>@sandbox.tensorlake.ai
ssh -R /tmp/remote.sock:/tmp/local.sock <sandbox-id>@sandbox.tensorlake.ai

VS Code Remote-SSH

Add an entry to ~/.ssh/config:
Host my-sandbox
  HostName sandbox.tensorlake.ai
  User <sandbox-id>
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
Then run Remote-SSH: Connect to Host… in VS Code and pick my-sandbox. VS Code installs its server inside the sandbox automatically. JetBrains Gateway, Cursor, and any other Remote-SSH client work the same way.

Persistent shells

tmux and screen work normally inside the sandbox — useful if you want a session that survives an ssh disconnect:
ssh <sandbox-id>@sandbox.tensorlake.ai
tmux new -s work
# … run things …
# detach with Ctrl-b d, exit ssh, reconnect later, then:
ssh <sandbox-id>@sandbox.tensorlake.ai
tmux attach -t work

Troubleshooting

When auth fails, the proxy disconnects with one of three specific messages. Key not registered.
your SSH public key is not registered with Tensorlake. Run `tl login` and `tl ssh-keys add ~/.ssh/id_ed25519.pub`.
The offered key isn’t on your Tensorlake account. Run tl ssh-keys add ~/.ssh/id_ed25519.pub. Sandbox not in any of your projects.
sandbox <id> is not present in any of your projects (verify the id with `tl sbx ls -r`).
Either a typo in the id, or the sandbox lives in a project you’re not a member of. Run tl sbx ls -r to see running sandboxes in your active project. Sandbox is not running.
sandbox <id> is currently <status> — resume it (`tl sbx resume <id>`) or create a new one.
The sandbox exists in your project but isn’t running. For named sandboxes, tl sbx resume <id>; otherwise create a fresh one. If your client offers multiple keys and one is unregistered, you’ll see the static banner followed by Permission denied (publickey). because OpenSSH iterates through them. Constrain it to the registered key:
Host *.tensorlake.ai
  IdentitiesOnly yes
  IdentityFile ~/.ssh/id_ed25519

CLI shortcut

If you don’t need standard ssh semantics — e.g. you just want a quick shell without setting up keys — tl sbx ssh opens an interactive PTY using the WebSocket flow described below:
tl sbx ssh my-sandbox
tl sbx ssh my-sandbox --shell /bin/sh
tl sbx ssh requires an interactive terminal and doesn’t support port forwarding or file transfer — use ssh, scp, etc. for that.

PTY sessions

Use PTY sessions when you need to drive an interactive shell programmatically — for example a browser-based terminal UI, a recorder, or a remote-control tool — without a real SSH client. The session is created over HTTPS and terminal I/O moves over a WebSocket.
The PTY management endpoints live on the sandbox proxy host, not https://api.tensorlake.ai:https://<sandbox-id-or-name>.sandbox.tensorlake.aiCreate, list, get, resize, and kill requests require Authorization: Bearer $TENSORLAKE_API_KEY. The WebSocket attach step also requires the per-session PTY token returned from session creation.

Happy Path

  1. Call createPty() or create_pty() on a connected sandbox client.
  2. Tensorlake creates the PTY session, opens the WebSocket, and sends the initial READY frame for you.
  3. Use the returned handle to send input, resize the terminal, stream output, wait for exit, disconnect, reconnect, or kill the session.
  4. If you need to reattach later, call connectPty() or connect_pty() with the original sessionId and token.

High-Level SDK API

The connected sandbox client now exposes a high-level PTY handle instead of making you manage WebSocket framing yourself. The handle exposes:
  • sendInput() / send_input() to write terminal input
  • resize() to change rows and columns
  • wait() to block until the PTY exits and get the exit code
  • disconnect() to close the current WebSocket without killing the PTY
  • connect() to reattach the same handle later
  • kill() to terminate the PTY session over HTTP
  • onData() / on_data() and onExit() / on_exit() to subscribe to output and exit events
Use tl sbx ssh when you want an interactive terminal immediately and do not need to manage PTY sessions programmatically:
tl sbx ssh my-sandbox
tl sbx ssh my-sandbox --shell /bin/sh
tl sbx ssh uses the PTY API under the hood and requires an interactive terminal. For reconnectable sessions or application-managed PTY control, use the Python or TypeScript SDK.
createPty() / create_pty() already open the WebSocket and send READY. Use connectPty() / connect_pty() only when you are reattaching to an existing session.

Disconnect or kill

disconnect() closes the WebSocket but leaves the PTY running, so you can reattach later with connectPty() / connect_pty(). kill() terminates the session over HTTP.
# Detach without killing the shell — reconnect later with sandbox_client.connect_pty(...)
pty.disconnect()

# Terminate the session immediately
pty.kill()

Raw HTTP and WebSocket Flow

The raw protocol is small enough that you can drive it yourself from any HTTP client plus any WebSocket client. These calls assume you already have a running sandbox ID or sandbox name.

1. Create the PTY session

curl -sS -X POST https://<sandbox-id>.sandbox.tensorlake.ai/api/v1/pty \
  -H "Authorization: Bearer $TENSORLAKE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "command": "/bin/bash",
    "args": ["-l"],
    "env": {"TERM": "xterm-256color"},
    "working_dir": "/workspace",
    "rows": 24,
    "cols": 80
  }'
Response:
{
  "session_id": "LYtJOrxE9Kz3bphPUDzuX",
  "token": "<pty-session-token>"
}

2. Attach the WebSocket

Open this URL:
wss://<sandbox-id>.sandbox.tensorlake.ai/api/v1/pty/<session-id>/ws
Send the PTY token on the upgrade request:
X-PTY-Token: <pty-session-token>
If your client cannot set headers, append ?token=<pty-session-token> to the WebSocket URL instead.

3. Exchange PTY frames

DirectionBytesMeaning
Client -> server02READY: flush any buffered output
Client -> server00 + UTF-8 bytesSend terminal input
Client -> server01 + cols + rowsResize terminal, with cols then rows as big-endian u16
Server -> client00 + raw bytesTerminal output
Server -> client03 + 4-byte big-endian signed intProcess exit code
Common examples:
ActionBytes
Send READY02
Run pwd\n00 70 77 64 0a
Run exit\n00 65 78 69 74 0a
Exit code 003 00 00 00 00
Resize to 120x4001 00 78 00 28

4. Close or abort

To close cleanly, write exit\n to the shell and wait for the 0x03 exit frame followed by the normal WebSocket close. To terminate the session immediately:
curl -X DELETE https://<sandbox-id>.sandbox.tensorlake.ai/api/v1/pty/<session-id> \
  -H "Authorization: Bearer $TENSORLAKE_API_KEY"

Notes

  • createPty() / create_pty() send READY for you immediately after the socket opens.
  • Closing the WebSocket does not kill the PTY session. You can reconnect while the shell is still running.
  • Persist the original PTY token if you plan to reconnect. Get PTY Session and List PTY Sessions do not return it again.
  • PTY sessions with no connected clients are killed after 300 seconds of inactivity.
  • You can resize either with the 0x01 WebSocket frame or with Resize PTY Session.
  • For the endpoint-by-endpoint API reference, see PTY Sessions API.

Commands

Run one-shot commands without an interactive shell.

Processes

Long-running background processes managed by the sandbox daemon.

Local Tunnels

Forward arbitrary TCP ports (Postgres, VNC, custom binary protocols) over an authenticated WebSocket.

Lifecycle

How long a sandbox lives, and what happens on suspend, resume, and terminate.