What chat does today
WhatsApp inbound
Customers message your business’s WhatsApp number. Our WhatsApp provider forwards the message to
our webhook receiver; the worker queues it; the agent replies through the same dispatch path
voice uses.
Cross-channel context
A customer who called and now WhatsApps continues the same conversation.
customers.phone is
the identity anchor; conversations are looked up by (tenant, channel, customer_identifier)
with phone-number normalization across wa_id and E.164 forms.Bilingual (Arabic + English)
Same prompt-driven language detection as voice. The agent responds in the language the customer
used on the latest turn.
Operator inbox reply
Your team can take over a thread from
app.vorel.ai/inbox; the agent stops auto-replying once
a human reply is sent on that conversation. Re-enable auto-reply via the inbox toggle.Webhook events
Subscribe to
lead.created, lead.qualified, conversation.created,
conversation.handoff_requested, conversation.closed: fire-on-state-change for your own
integrations. Bodies are HMAC-SHA256 signed. Six-attempt retry ladder.Dashboard send
The dashboard reply path uses the same
send_whatsapp_message tool; your operator’s reply is
persisted into messages and lands in the conversation transcript.What’s paused
WhatsApp outbound network send is being finalized as Meta Business Manager verification clears
per tenant. The
send_whatsapp_message tool persists the agent reply to the conversation
transcript and writes the outbox row; the network send to your WhatsApp provider activates
per-tenant once verification is through. Inbound messages flow normally; the dashboard inbox shows
everything.How a chat turn flows
runChatDispatch / runVoiceDispatch shape internally; only the ingress and the terminal differ. See How it works for the full picture.
Tool whitelist by sub-agent (chat)
| Sub-agent | Tools |
|---|---|
qualification | search_offerings · update_lead · crm_lookup_customer · crm_update_record · request_handoff |
booking | check_availability · book_appointment · update_lead · request_handoff |
handoff | request_handoff |
faq | get_faq_answer · search_offerings · crm_lookup_customer · request_handoff |
crm_update_record for a tenant whose CRM is read-only, etc.
Channel-aware reply formatting
Chat replies use a different output style than voice. The channel-rules block appended to every chat sub-agent prompt allows:- Up to four sentences per turn (vs. voice’s two-sentence cap).
- Bullet / numbered lists when listing options or steps.
- Numerals are readable (
AED 1,200,000, no need to spell out). - Emojis sparingly OK for warmth (one per message at most; never as decoration).
- Links are fine when relevant; the customer can tap them.
Anti-spam posture
Inbound abuse is gated at three layers:- Per-IP webhook limit (500 req/min): applied before signature verification, so a flood from a single IP doesn’t compromise the verification path’s cost.
- HMAC signature verification: the WhatsApp provider signs every webhook with a shared secret; we reject on signature mismatch with a 401 and a
webhook.signature_invalidlog line. - Per-(tenant, customer phone) limit (30 events/min): applied after parse, so a single compromised customer number can’t burn through the tenant’s quota or generate bot work.
customer_rate_limited flag.
Webhooks emitted on chat events
Subscribe at/(dashboard)/settings/integrations/webhooks. Chat-relevant events:
| Event | When |
|---|---|
conversation.created | First inbound from a new (tenant, customer) pair |
lead.created | Qualification sub-agent created the lead |
lead.updated | Slot changes via update_lead |
lead.qualified | Lead status moved off 'new' |
conversation.handoff_requested | Handoff sub-agent fired or request_handoff tool ran |
conversation.closed | Inbox closed by an operator action |
{id, event, created_at, tenant_id, data}; id doubles as the consumer’s idempotency key. HMAC-SHA256 signature in X-Webhook-Signature. Retry ladder: [60s, 300s, 1800s, 7200s, 43200s] with a 6-attempt cap; failures past 6 attempts raise a tenant-admin alert and land in webhook_deliveries.status='dead_letter'.
What’s NOT supported on chat today
- Outbound network send to WhatsApp: paused per the note above.
- Outbound proactive messaging (campaigns): depends on Phase 4b; even after that lands, outbound campaigns are scoped to opted-in customers per Meta policy.
- Other messaging channels (Telegram, Instagram DM, SMS): WhatsApp only today.
Per-tenant configuration that matters for chat
Set via the operator console, no code deploy:- Persona: agent name, tone, signature phrases, forbidden phrases (Arabic + English).
- Working hours + holidays: rejects outside-hours inbound at the agent layer with a per-vertical “we’re back at” message; falls through to a human if your handoff rules say so.
- Vertical pack: drives the qualification slots, FAQ redirect copy, handoff triggers (see Verticals).
- Tool whitelist: disable
crm_update_record(read-only CRM),book_appointment(no online booking yet), etc. - Guardrails: hallucination threshold + action; forbidden-phrase action. See Guardrails.
Related docs
- How it works: full architecture
- Voice features: voice side of the same agent
- Verticals: per-vertical qualification + handoff defaults
- Guardrails: per-tenant safety policy
- API Reference: webhook subscription, conversation send