Skip to main content
Operator supports two distinct WhatsApp connection modes. Choose based on your infrastructure and requirements:
ModeHow it worksWhen to use
BridgeConnects to an external WhatsApp bridge over WebSocketYou already run a bridge (e.g., whatsapp-web.js, mautrix-whatsapp) or want a language-agnostic adapter
NativeUses whatsmeow in-processYou want a self-contained setup with no external bridge dependency
Always configure allow_from for WhatsApp. WhatsApp phone numbers are often guessable or discoverable via group chats. Without an allow list, any WhatsApp user who finds your number can interact with your agent.
In bridge mode, Operator connects to an external process that manages the WhatsApp Web protocol. The bridge and Operator communicate over a WebSocket connection using a simple JSON message protocol.The bridge sends messages to Operator with this structure:
{
  "type": "message",
  "from": "+15551234567",
  "chat": "+15551234567",
  "content": "Hello",
  "id": "msg_abc123",
  "from_name": "Alice"
}
Operator sends replies with:
{
  "type": "message",
  "to": "+15551234567",
  "content": "Hi Alice!"
}

Setup

1

Deploy a WhatsApp bridge

Set up a WebSocket-capable WhatsApp bridge that implements the protocol above. The bridge should expose a WebSocket server at a URL like ws://localhost:3001.
2

Configure Operator

{
  "channels": {
    "whatsapp": {
      "enabled": true,
      "bridge_url": "ws://localhost:3001",
      "use_native": false,
      "session_store_path": "",
      "allow_from": ["+15551234567"],
      "reasoning_channel_id": ""
    }
  }
}
3

Start the gateway

Start Operator. It will connect to the bridge WebSocket on startup and begin routing messages.

Configuration reference

enabled
boolean
required
Set to true to activate the WhatsApp channel.
bridge_url
string
WebSocket URL of the external bridge. Required when use_native is false. Example: ws://localhost:3001.
use_native
boolean
When true, use the built-in whatsmeow connection instead of an external bridge. Requires the whatsapp_native build tag. Default: false.
session_store_path
string
Directory path where the SQLite session database is stored in native mode. Example: /var/lib/operator/whatsapp. If empty, defaults to "whatsapp" relative to the working directory.
allow_from
array of strings
Sender identifiers permitted to message the agent. In bridge mode, this is typically the phone number as the bridge sends it (e.g. "+15551234567"). In native mode, use WhatsApp JIDs (e.g. "[email protected]").Strongly recommended — leave empty only if you fully control who can reach the WhatsApp number. See Common configuration fields for details.
reasoning_channel_id
string
A chat ID where agent reasoning traces are sent. Leave empty to disable. See Messaging channels for details.

Security considerations

WhatsApp numbers are often shared in groups and can be forwarded. Unlike Slack or Discord where you control server membership, a WhatsApp number can receive messages from anyone with it. Always set allow_from to a specific list of phone numbers or JIDs. Messages from senders not in allow_from are dropped immediately, before any media is downloaded or the agent is invoked.

Build docs developers (and LLMs) love