WhatsApp Setup
WhatsApp setup connects Meta WhatsApp Cloud API to one Kravos.ai deployment. Meta delivers customer messages to Kravos.ai, and Kravos.ai sends AI or human re...
WhatsApp Setup
WhatsApp setup connects Meta WhatsApp Cloud API to one Kravos.ai deployment. Meta delivers customer messages to Kravos.ai, and Kravos.ai sends AI or human replies through the configured WhatsApp phone number.
External setup is still required
Kravos.ai does not create your Meta app, Business portfolio, WhatsApp Business Account, phone number, webhook subscription, or access token. Create and approve those in Meta, then point them at the implemented Kravos.ai webhook.
Required Kravos.ai Configuration
| Variable | Required for | Notes |
|---|---|---|
PUBLIC_APP_URL or NEXTAUTH_URL | Webhook URL display | Use the public HTTPS web app origin. |
META_VERIFY_TOKEN | Meta challenge verification | Must match the token entered in Meta's webhook setup. |
META_APP_SECRET | POST signature verification | Used to verify x-hub-signature-256. |
META_WHATSAPP_ACCESS_TOKEN | WhatsApp outbound replies | Preferred channel-specific token. |
META_ACCESS_TOKEN | WhatsApp outbound replies | Fallback when the channel-specific token is not set. |
META_PHONE_NUMBER_ID | WhatsApp outbound replies | Used in the Graph API /messages URL. |
RUNTIME_URL and RUNTIME_SERVICE_TOKEN | AI replies | Without these, inbound messages are stored but AI generation is skipped. |
The channel settings status endpoint reports this readiness at GET /api/settings/channels.
Meta Setup Checklist
- Create or choose your Meta app and add WhatsApp.
- Connect the WhatsApp Business Account and phone number you want Kravos.ai to send from.
- Create an access token that can send WhatsApp messages for that phone number.
- Set
META_PHONE_NUMBER_IDto the phone number ID, not the display phone number. - Set the callback URL to:
https://your-web-app.example.com/api/webhooks/whatsapp
- Enter the same verify token that you configured as
META_VERIFY_TOKEN. - Subscribe the webhook to WhatsApp message events.
- Create or activate a tenant
ChannelConfigforWHATSAPPwhen you need first-message fallback routing.
What The WhatsApp Webhook Accepts
Challenge request
Meta verifies the URL with a GET request that includes:
| Query parameter | Required value |
|---|---|
hub.mode | subscribe |
hub.verify_token | Must equal META_VERIFY_TOKEN |
hub.challenge | Any non-empty challenge string |
When the token matches, Kravos.ai returns the raw challenge text with status 200. Invalid tokens return 403. Missing META_VERIFY_TOKEN returns 503.
Message delivery request
Meta delivers messages with POST /api/webhooks/whatsapp.
Implemented behavior:
- reads the raw request body before parsing JSON
- verifies
x-hub-signature-256with HMAC SHA-256 andMETA_APP_SECRET - returns
401for missing or invalid signatures - returns
400for invalid JSON - extracts messages from
entry[].changes[].value.messages[] - extracts the business phone number ID from
value.metadata.phone_number_id - extracts sender name and phone from
value.contacts[]when available - ignores payloads that do not contain complete message records
- deduplicates provider message IDs for 24 hours
- enqueues
channel.inboundjobs for new messages
Message Support
| Direction | Supported now |
|---|---|
| Inbound text | Stored and passed to the agent runtime. |
| Inbound image/audio/document | Stored as [Image received], [Audio received], or [File received]; media download is not implemented. |
| Outbound text | Sent through WhatsApp Cloud API as a text message. |
| Outbound image/video/audio/document | Sent when the agent reply includes a public mediaUrl. |
Testing WhatsApp
Use Meta's webhook verification first. Then send a test message from a WhatsApp user to the configured business phone number.
A successful POST returns:
{
"data": {
"received": true,
"deduped": false,
"dedupedCount": 0,
"enqueued": 1
}
}
If you resend the same provider message ID within 24 hours, deduped becomes true and no new job is queued.
Troubleshooting
Meta cannot verify the webhook
- Confirm the public URL is HTTPS and points to
/api/webhooks/whatsapp. - Confirm
META_VERIFY_TOKENexactly matches the token entered in Meta. - Confirm the deployment has
PUBLIC_APP_URLorNEXTAUTH_URLset for display, but use the actual public URL in Meta.
POST returns 401
- Confirm
META_APP_SECRETis the app secret for the same Meta app sending the webhook. - Do not reserialize JSON before checking signatures. The implemented handler verifies the raw request body.
POST returns 503
- Check for missing
META_APP_SECRET. - Confirm there is an active
ChannelConfigforWHATSAPPif this is a first-time user. - In multi-tenant deployments, confirm first-message routing is not ambiguous across multiple tenants.
The message is stored but no AI reply is sent
- Confirm the worker process is running.
- Confirm
RUNTIME_URLandRUNTIME_SERVICE_TOKENare set for the worker. - Confirm the conversation status is
AI_ACTIVE. - Confirm
META_WHATSAPP_ACCESS_TOKENorMETA_ACCESS_TOKENandMETA_PHONE_NUMBER_IDare set for outbound sending.
Related Docs
Channels
Understand channel routing, queues, dedupe, and supported message types.
Incoming Webhooks
Review webhook verification, replay safety, retries, and failures.


