Channels
Channels let one agent talk to customers outside the web widget. Use them when the customer starts in a messaging app, but you still want Kravos.ai to create...
Channels
Channels let one agent talk to customers outside the web widget. Use them when the customer starts in a messaging app, but you still want Kravos.ai to create the end user, store the conversation, run the agent, and show the thread in the dashboard.
What is implemented now
Meta-based inbound channels for WhatsApp and Messenger are implemented. The existing web text and web voice channels are also supported. Slack, email inbox, and outbound customer webhook subscriptions are currently unavailable.
How Channel Messages Flow
- Meta sends a signed webhook to the web app domain.
- Kravos.ai verifies the provider signature against the raw request body.
- The handler normalizes provider-specific payloads into one inbound message shape.
- The handler deduplicates the provider message ID in Redis for 24 hours.
- A
channel-inboundBullMQ job creates or updates the end user, conversation, and message. - If the conversation is
AI_ACTIVE, the worker calls the agent runtime. - Any AI reply is queued as
channel-outboundand sent back through Meta Graph API.
Supported Channel Behavior
| Channel | Inbound support | Outbound support | Notes |
|---|---|---|---|
| Text plus image/audio/file placeholders | Text plus media URLs from agent replies | Media download from inbound WhatsApp messages is currently unavailable. | |
| Messenger | Text plus attachment placeholders | Text plus image/video/file attachments | Messenger echo events can pause AI when the Page replies manually. |
| Web text | Existing widget/chat flow | Existing widget/chat flow | Not configured through Meta webhooks. |
| Web voice | Existing voice session flow | Existing voice session flow | Uses the ElevenLabs webhook path, not the Meta channel path. |
Configuration Sources
Channel setup uses two kinds of configuration.
Deployment environment variables
These are used by the implemented Meta webhook handlers and outbound sender:
| Variable | Used for |
|---|---|
PUBLIC_APP_URL or NEXTAUTH_URL | Builds the webhook URLs shown by channel settings. |
META_VERIFY_TOKEN | Verifies Meta's hub.verify_token challenge request. |
META_APP_SECRET | Verifies x-hub-signature-256 on Meta POST requests. |
META_WHATSAPP_ACCESS_TOKEN or META_ACCESS_TOKEN | Sends WhatsApp replies. |
META_MESSENGER_ACCESS_TOKEN or META_ACCESS_TOKEN | Sends Messenger replies and fetches Messenger profile metadata. |
META_PHONE_NUMBER_ID | Sends WhatsApp replies through the configured phone number. |
META_PAGE_ID | Sends Messenger replies through the configured Page. |
RUNTIME_URL and RUNTIME_SERVICE_TOKEN | Let the inbound worker call the agent runtime for AI replies. |
Tenant channel config rows
ChannelConfig rows store tenant-level channel metadata:
channelisActive- encrypted
credentials - JSON
settings - optional
webhookUrl
Credentials are encrypted and write-only. Platform MCP tools can list channel metadata and update or create channel configs without returning the encrypted credentials.
Current routing detail
The implemented Meta sender reads tokens from environment variables. ChannelConfig rows are currently used for
tenant routing fallback, not for reading Meta access tokens at send time.
How Inbound Routing Works
Kravos.ai tries to route each incoming WhatsApp or Messenger message in this order:
- Find the latest existing conversation for the same external user ID and channel.
- If no conversation exists, find an active
ChannelConfigfor that channel. - If exactly one tenant has an active config, use that tenant's oldest active agent.
- If no config exists, no active agent exists, or multiple tenants are active for the same channel, return
503.
For multi-tenant deployments using one shared Meta app, avoid ambiguous first-message routing. Use separate provider apps per tenant, or keep only one active ChannelConfig per channel for first-contact fallback.
Channel Settings Status
The authenticated endpoint GET /api/settings/channels reports deployment readiness for WhatsApp and Messenger.
It returns:
- the app URL being used
- the WhatsApp webhook URL
- the Messenger webhook URL
- booleans for each required environment variable
configured: trueonly when every requirement for that channel is present
This status endpoint is read-only. It does not create Meta apps, create ChannelConfig rows, or save access tokens.
Testing Channels
Start with a provider challenge test, then test a real message.
- Confirm
/api/settings/channelsshows a webhook URL and all required booleans aretrue. - In Meta, verify the webhook URL with the same
META_VERIFY_TOKENconfigured in Kravos.ai. - Send a real WhatsApp or Messenger test message.
- Confirm the webhook response is
200and the response body hasdata.received: true. - Confirm the worker is running so
channel-inboundandchannel-outboundjobs are processed. - Open the conversation in the dashboard and verify the end user identity and messages.
Reliability And Duplicates
- Meta inbound messages are deduplicated for 24 hours with
dedupe:{channel}:{providerMessageId}. - Inbound messages also use a database uniqueness check on
conversationIdandchannelMessageId. - Outbound channel messages use a 7-day Redis dedupe key before persisting the provider message ID.
channel-inboundjobs retry 5 times with exponential backoff starting at 2 seconds.channel-outboundjobs retry 3 times with exponential backoff starting at 2 seconds.- There is no separate dead-letter queue. Failed jobs are retained in BullMQ up to the configured failed-job retention count.
Related Docs
WhatsApp Setup
Configure Meta WhatsApp Cloud API webhooks and outbound replies.
Messenger Setup
Configure Facebook Messenger webhooks, Page replies, and echo handling.
Incoming Webhooks
Review webhook verification, dedupe, retries, and troubleshooting.


