Run OpenClaw as a WhatsApp assistant on its own number

Link a spare WhatsApp number to OpenClaw from the Control UI, decide who may message it, and keep group chats from triggering it by accident.

· ranx.cloud

Illustration of a speech bubble on a small wooden slab, linked by a dotted line to a second slab, like a paired device

This guide is for someone who wants an assistant they can text from the WhatsApp app they already use, without installing anything on their laptop. At the end you have OpenClaw linked to a dedicated WhatsApp number, answering only you (plus anyone you approve), and staying quiet in group chats unless someone mentions it.

Every step runs in the OpenClaw Control UI in a browser. There is no terminal step.

What you need

  • An OpenClaw gateway with the Control UI reachable over HTTPS, and a model provider connected under Settings → Models → Connect provider.
  • A second WhatsApp number for the bot. The WhatsApp channel docs recommend a separate number. Personal-number mode works too, but you lose a clean line between "messages to me" and "messages to the bot". A cheap prepaid SIM is enough. If your phone has dual SIM, the WhatsApp Business app can run the second number next to your normal WhatsApp.
  • A phone with that number logged into WhatsApp, in your hand while you scan the QR code.

OpenClaw connects through WhatsApp Web, the same linked-device protocol the desktop app uses (via the Baileys library). It is not the WhatsApp Business Platform API, and OpenClaw has no Twilio WhatsApp channel. In practice this means no Meta developer account and no per-message fees, and also that the bot appears as one more device under Linked devices on that phone. It also means you are using an unofficial client, which WhatsApp's terms do not allow; numbers that behave like bots can be banned. That is one more reason to use a spare number rather than your own.

Set it up

  1. Open Settings → Channels. Under Add a channel, pick WhatsApp. If it is not in the first row, open More channels…, which lists installable plugins too. WhatsApp ships as a separate plugin (@openclaw/whatsapp), so the first setup may install it before it continues.
  2. Choose Guided step-by-step setup. The wizard asks:
    • WhatsApp phone setup: pick Separate phone just for OpenClaw.
    • WhatsApp DM policy: pick Allowlist only (block unknown senders) if only you will use it, or pairing if you want to approve people as they ask. More on this below.
    • Allowed sender numbers: your personal number in E.164 format, for example +15551234567.
  3. When the wizard reaches Link WhatsApp by scanning the QR code, click Show QR. On the bot's phone, open WhatsApp → Settings → Linked devices → Link a device, and scan it. The QR expires quickly. If it goes stale, click New QR code rather than reloading the page.
  4. Wait for WhatsApp is linked and ready. The channel card under Connected channels should now read Running.
  5. From your personal phone, send the bot's number a message: hi, what can you do?

If the reply comes back, the plumbing works. The rest of this guide is about who else can reach it.

The config you end up with

The wizard writes a channels.whatsapp block. To see or edit it, open Settings → Advanced and switch to Raw (the raw JSON5 editor). For a one-person assistant it should look like this:

{
  channels: {
    whatsapp: {
      dmPolicy: "allowlist",
      allowFrom: ["+15551234567"],   // your personal number
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
    },
  },
}

Leave the rest of the file alone, especially the gateway block. Save, and the channel reloads without a restart.

DM policy: allowlist or pairing

channels.whatsapp.dmPolicy accepts four values (docs):

Value Who gets through
pairing (default) Unknown senders get a code and wait for you to approve them
allowlist Only numbers in allowFrom
open Anyone, and only if allowFrom contains "*"
disabled Nobody

Pairing suits a household setup. Your partner texts the bot, the request appears in Settings → Channels → DM access requests, and you click Approve. Requests expire after an hour, and each account holds at most three pending requests, so a stranger can't flood the queue.

The approve dialog has a checkbox, Also make this sender the first command owner. Tick it only for yourself. Command owners can run privileged slash commands and approve risky actions from chat.

Don't use open on a bot that has tools. Anyone who finds the number can then talk to an agent that can browse, fetch URLs and, depending on your tool settings, run commands.

Group chats

Adding the bot's number to a family or team group is where most of the surprises come from. Group access has two separate checks:

  1. Which groups count. channels.whatsapp.groups is both the per-group settings map and the allowlist. If you leave it out, every group the number is in is eligible.
  2. Which senders count. groupPolicy: "allowlist" plus groupAllowFrom decides whose messages in those groups can trigger a reply. If groupAllowFrom is unset, it falls back to allowFrom.

On top of that, groups need a mention by default. The bot answers when it is @-mentioned, when someone replies to one of its messages, or when a message matches a mention pattern. By default the patterns come from the agent's name, so naming the agent "Juno" makes "Juno, what time is the dentist?" count.

