Protocol Implementation
GoClaw's gateway serves HTTP REST and a custom WebSocket envelope on server.port, with the webhook listener on gateway.ingress.port when one is set. This page compares that protocol design with OpenClaw's, which also serves HTTP and WebSocket but as JSON-RPC.
Network Topology
flowchart TD
subgraph OC["OpenClaw"]
direction LR
OC_GW["<b>Gateway (:18789)</b><br/>• HTTP REST<br/>• WebSocket JSON-RPC<br/>• SSE (streaming)<br/>• TLS (optional)<br/>• Tailscale Serve/Funnel"]
OC_MED["<b>Media Server & Discovery</b><br/>• GET /media/:id (TTL auto-cleanup)<br/>• mDNS/Bonjour local discovery"]
OC_AUTH["<b>Bind & Auth</b><br/>• Bind: loopback / lan / tailnet / auto / custom<br/>• Auth: token / password / device-pairing / trusted-proxy"]
end
subgraph GC["GoClaw"]
direction LR
GC_GW["<b>Gateway (server.port, :8080)</b><br/>• HTTP REST<br/>• WebSocket (custom)<br/>• SSE (chat, logs, doctor)<br/>• OpenAI-compat API<br/>• App API<br/>• Static Web UI"]
GC_WH["<b>Webhook Listener & Ingress</b><br/>• gateway.ingress.port (else main port)<br/>• POST /goclaw/hook/<type>[/<key>]<br/>• /hook/[<slug>/]msteams, facebook, …<br/>• ngrok tunnel (gateway.ingress.type: ngrok)"]
GC_SEC["<b>Bind, Auth & Security</b><br/>• Bind: loopback / lan (0.0.0.0) / IP<br/>• Auth: token / rate-limit / trust-proxy / WS auth<br/>• Security: SSRF protection / IP allowlist / access log"]
end
WebSocket Protocol Comparison
| Aspect |
OpenClaw |
GoClaw |
| Library |
ws (Node.js) |
nhooyr.io/websocket (Go) |
| Path |
Upgrade on any path |
/gateway |
| Protocol |
JSON-RPC v3 (req/res/event) |
Custom envelope (inbound/outbound/error/canvas) |
| Handshake |
ConnectParams → HelloOk with features, snapshot, auth |
Token auth on upgrade |
| Protocol version |
PROTOCOL_VERSION = 3 |
None |
| Methods |
40+ RPC methods |
Implicit — kind field determines action |
| Events |
15+ event types |
outbound_chunk streaming |
| Streaming |
chat event with chunks |
outbound_chunk kind |
| Auth |
Token/password/device in ConnectParams |
Gateway token on the upgrade request (X-GoClaw-Token or Bearer header, ?token=, or cookie) |
| Bidirectional RPC |
Yes |
Partial — client inbound, server outbound |
OpenClaw WebSocket frame:
{ "type": "req", "id": "abc123", "method": "chat.send", "params": { "content": "hello" } }
{ "type": "res", "id": "abc123", "ok": true, "payload": { "sessionId": "..." } }
{ "type": "event", "event": "chat", "payload": { "content": "...", "streaming": true } }
GoClaw WebSocket frame:
{ "id": "uuid", "kind": "inbound", "session_id": "s1", "payload": { "channel": "web", "content": "hello" } }
{ "id": "uuid", "kind": "outbound_chunk", "payload": { "content": "Hel" } }
{ "id": "uuid", "kind": "outbound", "payload": { "content": "Hello! How can I help?" } }
REST API Endpoints
GoClaw Endpoint Summary
| # |
Endpoint |
Method |
Description |
Status |
| 4.1 |
/gateway |
WS |
WebSocket chat + streaming |
Done |
| 4.2 |
/api/webhook |
POST |
Inbound messages from integrations |
Done |
| 4.3 |
/api/logs |
GET |
SSE log streaming (real-time) |
Done |
| 4.4 |
/api/stats |
GET |
Provider, model, sessions, WS count, channels, version |
Done |
| 4.5 |
/api/sessions |
GET |
List sessions (id, title, message_count, last_seen); history is GET /api/session?id= |
Done |
| 4.6 |
/api/inspect |
GET |
Session + memory + paths inspection |
Done |
| 4.7 |
/api/memory |
GET |
Memory.md + SQLite global + personal records |
Done |
| 4.8 |
/api/canvas |
GET |
List canvas artifacts (name, size, mod_time) |
Done |
| 4.9 |
/api/pairing |
GET/POST |
Channel pairing (approve/revoke/update_role) |
Done |
| 4.10 |
/api/agents |
GET |
Multi-agent list + bindings + subagent runs |
Done |
| 4.11 |
/api/skills |
GET |
Skills with dependency status, tags, pure_go flag |
Done |
| 4.12 |
/api/cron |
GET/POST |
Cron jobs list + run, enable, disable, reschedule, delete |
Done |
| 4.13 |
/api/hooks |
GET |
Registered hook events + handler counts |
Done |
| 4.14 |
/api/extensions |
GET |
Discovered + active Go extensions |
Done |
| 4.15 |
/api/search |
GET |
Unified memory search (global+personal+archive) |
Done |
| 4.16 |
/api/memory/core?agent=<id> |
GET/POST |
Per-agent core instruction editor |
Done |
| 4.17 |
/api/send |
POST |
Loopback-only channel sender (cron → channel) |
Done |
| 4.18 |
/api/secrets |
GET/POST/DELETE |
Secrets vault management |
Done |
| 4.19 |
/api/config |
GET/POST |
CLI-like config management (get/set/append/remove) |
Done |
| 4.20 |
/api/gateway?limit=N |
GET |
Runtime info, ingress, access logs |
Done |
| 4.21 |
/ |
GET |
Static Web UI |
Done |
| 4.22 |
/hook/msteams (/hook/<webhook_secret_slug>/msteams) |
POST |
MS Teams Bot Framework webhook, on the webhook listener |
Done |
| 4.23 |
/health /healthz /ready /readyz |
GET |
Health/readiness probes (status, uptime_seconds) |
Done |
| 4.24 |
/v1/chat/completions |
POST |
OpenAI-compatible API (stream + non-stream) |
Done |
| 4.25 |
Auth middleware |
— |
Token auth on all API/WS routes, health exempt |
Done |
| 4.26 |
Rate limiting |
— |
Per-IP token bucket middleware (configurable) |
Done |
| 4.27 |
/api/chat |
POST |
Web UI chat, reply streamed as SSE |
Done |
Endpoints Comparison (OpenClaw vs GoClaw)
| Endpoint |
OpenClaw |
GoClaw |
Status |
| Health probe |
GET /health, /healthz |
Same, returns status and uptime_seconds |
Done |
| Chat completions |
POST /v1/chat/completions |
Same + subagent command routing |
Done |
| OpenResponses |
POST /v1/responses |
— |
TODO |
| Tool invoke |
POST /tools/invoke |
— |
TODO |
| HTTP hooks |
POST /hooks/* |
POST /goclaw/hook/<type>[/<key>] |
Done |
| Stats |
via WS RPC |
GET /api/stats |
Done |
| Sessions |
via WS RPC |
GET /api/sessions (list), GET /api/session (history) |
Done |
| Memory |
via WS RPC |
GET /api/memory (+ SQLite records) |
Done |
| Search |
— |
GET /api/search (keyword scoring, multi-source) |
GoClaw only |
| Canvas |
via WS RPC |
GET /api/canvas |
Done |
| Pairing |
via WS RPC |
GET/POST /api/pairing (approve/revoke/update_role) |
Done |
| Agents |
— |
GET /api/agents (multi-agent + bindings + subagent runs) |
GoClaw only |
| Skills |
— |
GET /api/skills (dep check, tags, pure_go) |
GoClaw only |
| Cron |
via WS RPC |
GET/POST /api/cron (list, run, enable, disable, reschedule, delete) |
GoClaw only |
| Hooks |
— |
GET /api/hooks (events + handlers) |
GoClaw only |
| Extensions |
— |
GET /api/extensions (discovered + active) |
GoClaw only |
| Core Inst. |
— |
GET/POST /api/memory/core?agent=<id> (per-agent) |
GoClaw only |
| Send |
— |
POST /api/send (loopback → channel) |
GoClaw only |
| Secrets |
credential store |
GET/POST/DELETE /api/secrets |
Done |
| Config |
via WS RPC |
GET/POST /api/config (CLI-like operations) |
Done |
| Runtime info |
— |
GET /api/gateway (ingress, access logs) |
GoClaw only |
| Log stream |
via WS events |
GET /api/logs (SSE) |
Done |
| Control UI |
{basePath}/* SPA |
GET / (static) |
Done |
| Webhook |
via WS RPC |
POST /api/webhook |
Done |
| Media hosting |
GET /media/:id |
GET /media/<id> |
Done |
| Canvas host |
/__openclaw__/canvas |
/canvas/<file>; HTML pages at /goclaw/view/<slug> |
Done |
| A2UI host |
/__openclaw__/a2ui |
— |
TODO |
| Avatar |
{basePath}/avatar/* |
— |
TODO |
| Plugin routes |
/{plugin}/api/* |
— |
TODO |
Additional Protocols
| Protocol |
OpenClaw |
GoClaw |
Status |
| TLS/HTTPS |
Optional gateway.tls.enabled |
— |
TODO |
| Tailscale Serve |
https://*.ts.net |
— |
TODO |
| Tailscale Funnel |
Public HTTPS tunnel |
— |
TODO |
| mDNS / Bonjour |
Local network discovery |
— |
TODO |
| Media server |
Separate HTTP server |
/media/<id> on the main port |
Done |
| SSE streaming |
Chat + responses |
/api/chat, /v1/chat/completions (stream: true), /api/app/events, /api/doctor?stream=1, /api/logs |
Done |
| Bot Framework |
— |
/hook/msteams or /hook/<webhook_secret_slug>/msteams (Teams), on the webhook listener |
Done |
| ngrok tunneling |
— |
Tunnel to the webhook listener when gateway.ingress.type: ngrok (IP allowlist) |
Done |
Gateway Auth & Security
| Feature |
OpenClaw |
GoClaw |
Status |
| No auth (loopback) |
Default |
Not offered: the gateway does not start without gateway.auth.token, on any bind |
— |
| Token auth |
X-OpenClaw-Token |
X-GoClaw-Token / Bearer header, ?token=, or cookie |
Done |
| WebSocket auth |
ConnectParams |
Token on the upgrade request (header, ?token= or cookie), reject unauthorized |
Done |
| Password auth |
gateway.auth.password |
— |
TODO |
| Device pairing |
Public key + signature |
— |
TODO |
| Trusted proxy |
Tailscale proxy headers |
gateway.rate_limit.trust_proxy (X-Forwarded-For) |
Done |
| Rate limiting |
AuthRateLimiter |
Per-IP token bucket, configurable req/min; requests with the token are exempt |
Done |
| Ingress IP allowlist |
— |
ngrok + M365 presets + CIDR |
GoClaw only |
| Access logging |
— |
Timestamp, IP, method, path, status, duration, host |
GoClaw only |
| SSRF protection |
— |
DNS-level private IP blocking |
GoClaw only |
| Remote connect |
OPENCLAW_GATEWAY_URL |
— |
TODO |
Gateway Source Files
Routes are registered in cmd/gateway/startup.go (registerAPIRoutes) and
cmd/gateway/main.go (the Web UI's files, /canvas/, /uploads/ and the
middleware chain), and implemented under internal/gateway. The route list,
with each route's request and response, is in
Gateway Endpoints.
OpenClaw vs GoClaw Protocol Comparison
| Aspect |
OpenClaw |
GoClaw |
| WebSocket protocol |
JSON-RPC v3 (40+ methods) |
Custom envelope (simple) |
| REST endpoints |
~15 (most via WS RPC) |
A REST endpoint for each feature |
| GoClaw only endpoints |
— |
agents, skills, cron, hooks, extensions, search, memory/core, send, gateway (runtime info) |
| Auth |
token/password/device-pairing |
token + WebSocket auth + rate limit + trust proxy |
| Network security |
— |
SSRF + IP allowlist + access logging |
| Tunneling |
Tailscale Serve/Funnel |
ngrok tunnel to the webhook listener |
| API style |
Mostly WS-based RPC |
REST-first (each feature has its own endpoint) |