Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

WhatsApp

ZeroClaw supports two WhatsApp backends under the same channels.whatsapp config family:

ModeUse it whenRequired selector
WhatsApp Cloud APIYou have a Meta Business app and WhatsApp Business phone number IDphone_number_id
WhatsApp WebYou want to link a regular WhatsApp account through the Web protocolsession_path

Do not configure both selectors in the same channel unless you intentionally want Cloud API mode to win for backward compatibility.

Who can talk to the agent

Inbound senders are gated against the peer set resolved for the bound agent, drawn from the peer_groups config the agent belongs to. Matching strips a leading @ and is case-insensitive against the channel’s native sender identifier. An empty set denies everyone; a set containing "*" accepts anyone; otherwise only the listed external peers (and peer agents) are accepted. This is separate from gateway pairing (gateway.require_pairing), which authenticates HTTP/WebSocket clients, not chat-channel senders.

A peer group for whatsapp sets channel to whatsapp, lists the allowed senders in external_peers (for whatsapp, a phone identifier (Cloud API) or the JID user part (Web mode); ["*"] accepts anyone), optionally names peer agents for cross-agent dispatch, an ignore blocklist, and an output_modality (mirror, voice, or text). See Peer Groups for the field reference.

Where to set this:

Gateway dashboard

Open /config/peer_groups in the web dashboard.

zerocode

In the Config pane, under Peer groups.

Cloud API mode

Cloud API mode is the Meta Business Platform integration. It requires a Meta Business account, a WhatsApp Business app, a phone number ID, a verify token, and an access token. It is the right mode for business deployments that receive messages through Meta webhooks.

The gateway must be reachable by Meta for inbound webhooks. Configure a tunnel under the top-level [tunnel] section (tunnel_provider and the related provider blocks, see the config reference), or front the gateway with your own reverse proxy when developing locally.

Web mode

WhatsApp Web mode links a regular WhatsApp account through the optional Web backend. It does not need a Meta Business account. It does need a ZeroClaw build with the whatsapp-web feature enabled and a persistent session database path.

On first start, the Web backend pairs the account using QR or pair-code linking (pair_phone seeds pair-code linking; leave it unset for QR). Keep session_path on persistent storage; removing it forces a fresh device link. Bind the channel to an agent via that agent’s channels list.

Personal and business behavior

For Web mode, mode = "personal" applies separate DM, group, and self-chat policies:

FieldValuesEffect
dm_policyallowlist, ignore, allControls direct messages
group_policyallowlist, ignore, allControls group chats
self_chat_modetrue, falseControls the user’s self-chat
mention_onlytrue, falseRequires group messages to mention the bot

The default mode = "business" does not apply the personal DM/group policy split. For peer-gated regular-account deployments, use mode = "personal" with dm_policy = "allowlist" and group_policy = "allowlist".

Configuration surfaces

access_token 🔑 secret · default null

Access token from Meta Business Suite (Cloud API mode)

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.access_token field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.access_token field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.access_token    # masked input, stored encrypted

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__access_token=
app_secret 🔑 secret · default null

App secret from Meta Business Suite (for webhook signature verification) Can also be set via ZEROCLAW_WHATSAPP_APP_SECRET environment variable Only used in Cloud API mode

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.app_secret field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.app_secret field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.app_secret    # masked input, stored encrypted

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__app_secret=
approval_timeout_secs integer · default 300

Seconds to wait for operator approval on always_ask tools before auto-denying.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.approval_timeout_secs field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.approval_timeout_secs field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.approval_timeout_secs <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__approval_timeout_secs=
dm_mention_patterns string[] · default []

Regex patterns for DM mention gating (case-insensitive). When non-empty, only direct messages matching at least one pattern are processed; matched fragments are stripped from the forwarded content. Example: ["@?ZeroClaw", "\\+?15555550123"]

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.dm_mention_patterns field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.dm_mention_patterns field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.dm_mention_patterns <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__dm_mention_patterns=
dm_policy WhatsAppChatPolicy · default "allowlist"

Policy for direct messages when mode = “personal”. “allowlist” (default) | “ignore” | “all”.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.dm_policy field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.dm_policy field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.dm_policy <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__dm_policy=
excluded_tools string[] · default []

Tools excluded from this channel’s tool spec. When set, these tools are not exposed to the model when responding via this channel.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.excluded_tools field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.excluded_tools field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.excluded_tools <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__excluded_tools=
group_mention_patterns string[] · default []

Regex patterns for group-chat mention gating (case-insensitive). When non-empty, only group messages matching at least one pattern are processed; matched fragments are stripped from the forwarded content. Example: ["@?ZeroClaw", "\\+?15555550123"]

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.group_mention_patterns field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.group_mention_patterns field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.group_mention_patterns <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__group_mention_patterns=
group_policy WhatsAppChatPolicy · default "allowlist"

