API Reference

3 built-in C servers, 19 endpoints, JWT auth, SSE streaming, CGI execution, WebSocket bridging — all from source, zero dependencies.

3
Servers
19
Endpoints
6
Middleware
0
Dependencies

Contents

Overview Servers Endpoints Middleware CGI Execution WebSocket Bridge Configuration

Overview

scorpiox code ships 3 HTTP/WebSocket servers written in pure C — no nginx, no Node, no external runtime. scorpiox-server is the primary application server executing Python CGI scripts with JWT authentication. scorpiox-host manages AI coding sessions via REST API. scorpiox-ws2tcp bridges WebSocket connections to TCP backends for noVNC.

Servers

scorpiox-server

Built-in HTTP server — executes Python scripts as CGI routes with JWT auth, SSE streaming, and git deploy.

:8080 scorpiox/scorpiox-server.c
python_cgi sse_streaming jwt_auth cors git_deploy large_body_streaming chunked_transfer

scorpiox-host

Session gateway server — manages AI coding sessions, events, and messages via REST API.

:7432 scorpiox/scorpiox-host.c
session_management event_streaming message_queue session_discovery

scorpiox-ws2tcp

WebSocket to TCP bridge — replaces Python websockify for noVNC deployments with static file serving.

:6080 bridge/ws2tcp.c
websocket tcp_bridge static_files token_auth

Endpoints

scorpiox-server — :8080

Method Path Description Auth
OPTIONS * (any) CORS preflight — returns 204 with permissive Access-Control headers for any path
GET /api/ping Health check — returns ‘ok’ as plain text
GET /api/otp?a=&s= Generate TOTP code — invokes scorpiox-otp CLI with sanitized inputs, returns JSON
GET {prefix}{name} Execute {name}.py from script dirs — query params passed as env vars, CGI headers parsed from output JWT⚙
POST {prefix}{name} Execute {name}.py with POST body — body written to temp file (POST_BODY_FILE), large bodies (>512KB) streamed to stdin JWT⚙
GET {prefix} Default route — when name is empty, serves index.py from script dirs JWT⚙
* * (no match) Catch-all fallback — when no script matches and _fallback.py exists, invokes it with original path JWT⚙

scorpiox-host — :7432

Method Path Description Auth
GET /health Server health check — returns {"status":"ok"}
GET /status Server summary — returns version, port, uptime, session count, active count as JSON
GET /sessions List all sessions — re-discovers sessions from .scorpiox/sessions dir, returns JSON array
GET /sessions/:id Session detail — returns full session info including state, event_count, message_count
GET /sessions/:id/events Get session events — returns all buffered events as NDJSON
POST /sessions/:id/events Fire event for session — creates/updates session, pushes event to ring buffer
POST /sessions/:id/register Register a session — creates or updates session with name, sets state to active
GET /sessions/:id/messages Pull queued messages — returns and drains the message queue for a session
POST /sessions/:id/messages Push message to session — queues a message for the session (max 32 queued)
POST /stop Graceful shutdown — stops the host server

scorpiox-ws2tcp — :6080

