v1.0 Dashboard Public Profile GitHub
Global Provider Voice + SMS + WhatsApp

Twilio Setup Guide

Twilio is the global telephony provider for KaiVox — handling voice calls, inbound SMS, and WhatsApp messages for non-Indian numbers. Configuration is platform-level: one set of credentials handles all tenants.

Architecture note: Twilio credentials are set in .env at the platform level. Individual tenants are identified by their {slug} in the webhook URL — not by separate Twilio accounts. One Twilio account, many tenants.

Environment Variables

KeyWhere to FindRequired
TWILIO_ACCOUNT_SIDTwilio Console → Account Info (starts with AC…)✅ Yes
TWILIO_AUTH_TOKENTwilio Console → Account Info✅ Yes
TWILIO_FROM_NUMBERTwilio Console → Phone Numbers → your purchased number✅ Yes (for outbound SMS/WhatsApp)
.env example
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token_here
TWILIO_FROM_NUMBER=+12025551234

Webhook URLs

Configure these URLs in the Twilio Console under your phone number settings. Replace {slug} with the tenant's slug.

WebhookMethodURL
Voice — Answer POST https://kaivoxai.com/api/twilio/{slug}/answer
Voice — Gather (Input) POST https://kaivoxai.com/api/twilio/{slug}/gather
Voice — Status Callback POST https://kaivoxai.com/api/twilio/{slug}/status
Inbound SMS POST https://kaivoxai.com/api/twilio/{slug}/sms
Inbound WhatsApp POST https://kaivoxai.com/api/twilio/{slug}/whatsapp
All webhook endpoints are CSRF-exempt. Twilio does not send CSRF tokens. The routes are registered under routes/api.php which bypasses CSRF middleware automatically.

Voice Call Setup

  1. Purchase a Twilio phone number In the Twilio Console, go to Phone Numbers → Manage → Buy a Number. Choose a country and number type. You can also use KaiVox's built-in DID Marketplace (Phase 16) which purchases and configures Twilio numbers automatically.
  2. Configure the Voice webhook In Twilio Console → Phone Numbers → click your number. Under "Voice & Fax", set:
    • A Call Comes In: Webhook → POST https://kaivoxai.com/api/twilio/{slug}/answer
    • Call Status Changes: POST https://kaivoxai.com/api/twilio/{slug}/status
  3. Save and test Call the Twilio number. KaiVox AI should answer with the tenant's greeting.

SMS Inbound Webhook Setup

  1. Open phone number settings in Twilio Console Navigate to Phone Numbers → your number.
  2. Set the Messaging webhook Under "Messaging", set:
    • A Message Comes In: Webhook → POST https://kaivoxai.com/api/twilio/{slug}/sms
  3. Verify in KaiVox Send an SMS to the number. It should appear in the tenant's unified inbox under Messages.

WhatsApp Inbound Webhook Setup

Twilio WhatsApp requires either a Twilio Sandbox (for testing) or an approved WhatsApp Business Account (for production). The sandbox is free and ready to use immediately.
  1. Enable Twilio WhatsApp Sandbox In Twilio Console, go to Messaging → Try it out → Send a WhatsApp message. Follow the instructions to join the sandbox from your WhatsApp.
  2. Set the sandbox webhook In the sandbox settings, set:
    • When a message comes in: POST https://kaivoxai.com/api/twilio/{slug}/whatsapp
  3. Production WhatsApp Apply for a WhatsApp Business Account in Twilio. Once approved, configure the same webhook URL on your approved WhatsApp number.

What KaiVox Does With Inbound SMS/WhatsApp

When an inbound message arrives:

  1. The tenant is resolved from the {slug} in the URL
  2. The sender's phone number is looked up in the customers table — created if new
  3. The message is stored in the messages table with channel = sms or channel = whatsapp
  4. The inbound_sms or inbound_whatsapp automation trigger fires — any matching rules execute
  5. The message appears in the tenant's unified inbox at Messages in the sidebar

Outbound SMS — SmsService

KaiVox sends outbound SMS via App\Services\SmsService which wraps the Twilio SDK. Used for:

  • Appointment booking confirmations
  • 24-hour appointment reminders
  • Missed-call follow-up messages
  • Review request messages
  • Manual SMS from the CRM (Customers page)
  • Automation rule actions (send_sms)
How SmsService sends a message
// From any controller or service:
app(SmsService::class)->send(
    tenant: $tenant,
    to: '+919876543210',
    message: 'Your appointment is confirmed for 2pm tomorrow.'
);

Outbound WhatsApp — WhatsAppService

App\Services\WhatsAppService works identically to SmsService but prefixes the to-number with whatsapp: for Twilio routing. The TWILIO_FROM_NUMBER must be a WhatsApp-enabled number.

Call Flow (Twilio)

Caller dials Twilio number
        ↓
Twilio POST → /api/twilio/{slug}/answer
        ↓
KaiVox returns TwiML — <Gather> with <Say> greeting
        ↓
Caller speaks
        ↓
Twilio POST → /api/twilio/{slug}/gather  (with SpeechResult)
        ↓
KaiVox: sends to OpenAI → gets response → returns TwiML with <Say>
        ↓
[Continues until hangup]
        ↓
Twilio POST → /api/twilio/{slug}/status  (CallStatus=completed)
        ↓
KaiVox: saves call log, runs sentiment, triggers automations

Troubleshooting Twilio

ProblemLikely CauseFix
Call goes to voicemailWebhook URL not set or wrongCheck Twilio Console → Phone Number → Voice webhook URL
SMS not received in inboxMessaging webhook not configuredSet Messaging webhook URL in Twilio Console
WhatsApp message not receivedSandbox join not completedAsk sender to join sandbox first (send "join <code>" to Twilio sandbox number)
Outbound SMS failsInvalid TWILIO_FROM_NUMBEREnsure number is in E.164 format: +12025551234
401 Unauthorized in logsWrong TWILIO_AUTH_TOKENCopy token fresh from Twilio Console — it may have rotated