A family group where everyone may ask, but only by name:

{
  channels: {
    whatsapp: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567", "+15557654321", "+15550001111"],
      groups: {
        "120363012345678901@g.us": {
          requireMention: true,
          systemPrompt: "This is the family group. Keep answers to two or three lines.",
        },
      },
    },
  },
}

Once groups lists a specific JID, every other group is dropped before routing. To find a group's JID, mention the bot in the group once and look at the session list or Logs. The ID ends in @g.us.

Two behaviours to know about:

  • Replying to the bot does not authorize you. Quoting a bot message satisfies the mention requirement, but a sender outside groupAllowFrom is still blocked.
  • Unanswered messages become context. Up to 50 unprocessed group messages are buffered and passed in when the bot is next triggered (channels.whatsapp.historyLimit). That is useful ("summarize what I missed") and also a way for anyone in the group to put text in front of the model. Set historyLimit: 0 if the group is busy or not fully trusted.

To make one group always-on, set requireMention: false on that group's entry, or send /activation always in the group as the owner. The slash command only changes that session.

Small settings that make it nicer

{
  channels: {
    whatsapp: {
      replyToMode: "first",       // quote your message in the first reply chunk
      sendReadReceipts: true,     // default; set false to stay "unread"
      reactionLevel: "ack",       // react on receipt, no agent-chosen emoji
    },
  },
}

Voice notes work. Authorized voice notes are transcribed before mention gating, so saying the bot's name in a voice note in a group counts as a mention. Media is capped at 50 MB each way (mediaMaxMb).

Costs

WhatsApp itself costs nothing here, because this is a linked device and not the paid Business API. The cost is the model.

Use the Control UI's Usage page for real numbers. To plan, assume each turn sends about 20,000 input tokens (system prompt, tool definitions, recent history) and returns about 500 output tokens. With Claude Sonnet 5.5 at $2 per million input tokens and $10 per million output tokens (Anthropic pricing, November 2026):

input:  20,000 × $2  / 1,000,000 = $0.040
output:    500 × $10 / 1,000,000 = $0.005
per turn ≈ $0.045
30 messages a day ≈ $1.35/day ≈ $40/month (before caching)

Prompt caching brings this down a lot, because the system prompt and tools repeat on every turn and cache reads cost $0.10 per million on Sonnet 5.5. Treat $40 as a ceiling for a busy single user, not a forecast. Haiku 5.5 is $0.10/$0.50 per million and fine for chat-only use. The prompt injection docs advise against small models for an agent that has tools and reads messages from other people.

Also keep the heartbeat in mind. By default OpenClaw runs a check-in turn every 30 minutes and delivers alerts to the owner's DM, which may now be your WhatsApp. The heartbeat guide shows how to tune it.

What goes wrong

The QR expires before you scan it. The docs warn that QR codes relayed through screenshots or chat expire on the way. Scan straight from the browser screen with the bot's phone, and click New QR code if it has gone stale. A past issue covered QR refresh behaviour.

It was linked, now it says logged out. Removing the linked device on the phone, or a WhatsApp-side logout, ends the session. Older versions sometimes kept restarting a listener that WhatsApp had logged out for good (#78419, #49305). The fix is to re-link: open the WhatsApp channel details in Settings → Channels, click Relink, and scan again.

Reconnect loops. Repeated 408 disconnects were reported under heavy load on small hosts (#76315). If the card keeps flipping to Needs attention, check Logs for 408 and consider a plan with more CPU before blaming WhatsApp.

The agent answers in the transcript but nothing arrives on WhatsApp. The transcript records what the model wrote. Delivery is checked separately. Search Logs for auto-reply delivery failed. An ack reaction does not prove the reply was delivered.

Group messages are ignored. Check in this order: groupPolicy, groupAllowFrom/allowFrom, the groups map (did adding one group lock out the rest?), then mention patterns. Also check for duplicate keys in the raw config. In JSON5 the later key wins, which can quietly undo your change.

Messages you send to yourself trigger the bot. This only matters in personal-number mode. selfChatMode admits DMs from the linked number to itself, so a "note to self" becomes agent input. Set selfChatMode: false if you don't want that, or use a dedicated number.

Notes on hosting. On ranx.cloud, the linked session lives on the instance's persistent disk under /home/node/.openclaw, so it survives restarts and Stop. Deleting the instance removes it, and you will need to scan again.

Next steps

  • Lock down tools before you add the bot to any group with people you don't fully trust. The group-chat safety post covers tools.deny, contextVisibility and exec approvals.
  • Schedule an automation that reports into this chat at a fixed time.