Policy for group chats when mode = “personal”. “allowlist” (default) | “ignore” | “all”.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.group_policy field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.group_policy field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.group_policy <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__group_policy=
mention_only bool · default false

When true, only respond to messages that @-mention the bot in groups (Web mode only). Direct messages are always processed. Bot identity is resolved from the wa-rs device at runtime; pair_phone seeds it on first connect.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.mention_only field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.mention_only field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.mention_only <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__mention_only=
mode WhatsAppWebMode · default "business"

Usage mode for WhatsApp Web: “business” (default) or “personal”. In personal mode the bot applies dm_policy, group_policy, and self_chat_mode to decide which chats to respond in.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.mode field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.mode field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.mode <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__mode=
pair_code string? · default null

Custom pair code for linking (Web mode, optional) Leave empty to let WhatsApp generate one

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.pair_code field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.pair_code field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.pair_code <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__pair_code=
pair_phone string? · default null

Phone number for pair code linking (Web mode, optional) Format: country code + number (e.g., “15551234567”) If not set, QR code pairing will be used

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.pair_phone field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.pair_phone field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.pair_phone <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__pair_phone=
phone_number_id string? · default null

Phone number ID from Meta Business API (Cloud API mode)

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.phone_number_id field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.phone_number_id field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.phone_number_id <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__phone_number_id=
proxy_url string? · default null

Per-channel proxy URL (http, https, socks5, socks5h). Overrides the global [proxy] setting for this channel only.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.proxy_url field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.proxy_url field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.proxy_url <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__proxy_url=
reply_min_interval_secs integer · default 0

Per-(channel, recipient) outbound pacing floor in seconds. Range: 0..=REPLY_MIN_INTERVAL_MAX_SECS (0 disables).

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.reply_min_interval_secs field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.reply_min_interval_secs field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.reply_min_interval_secs <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__reply_min_interval_secs=
reply_queue_depth_max integer · default 0

Per-(channel, recipient) outbound pacing queue depth. Range: 0..=REPLY_QUEUE_DEPTH_CEILING. When reply_min_interval_secs > 0 and this value is 0, the pacing wrapper substitutes DEFAULT_REPLY_QUEUE_DEPTH (16). When the queue is full, the newest send is dropped and a WARN is logged.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.reply_queue_depth_max field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.reply_queue_depth_max field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.reply_queue_depth_max <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__reply_queue_depth_max=
self_chat_mode bool · default false

When true and mode = “personal”, always respond to messages in the user’s own self-chat (Notes to Self). Defaults to false.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.self_chat_mode field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.self_chat_mode field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.self_chat_mode <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__self_chat_mode=
session_path string? · default null

Session database path for WhatsApp Web client (Web mode) When set, enables native WhatsApp Web mode with wa-rs

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.session_path field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.session_path field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.session_path <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__session_path=
verify_token 🔑 secret · default null

Webhook verify token (you define this, Meta sends it back for verification) Only used in Cloud API mode

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.verify_token field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.verify_token field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.verify_token    # masked input, stored encrypted

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__verify_token=
ws_url string? · default null

Override the WhatsApp Web WebSocket URL (Web mode, optional). Used by integration tests and proxy setups; leave unset to use the default endpoint that ships with wa-rs.

Set it on any surface:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.ws_url field.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.ws_url field.

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.ws_url <value>

Environment variable

Export the override (POSIX shells; drop into ~/.bashrc, ~/.zshrc, .env, or a Dockerfile). Replace <alias> with the literal alias:

export ZEROCLAW_channels__whatsapp__<alias>__ws_url=

Gateway dashboard

Open /config/channels/whatsapp in the web dashboard.

zerocode

In the Config pane, under Channels.

channels.whatsapp.<alias>.access_token is a secret. Stored encrypted, never in plain config.toml. Set it through one of these, which encrypt on write:

Gateway dashboard

Open /config/channels/whatsapp and set the channels.whatsapp.<alias>.access_token field there.

zerocode

In the Config pane, set the channels.whatsapp.<alias>.access_token field (input is masked).

zeroclaw config

zeroclaw config set channels.whatsapp.<alias>.access_token    # prompts for masked input, stores encrypted

The same applies to verify_token and app_secret (Cloud API).

Start and check

After configuring one mode, start the channel runner:

sh

zeroclaw channel start

Use zeroclaw channel doctor for a first check. For Web mode, also confirm the binary was built with whatsapp-web; for Cloud API mode, confirm the webhook tunnel and Meta verify token agree.