Skip to main content
Use @kapso/openclaw-whatsapp when an OpenClaw agent needs to send and receive WhatsApp messages through Kapso. Use @kapso/whatsapp-cloud-api directly when you are building your own app and do not need OpenClaw channel routing.

Installation

Requires OpenClaw >= 2026.5.27.
If plugins.allow already has entries, keep them and add kapso-whatsapp. OpenClaw resolves the plugin from ClawHub and installs runtime dependencies, including @kapso/whatsapp-cloud-api and @kapso/cli. No separate npm install is needed. The Kapso CLI is bundled with the plugin:

Setup

Requires: After your OpenClaw gateway has a public URL, let the plugin resolve the number, register the webhook, and write config:
If you already know the Kapso/Meta phone_number_id, use --phone-number-id:
Useful setup flags: Omit --write-config to print the openclaw config set commands without applying them.

Agent setup

The plugin ships an OpenClaw skill named kapso-whatsapp-setup. Check that OpenClaw sees it:
Before asking the agent to finish setup, do the interactive and secret-bearing steps yourself:
Use the browser dashboard for setup visibility:
If you prefer the terminal UI, start openclaw tui and send:
Then paste something like this into OpenClaw:
If you already know the public webhook URL, replace the gateway line with:
If you use another public tunnel or reverse proxy, name it:
If you already know the Kapso/Meta number ID, replace the sender-number line with:
If the Kapso CLI is not logged in, the agent should stop and ask you to run openclaw kapso-whatsapp cli login in your terminal. It should not run interactive login for you.

Public gateway

Kapso Cloud must reach your OpenClaw webhook over the public internet. A private tailnet URL is not enough. For Tailscale, use Funnel:
Use --password-file instead of passing a password directly in process arguments. The Kapso webhook URL should use your Funnel hostname plus /kapso/webhook:
Discover an existing Funnel URL from the machine running OpenClaw:

Configure manually

Use JSON strings for IDs and secrets, especially digit-only values. Current plugin versions coerce numeric phoneNumberId and defaultTo values, but JSON strings avoid precision loss for large IDs. Optional settings:
Kapso webhook sender IDs often arrive as digits-only values, while users usually type E.164 numbers with +. Current plugin versions compare both forms as the same sender. Including both is harmless for older installs or raw config edits. You can also use environment variables:

Kapso webhook

Create a phone-number scoped Kapso webhook, not a project webhook. The setup command can register this webhook with --register-webhook. You can also run the bundled Kapso CLI through OpenClaw:
The setup command uses the bundled CLI internally for number resolution, project access checks, and webhook registration.

Channel targets

The plugin accepts WhatsApp phone-number targets with these prefixes:
Plain E.164 or digits-only phone numbers also work. Set a default recipient when you want OpenClaw to send through this channel without an explicit target:

Diagnostics

Check config and webhook registration:
Tail OpenClaw logs:
If the gateway prints a log path, tail it directly:

Media

Images, videos, and documents can be forwarded when Kapso includes a downloadable media URL, such as mediaUrl, media_data.url, media_data.downloadUrl, or a direct media link or url. The selected OpenClaw model/runtime must support that media type. If Kapso sends only a media ID and no URL, the plugin records that media exists but cannot pass the file bytes to the model. Logs warn about id but no URL. Voice notes and audio messages need a transcription provider. Without one, the agent may only receive audio metadata. Hosted options include OpenAI gpt-4o-transcribe, gpt-4o-mini-transcribe, or whisper-1. Self-hosted ASR can work if your OpenClaw deployment exposes a compatible transcription provider.

Troubleshooting

Config values rejected as “must be string”

Use strict JSON strings:

Webhook returns 401

The Kapso webhook secret and channels["kapso-whatsapp"].webhookSecret do not match, or the request is missing the Kapso signature header.

Webhook is reachable but no messages arrive

Confirm the webhook is phone-number scoped and subscribed to whatsapp.message.received. Project webhooks do not receive WhatsApp message events.

Webhook dispatches but no agent session or reply

Check allowFrom. Kapso commonly sends inbound sender IDs without a leading +, even if your allowlist was configured with E.164 values. Current plugin versions compare those forms as the same sender. On older installs, include both variants and restart the gateway:

Images sometimes work and sometimes do not

Check logs for media=image/url=yes. If logs say url=no or warn that the event had an ID but no URL, the model did not receive the actual image bytes.

Source

GitHub repository

Source code, setup skill, and issue tracker for @kapso/openclaw-whatsapp.