Method Path Description Auth
GET /* Static file serving — serves files from webroot directory with MIME type detection
WS / (WebSocket upgrade) WebSocket upgrade — performs Sec-WebSocket-Accept handshake then bridges binary frames to TCP backend token⚙

Middleware

All middleware is compiled into scorpiox-server. No plugins, no dynamic loading.

cors

Permissive CORS on every response — Access-Control-Allow-Origin: *, all methods, all headers, credentials allowed, 86400s max-age.

jwt_auth

JWT HMAC-SHA256 authentication — extracts token from Authorization: Bearer header or configurable cookie, validates signature/exp/iss/aud, maps custom claims to env vars, protects configurable route prefixes, redirects browsers to login URL on 401.

cgi_env

Full CGI environment — sets REQUEST_METHOD, CONTENT_TYPE, CONTENT_LENGTH, QUERY_STRING, PATH_INFO, HTTP_COOKIE, HTTP_AUTHORIZATION, and all HTTP_* headers as env vars for scripts.

body_streaming

Large body streaming — POST bodies >512KB are streamed directly to script stdin instead of buffering, with chunked transfer encoding support.

request_limits

Request/response size limits — configurable max request (SERVER_MAX_REQUEST_MB, default 200MB) and max response (SERVER_MAX_RESPONSE_MB, default 200MB).

script_timeout

Script idle timeout — kills scripts that produce no stdout for SERVER_SCRIPT_TIMEOUT seconds (default 300s).

CGI Execution

Python CGI execution engine — scripts output optional CGI headers (Status, Content-Type, Location, Set-Cookie) followed by blank line then body. SSE support via Content-Type: text/event-stream.

Script resolution: searches SERVER_SCRIPT_DIR directories in order, first dir containing {name}.py wins.

Variable Description
REQUEST_METHODHTTP method (GET, POST, etc.)
CONTENT_TYPERequest Content-Type header value
CONTENT_LENGTHRequest body size in bytes
QUERY_STRINGRaw query string after ?
PATH_INFOMatched path portion of the URL
HTTP_COOKIECookie header value
HTTP_AUTHORIZATIONAuthorization header value
POST_BODY_FILETemp file path containing POST body (<512KB)
SX_STREAMINGSet to "1" when SSE streaming is active
X_JWT_RAWRaw JWT token if auth is enabled
X_JWT_SUBJWT subject claim value
X_JWT_AUTHSet to "1" if JWT validated successfully
HTTP_*All request headers prefixed with HTTP_
Example CGI Script
#!/usr/bin/env python3
# hello.py — minimal CGI example
import os

name = os.environ.get('name', 'world')
print("Content-Type: text/html")
print()
print(f"<h1>Hello, {name}!</h1>")
SSE Streaming Example
#!/usr/bin/env python3
# stream.py — SSE streaming CGI
import sys, time

print("Content-Type: text/event-stream")
print()
for i in range(10):
    print(f"data: event {i}
")
    sys.stdout.flush()
    time.sleep(1)

WebSocket Bridge

scorpiox-ws2tcp

WebSocket-to-TCP bridge server — performs RFC 6455 handshake, bridges binary WebSocket frames to backend TCP targets. Used for noVNC/VNC proxying. Includes static file serving for web client assets.

noVNC VNC proxying TCP bridging
Launch WebSocket Bridge
# Bridge ws://localhost:6080 → tcp://localhost:5900 (VNC)
scorpiox-ws2tcp --port 6080 --target localhost:5900 --webroot /opt/novnc

Configuration

All config via scorpiox-env.txt environment variables. No YAML, no TOML, no config files to parse.

scorpiox-server

Key Description Default
SERVER_PORT HTTP listen port 8080
SERVER_SCRIPT_DIR Colon-separated list of directories to search for .py scripts .
SERVER_PREFIX URL prefix for script routes (e.g. /app/) /
SERVER_JWT_SECRET HMAC-SHA256 secret for JWT validation
SERVER_JWT_PROTECT Comma-separated route prefixes requiring JWT auth
SERVER_JWT_COOKIE Cookie name to extract JWT from (alternative to Bearer header)
SERVER_JWT_LOGIN_URL Redirect URL for browser 401 responses
SERVER_MAX_REQUEST_MB Maximum request body size in megabytes 200
SERVER_MAX_RESPONSE_MB Maximum response body size in megabytes 200
SERVER_SCRIPT_TIMEOUT Idle timeout in seconds — kills scripts with no stdout activity 300
SERVER_GIT_CACHE_DIR Git deploy: local clone directory for auto-pull
SERVER_GIT_POLL_INTERVAL Git deploy: poll interval in seconds for change detection
SERVER_GIT_PAT Git deploy: personal access token for repo authentication
scorpiox-env.txt
# HTTP server configuration
SERVER_PORT=8080
SERVER_SCRIPT_DIR=/opt/website:/opt/api
SERVER_PREFIX=/

# JWT authentication
SERVER_JWT_SECRET=your-hmac-secret-here
SERVER_JWT_PROTECT=/admin,/api/private
SERVER_JWT_COOKIE=sx_token
SERVER_JWT_LOGIN_URL=https://login.scorpiox.net/

# Git deploy (auto-pull website repo)
SERVER_GIT_CACHE_DIR=/var/cache/scorpiox-site
SERVER_GIT_POLL_INTERVAL=60

Git Deploy

Git deploy mode — clones a git repo, polls for changes, auto-pulls and hot-reloads script directory. Supports PAT auth. scorpiox-server becomes a self-updating web application server with zero downtime deploys.

Deploy Flow
# 1. scorpiox-server starts, reads SERVER_GIT_CACHE_DIR
# 2. Clones repo into cache dir (with PAT if set)
# 3. Adds cache dir to SERVER_SCRIPT_DIR search path
# 4. Background thread polls every SERVER_GIT_POLL_INTERVAL seconds
# 5. On change: git pull, scripts are immediately available
# 6. No restart needed — new requests use updated scripts