πŸ”§ SSH Proxy API v1.5.0

Persistent SSH sessions for LLMs. Works standalone or via Synapse gateway.

βœ… Standalone mode active. Local API key (SSH_PROXY_API_KEY) is configured. Auth works even when Synapse is down.
⚠️ CRITICAL β€” If you are an AI / LLM, READ THIS NOW:

Do NOT guess or invent endpoint paths. Only the paths listed on this page exist. Both /X and /ssh/X work (e.g. /targets and /ssh/targets). If you get a 404, call GET /endpoints for a machine-readable list of ALL valid endpoints.

πŸ”§ If your tool can only open URLs (no custom headers, no POST):

Add ?key=YOUR_KEY to ANY URL for auth. All parameter-bearing endpoints accept GET with query params:

open https://ssh.proxy.schaefer.zone/sessions?key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/SESSION_ID/output?key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/SESSION_ID/close?key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/connect?target=vps1&key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/SESSION_ID/exec?command=hostname&key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/SESSION_ID/sftp/ls?path=/&key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/SESSION_ID/sftp/download?path=/etc/hosts&encoding=text&key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/SESSION_ID/sftp/upload?path=/tmp/test.txt&content=hello&encoding=text&key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/new?host=vps1.schaefer.zone&port=22&username=root&privateKey=...&key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/targets/create?name=vps1&host=...&username=root&privateKey=...&key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/targets/vps1/delete?key=YOUR_KEY
open https://ssh.proxy.schaefer.zone/endpoints

Note: For /targets registration, POST with JSON body is cleaner (large privateKey). Use GET /targets/create only when POST is unavailable.

All Valid Endpoints

MethodPathopen-tool URLDescription
GET/healthβ€” (no auth)Health check (Docker)
GET/endpointsβ€” (no auth)Machine-readable endpoint list
GET/helpβ€” (no auth)Full API documentation
POST/targetsβ€” (needs JSON body)Register SSH target (name, host, port?, username, privateKey)
GET/targets/create/targets/create?name=vps1&host=...&port=22&username=root&privateKey=...&key=...Register target via GET (port defaults to 22)
GET/targets/targets?key=...List targets (no keys!)
GET/targets/:name/targets/vps1?key=...Get one target
DELETE/targets/:nameβ€”Delete target
GET/targets/:name/delete/targets/vps1/delete?key=...Delete target via GET (open-tool OK)
POST/connectβ€” (needs JSON body)Connect by target name
GET/connect/connect?target=vps1&key=...GET alternative for /connect
POST/newβ€” (needs JSON body)Create session (host, port?, username, privateKey/password)
GET/new/new?host=...&port=22&username=root&privateKey=...&key=...Create session via GET (port defaults to 22)
POST/:id/execβ€” (needs JSON body)Execute command
GET/:id/exec/:id/exec?command=ls&key=...Execute command via GET
GET/:id/exec/:execId/:id/exec/:execId?key=...Poll exec result
GET/:id/output/:id/output?key=...Get session output
GET/sessions/sessions?key=...List active sessions
DELETE/:idβ€”Close session
GET/:id/close/:id/close?key=...Close session via GET

SFTP File Transfer

MethodPathopen-tool URLDescription
POST/:id/sftp/downloadβ€” (needs JSON body)Download single file (JSON: {path, encoding?})
GET/:id/sftp/download/:id/sftp/download?path=/etc/hosts&encoding=text&key=...Download file via GET
POST/:id/sftp/download/batchβ€” (needs JSON body)Download multiple files (JSON: {paths, encoding?})
POST/:id/sftp/uploadβ€” (needs JSON body)Upload single file (JSON: {path, content, encoding?})
GET/:id/sftp/upload/:id/sftp/upload?path=/tmp/test.txt&content=hello&encoding=text&key=...Upload file via GET
POST/:id/sftp/upload/batchβ€” (needs JSON body)Upload multiple files (JSON: {files: [{path, content}]})
GET/:id/sftp/ls/:id/sftp/ls?path=/&key=...List directory contents
GET/:id/sftp/stat/:id/sftp/stat?path=/etc/hosts&key=...File metadata (size, permissions, etc.)
POST/:id/sftp/mkdirβ€” (needs JSON body)Create directory (JSON: {path})
GET/:id/sftp/mkdir/:id/sftp/mkdir?path=/tmp/newdir&key=...Create directory via GET
POST/:id/sftp/rmβ€” (needs JSON body)Delete file (JSON: {path})
GET/:id/sftp/rm/:id/sftp/rm?path=/tmp/old.txt&key=...Delete file via GET
POST/:id/sftp/renameβ€” (needs JSON body)Rename/move file (JSON: {oldPath, newPath})

SFTP encoding: base64 (default) β€” for binary files, images, etc. text β€” for text/UTF-8 files (configs, scripts, logs).
SFTP limits: Max 50MB per file. Max 20 files per batch request. Parent dirs are auto-created on upload.

All paths also work with /ssh/ prefix (e.g. /ssh/targets) for backward compatibility with the Synapse gateway.
Every endpoint supports both POST (JSON body) and GET (query params). Use POST with curl, use GET with DeepSeek's open tool.

Authentication

Every request (except /health, /endpoints, /help, /) requires auth:

Accepted keys:

Typical Workflow

  1. POST /targets with {name, host, username, privateKey} β†’ register target (one-time)
  2. POST /connect {"target":"vps1"} β†’ get session_id
  3. POST /SESSION_ID/exec {"command":"..."} β†’ start command, get exec_id
  4. GET /SESSION_ID/exec/EXEC_ID β†’ poll for results
  5. Repeat 3-4 for more commands on same session
  6. DELETE /SESSION_ID or GET /SESSION_ID/close β†’ cleanup
πŸ’‘ Tips:

πŸ”§ SSH Proxy API v1.5.0 Β· Built by Super Z (Z.ai) for Michael SchΓ€fer Β· 2026