OpenClaw series · Part 4 · Updated October 20, 2026.
OpenClaw Gateway: port 18789, WebSocket, and message routing
The Gateway coordinates clients, conversations, channels, and agent execution. In a default local installation, open the Control UI at http://127.0.0.1:18789/. The documented WebSocket address is ws://127.0.0.1:18789, using the same port. Do not append /ws just because an older example did.
Three questions isolate most connection problems: is the Gateway listening, can this client authenticate, and is the request routed to the intended agent/session? A successful HTTP page load answers only part of the first question.
Architecture overview
| Component | Responsibility | Useful evidence |
|---|---|---|
| Gateway listener | Accept HTTP and WebSocket connections | Effective bind address, port, process/service status |
| Authentication and pairing | Identify an authorized client and its access | Handshake result and the intended device identity |
| Channel adapter | Receive and send messages for a messaging service | Provider connection and inbound/outbound logs |
| Routing and sessions | Select the agent and conversation context | Channel/account/peer, selected agent, and session identity |
| Agent tools and skills | Carry out work using available capabilities | Loaded skills, tool availability, approvals, and execution result |
Keeping these boundaries separate prevents a common mistake: changing a model or skill to repair a connection that never reached the agent.
Verify Gateway health before changing routing
On the Gateway host:
openclaw --version
openclaw gateway status
openclaw gateway probe
openclaw doctor
Inspect the runtime and connectivity results, not just the command’s existence. The current runbook also documents openclaw gateway status --require-rpc when you need read-scope RPC proof. A reachable port is weaker evidence than an authenticated RPC.
If a managed Gateway is already running, use its service lifecycle. Do not start a second process on the same port. For a foreground diagnostic run on a host without an active instance:
openclaw gateway --port 18789 --verbose
Default non-container installs bind to loopback. Containers and explicit settings can change that behavior; inspect the effective bind instead of assuming that a process is accessible only locally.
WebSocket protocol and authentication
The current protocol uses request, response, and event frames. Connection establishment includes a challenge and a connect handshake carrying the client’s role, capabilities, and authentication/device information. A generic JSON object with type: "chat" is not a substitute for that handshake.
For application clients, follow the Gateway protocol and its transport/handshake references for your installed release. The schema and client implementation are more reliable than copying a partial socket example from a blog.
The port is selected from the CLI override, environment, configuration, or default. Current upstream documents this order:
--port → OPENCLAW_GATEWAY_PORT → gateway.port → 18789
A service may retain the resolved port in its supervisor metadata. If an edited config and running service disagree, inspect service status and the current Gateway runbook before changing more settings.
Authentication happens before device pairing. Loopback is a network location, not a promise that credentials are unnecessary. Keep token/password handling and device approval distinct; do not disable either mechanism to make an unexplained connection failure disappear.
Message router and session model
A channel message arrives with a channel, account, sender/peer, and sometimes group or thread context. Routing chooses an agent; the session determines which conversation history that agent uses. A reply then needs the correct delivery destination.
When a Telegram message reaches the wrong conversation, record those identities before changing configuration. “Same person” does not necessarily mean “same session” across a DM, a group, a different channel, and a browser chat.
Use the current channel-routing reference for binding rules and session keys. Do not add guessed router.rules or session-cleanup fields from older examples to openclaw.json.
For a routing incident, compare:
- Which channel/account received the message?
- Which peer, group, or thread supplied its context?
- Which agent and session were selected?
- Did execution complete, and where was the reply sent?
If no inbound channel event exists, troubleshoot the provider connection and pairing first. If execution succeeded but delivery failed, keep the agent result and delivery error separate.
Tools, skills, and permissions
A tool is an executable capability. A skill is instructions for using capabilities. Installing a skill does not automatically register a new tool, grant host access, or place an API key inside a sandbox.
Start with the SKILL.md authoring guide for a small custom workflow. Check tool policy, sandbox scope, and dependency eligibility independently when a tool call fails. Avoid using “temporarily disable the sandbox” as a generic troubleshooting step.
Configuration, automation, and events
Keep Gateway configuration, channel routing, and automation schedules in their documented schemas. Confirm a setting is supported by the installed release before editing it. A JSON file being parseable does not prove that the application accepts its keys.
Likewise, connection events, agent results, scheduled runs, and outbound webhooks are different mechanisms. Inspect the relevant current reference rather than reusing an invented event name or webhook payload. For an existing automation, record its actual schedule, target agent/session, and delivery result before changing it.
Remote access without exposing port 18789 publicly
For an SSH-accessible Gateway host, a local forward is a useful diagnostic route:
ssh -N -L 18789:127.0.0.1:18789 user@gateway-host
Then open http://127.0.0.1:18789/ locally, retaining Gateway authentication. Choose another local port if 18789 is occupied. The forward does not make a second Gateway process.
For persistent remote access, follow the documented Tailscale or reverse-proxy setup, including origin and authentication handling. A proxy serving the HTML successfully may still fail WebSocket upgrades or reject the browser’s origin.
Troubleshooting
| Symptom | First distinction | Next check |
|---|---|---|
| Connection refused | No listener versus wrong address/port | Runtime, bind, service port, and whether the client is remote |
| Dashboard loads but chat disconnects | HTTP assets versus WebSocket handshake | Browser connection error, auth, pairing, origin, and proxy upgrades |
| Unauthorized | Reachable service with rejected credentials | Correct Gateway identity, auth mode, and client credential |
| Pairing required | Authentication versus device approval | The pending request and intended device; do not approve unrelated requests |
| Works locally, fails remotely | Listener scope versus remote transport | Tunnel/proxy route, allowed origins, and firewall evidence |
| Bot silent, browser chat works | Core Gateway versus channel path | Channel connection, pairing, sender/group policy, and delivery logs |
| Reply uses unexpected context | Routing versus model behavior | Selected agent/session and channel/group/thread identity |
Collect the version, effective endpoint, status/probe output, and a short sanitized log excerpt. Never include a Gateway token or raw private conversation in a public issue.
Next steps and references
Use the Web UI guide for dashboard access and visual surfaces, or return to channel setup when the failing boundary is a messaging provider.
These are documentation-backed diagnostics, not results from a live OpenClaw deployment in this article. Verify the boundary that failed before declaring a repair successful.