Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.wednesdayai.dev/llms.txt

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

Gateway API reference

The WednesdayAI gateway exposes:
  1. WebSocket control plane — all clients (CLI, web UI, mobile apps) connect here
  2. HTTP tools endpoint — invoke agent tools directly without a full agent run
  3. OpenAI-compatible chat completions — drop-in for tools expecting OpenAI API format
All endpoints share the same port (18789 by default) via HTTP/WebSocket multiplexing.

Authentication

All endpoints use the gateway auth configuration:
Auth modeHow to authenticate
token (default)Authorization: Bearer <OPENCLAW_GATEWAY_TOKEN>
passwordAuthorization: Bearer <OPENCLAW_GATEWAY_PASSWORD>
trusted-proxyDelegated to upstream proxy via x-forwarded-user header
Too many failed auth attempts returns HTTP 429 with a Retry-After header.

WebSocket protocol

The WebSocket control plane is the primary integration surface. All CLI commands, the web control panel, and mobile nodes use this protocol. Connection: ws://localhost:18789 (or wss:// with TLS)

Handshake

The gateway sends a challenge before accepting the connection: Gateway → Client (challenge):
{
  "type": "event",
  "event": "connect.challenge",
  "payload": { "nonce": "...", "ts": 1737264000000 }
}
Client → Gateway (connect request):
{
  "type": "req",
  "id": "req-1",
  "method": "connect",
  "params": {
    "minProtocol": 3,
    "maxProtocol": 3,
    "client": {
      "id": "my-client",
      "version": "1.0.0",
      "platform": "linux",
      "mode": "operator"
    },
    "role": "operator",
    "scopes": ["operator.read", "operator.write"],
    "caps": [],
    "commands": [],
    "permissions": {},
    "auth": { "token": "your-gateway-token" },
    "locale": "en-US",
    "userAgent": "my-client/1.0.0"
  }
}
Gateway → Client (success):
{
  "type": "res",
  "id": "req-1",
  "ok": true,
  "payload": {
    "type": "hello-ok",
    "protocol": 3,
    "policy": { "tickIntervalMs": 15000 },
    "auth": {
      "deviceToken": "...",
      "role": "operator",
      "scopes": ["operator.read", "operator.write"]
    }
  }
}
The deviceToken in the response can be saved and used for subsequent connections — pass it as auth.token to skip full re-authentication.

Request/response pattern

After handshake, all communication uses type: "req" with an id for correlation, and type: "res" responses:
{
  "type": "req",
  "id": "req-2",
  "method": "sessions.list",
  "params": {}
}
{
  "type": "res",
  "id": "req-2",
  "ok": true,
  "payload": { "sessions": [...] }
}
On error, ok is false and error is set:
{
  "type": "res",
  "id": "req-2",
  "ok": false,
  "error": { "code": "NOT_FOUND", "message": "Session not found" }
}

Key RPC methods

MethodDescription
connectHandshake — must be the first call
config.getRead current gateway config
config.applyFull config replace (validates, writes, and restarts)
config.patchPartial config update (JSON merge patch)
sessions.listList active sessions
sessions.getGet session details
sessions.clearClear session history
gateway.statusGateway health snapshot
gateway.callInvoke an RPC method by name
logs.tailTail the gateway log file
health.probeFull health probe
channels.statusPer-channel connectivity status
tools.invokeInvoke a tool (same as HTTP endpoint)

Config RPC rate limiting

config.apply and config.patch are rate-limited to 3 requests per 60 seconds per deviceId+clientIp. When limited, returns UNAVAILABLE with retryAfterMs. config.apply and config.patch require a baseHash (the current config hash from config.get) to prevent concurrent conflicting writes. Restarts are coalesced with a 30-second cooldown.

HTTP: Tool invocation

POST /tools/invoke — invoke a single agent tool directly. Always enabled; gated by gateway auth and tool policy. Maximum payload size: 2 MB Request:
curl -X POST http://localhost:18789/tools/invoke \
  -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "sessions_list",
    "args": {},
    "sessionKey": "main"
  }'
Request fields:
FieldTypeRequiredDescription
toolstringYesTool name to invoke
actionstringNoShorthand mapped into args if tool supports action
argsobjectNoTool-specific arguments
sessionKeystringNoTarget session key. Defaults to main session
dryRunbooleanNoReserved — currently ignored
Tool availability is filtered through the agent tool policy chain:
  • tools.profile / tools.allow in global config
  • agents.<id>.tools.allow for per-agent policy
  • Group/channel policies for session-routed tools
If a tool is not allowed by policy, the endpoint returns HTTP 404.

HTTP: OpenAI-compatible chat completions

POST /v1/chat/completions — drop-in replacement for the OpenAI Chat Completions API. Runs a full gateway agent turn. Disabled by default. Enable in config:
{
  gateway: {
    http: {
      endpoints: {
        chatCompletions: { enabled: true },
      },
    },
  },
}
This endpoint has full operator-access to the gateway. A valid token here is equivalent to owner/operator credentials. Keep it on loopback or a private network — do not expose it to the public internet.
Request:
curl -X POST http://localhost:18789/v1/chat/completions \
  -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openclaw:main",
    "messages": [
      { "role": "user", "content": "What is the current time?" }
    ],
    "stream": false
  }'
Targeting a specific agent:
{
  "model": "openclaw:main",  // openclaw:<agentId>
  ...
}
Or via header:
x-openclaw-agent-id: main
x-openclaw-session-key: agent:main:whatsapp:dm:+15555550123
Response follows the OpenAI Chat Completions response format. Tool calls, streaming (stream: true), and multi-turn conversations are supported.

Node connection (mobile/desktop nodes)

Nodes (iOS, Android, macOS app in node mode) connect with role: "node" and advertise their capabilities:
{
  "type": "req",
  "id": "req-1",
  "method": "connect",
  "params": {
    "role": "node",
    "scopes": [],
    "caps": ["camera", "canvas", "screen", "location", "voice"],
    "commands": ["camera.snap", "canvas.navigate"],
    "auth": { "token": "node-device-token" },
    ...
  }
}
After connecting, the node listens for node.* RPC calls dispatched by the gateway agent and returns results.

See also