Why does Chatwoot return 401 Unauthorized to WhatsApp webhooks?
In short: since version 4.14, Chatwoot checks the X-Hub-Signature-256 of WhatsApp Cloud deliveries against the app_secret of the inbox they match. A 401 means one of two things: no inbox matches the number, or the inbox's app_secret is not the secret that signed the delivery. You fix both on the inbox, through Chatwoot's API.
ZapClaw connects your number to the official WhatsApp API, signs every delivery to Chatwoot and shows the inbox command for each number with the number's details filled in.
Start for freeThe two causes
- No inbox matches the number. Chatwoot picks the inbox from the business number and the Phone Number ID inside the payload: the inbox's phone number must be your WhatsApp number in E.164 (
+, country code and number, no spaces), and itsphone_number_idmust be that number's ID. With no match, Chatwoot checks the signature against its installation'sWHATSAPP_APP_SECRETalone. That is empty on a standard install, so every delivery gets 401. - The secret differs. The inbox's
app_secretmust match the secret that signed the delivery byte for byte. Trailing whitespace counts. After you generate a new secret, every inbox needs the new one.
WHATSAPP_APP_SECRET in the environment does not help. Chatwoot reads that value from its installation config, which db:chatwoot_prepare creates empty on a standard install, so the environment value is never used. You can remove the variable.
How to fix it
- Open the failed delivery in ZapClaw's Logs: it shows the status and the raw response Chatwoot returned. A 401 with Empty response body comes from this signature check.
-
Fix the inbox through Chatwoot's API. A number with no inbox yet gets one from the command the ZapClaw dashboard shows for it. For an existing inbox, send the whole
provider_config,app_secretandsource: manual_setup_v2included: Chatwoot replaces the object instead of merging it, and a partial one is refused with Provider config Invalid Credentials. If the phone number is wrong too, addphone_numbertochannelin the same call.curl -X PATCH "https://chatwoot.your-domain.com/api/v1/accounts/<ACCOUNT_ID>/inboxes/<INBOX_ID>" \ -H "api_access_token: <CHATWOOT_ACCESS_TOKEN>" \ -H "Content-Type: application/json" \ -d '{ "channel": { "provider_config": { "api_key": "zc_live_xxx", "phone_number_id": "<PHONE_NUMBER_ID>", "business_account_id": "<WABA_ID>", "source": "manual_setup_v2", "app_secret": "<CHATWOOT_SIGNING_SECRET>" } } }'app_secretis the Signing secret of the Chatwoot section in ZapClaw. The inbox ID is the number after/settings/inboxes/when you open the inbox's settings. The Rails console works too: see the guide. - Press Send test event in ZapClaw's Chatwoot section. A success means Chatwoot found the inbox and accepted the signature. The test goes to your first connected number, so that number needs an inbox too. Then resend the failed deliveries from Logs.
Straight from Meta, without ZapClaw
- The check is the same, and the secret is your Meta app's App Secret, which Meta signs every delivery with. An inbox from Chatwoot's Embedded Signup is checked against the
WHATSAPP_APP_SECRETsaved in Chatwoot's Super Admin: after you reset the App Secret at Meta, update it there, not on the inbox. Any other inbox is checked only if it has anapp_secret, which must then be the App Secret. - A 401 while you save the Callback URL and Verify token in Meta's App Dashboard comes from another check, the token. The URL is your Chatwoot address, then
/webhooks/whatsapp/and the inbox's phone number with its+. The token is the Webhook Verification Token on the inbox's Configuration tab in Chatwoot.
A 404, Invalid OAuth access token and replies that never leave Chatwoot have their own fixes in the Chatwoot troubleshooting.
Self-hosted Chatwoot on the official WhatsApp API
ZapClaw connects your number through Coexistence, so it keeps working in the WhatsApp Business app, and Chatwoot's own WhatsApp Cloud channel talks to ZapClaw instead of Meta. You need no Meta app of your own and no App Review.
The dashboard shows each number's inbox command with the number's details filled in, and Logs keeps every delivery with Chatwoot's answer, ready to resend.
Start for free Why run Chatwoot on ZapClaw