๐Ÿ”
Gateway ArchitectureChapter 4 of 33ยท 6 min read

Chapter 4: Gateway Architecture

The OpenClaw Gateway is the core engine that makes everything work. Understanding how it is built helps you configure it correctly, troubleshoot problems faster, and extend it with confidence. This chapter explains the internal architecture of the gateway โ€” how messages move through it, what each layer does, and why the design choices were made.


What the Gateway Is

When you run openclaw start, you launch a Node.js server process on your machine or cloud host. This process is the Gateway. It does several things simultaneously:

  • Listens for incoming messages on every connected channel
  • Authenticates and identifies the sender
  • Routes the message to the correct workspace and agent
  • Executes any skills the agent needs
  • Returns the response back through the originating channel

Everything in OpenClaw flows through this single process.


The Four Layers

The Gateway has four distinct processing layers. Every message passes through all four in sequence.

Incoming Message
      โ†“
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  1. Channel Layer   โ”‚  Receives raw messages from WhatsApp, Telegram, Slack, etc.
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  2. Auth Layer      โ”‚  Verifies the sender's identity and permissions
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  3. Router Layer    โ”‚  Selects the right workspace, agent, and skill set
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  4. Agent Layer     โ”‚  Sends the message to the AI model and executes tools
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
      โ†“
Outgoing Response

Layer 1 โ€” Channel Layer

The Channel Layer is a collection of channel adapters โ€” one for each messaging platform. Each adapter:

  • Connects to the platform's API (WhatsApp Business API, Telegram Bot API, Slack Events API, etc.)
  • Listens for incoming messages in real time
  • Normalizes the message into OpenClaw's internal format
  • Passes the normalized message to the Auth Layer

The normalization step is critical. WhatsApp, Telegram, and Slack all use different JSON schemas. The channel adapter converts all of them into a single OpenClaw Message Object:

{
  "channel": "whatsapp",
  "channelUserId": "+1234567890",
  "workspaceId": "team-dev",
  "text": "Refactor this function to async/await",
  "timestamp": 1714500000000,
  "attachments": []
}

Layer 2 โ€” Auth Layer

The Auth Layer checks every incoming message against the workspace allowlist:

  1. Identifies the sender by their channel-specific ID (phone number, username, user ID)
  2. Looks up whether this sender is authorized in any workspace
  3. Rejects unauthorized senders with a polite error (or silence, depending on config)
  4. Attaches the workspace and user context to the message object

This is where pairing codes are verified. When a new user wants access, they use a pairing command and the gateway registers their channel ID in the workspace allowlist.

Layer 3 โ€” Router Layer

The Router Layer decides:

  • Which workspace owns this conversation
  • Which agent should handle this message
  • Which skills the agent has access to
  • What session context (conversation history) to attach

The Router maintains an in-memory session store. Each user gets a session that carries their conversation history. When you run /reset, the Router clears your session.

Layer 4 โ€” Agent Layer

The Agent Layer is where actual AI processing happens:

  1. Builds the prompt from message + session history + system prompt
  2. Calls the configured AI model API (Claude, GPT-4, Gemini, or local)
  3. Executes any tool calls the model requests (file reads, shell commands, web searches)
  4. Collects the full response
  5. Returns the response to the Router for delivery

The Message Lifecycle

StepLayerAction
1ChannelWhatsApp webhook fires with user message
2ChannelAdapter normalizes message to OpenClaw format
3AuthSender phone number looked up in allowlist
4AuthWorkspace team-dev matched, user alice identified
5RouterAgent claude-sonnet selected for workspace
6RouterSession history for alice retrieved
7AgentPrompt built: system prompt + history + new message
8AgentClaude API called with full prompt
9AgentClaude requests run_bash tool โ€” gateway executes it
10AgentFinal response assembled
11RouterResponse stored in session history
12ChannelResponse sent back to alice via WhatsApp

Sessions

The Gateway handles multiple users simultaneously using async I/O. Sessions are stored in memory:

{
  "userId": "alice",
  "workspaceId": "team-dev",
  "messages": [
    { "role": "user", "content": "..." },
    { "role": "assistant", "content": "..." }
  ],
  "createdAt": 1714500000000,
  "lastActiveAt": 1714503600000
}

Sessions expire after configurable inactivity (default: 30 minutes). Reset manually with /reset.


The Daemon Process

When you run openclaw onboard --install-daemon, OpenClaw installs as a system daemon that starts automatically on boot:

OSDaemon System
macOSlaunchd
Linuxsystemd
WindowsTask Scheduler
openclaw start          # start the gateway
openclaw stop           # stop the gateway
openclaw restart        # restart (reload config)
openclaw status         # check if running + active channels

Always run openclaw restart after editing openclaw.json.


Configuration Loading Order

  1. Global defaults โ€” built-in defaults for every setting
  2. Config file โ€” your openclaw.json overrides the defaults
  3. Environment variables โ€” OPENCLAW_* vars override the config file
  4. Runtime flags โ€” CLI flags override everything
OPENCLAW_CLAUDE_API_KEY=sk-ant-... openclaw start

Health Endpoint

GET http://localhost:3000/health
{
  "status": "ok",
  "uptime": 3621,
  "channels": {
    "whatsapp": "connected",
    "telegram": "connected",
    "slack": "disconnected"
  },
  "activeSessions": 4
}

Logs

Logs are written to ~/.openclaw/logs/openclaw.log.

LevelWhat It Shows
errorFatal errors, crashed channels
warnNon-fatal issues, retries
infoMessage received/sent, agent called
debugFull message payloads, API calls
traceEverything โ€” very verbose

Set log level in openclaw.json:

{
  "logLevel": "info"
}

Or enable trace for your current session only with the /trace chat command.


Next: Chapter 5 โ€” Workspaces & Multi-Agent Routing โ€” Learn how workspaces organize users and how the router picks the right agent for each message.