Webhooks
Webhooks allow third-party services (Twilio, Meta, Africa's Talking, Telegram) to push events to Tavio in real time. Each channel has a dedicated webhook endpoint.
How Webhooks Work
- You register your Tavio webhook URL in the third-party provider's dashboard
- When an event occurs (e.g., a customer sends a message), the provider sends an HTTP POST to your webhook URL
- Tavio verifies the request signature to ensure it came from the legitimate provider
- The message is processed through the AI pipeline and a response is sent back via the provider's API
Webhook Endpoints
| Channel | Endpoint |
|---|---|
| /api/channels/whatsapp | |
| SMS | /api/channels/sms |
| USSD | /api/channels/ussd |
| Twitter / X | /api/channels/twitter |
| Voice (Twilio) | /api/v1/voice/inbound |
| Voice Status | /api/v1/voice/status |
| Telegram | /api/v1/channels/telegram/webhook |
| Messenger & Instagram | /api/v1/channels/meta/webhook |
Signature Verification
Every webhook request is verified before processing. The verification method depends on the provider:
| Provider | Method |
|---|---|
| Meta (WhatsApp, Messenger, Instagram) | HMAC-SHA256 |
| Twilio (Voice, SMS) | HMAC-SHA1 URL signature |
| Telegram | Secret token comparison |
| Africa's Talking | API key validation |
Meta signature verification example
typescript
import crypto from "crypto";
function verifyMetaSignature(
payload: string,
signature: string,
appSecret: string
): boolean {
const expected = crypto
.createHmac("sha256", appSecret)
.update(payload)
.digest("hex");
return signature === `sha256=${expected}`;
}Retry Policy
Tavio responds to webhooks as quickly as possible (typically under 200ms for the initial acknowledgment). If your Tavio instance is unavailable, the provider's retry behavior applies:
| Provider | Retry Behavior |
|---|---|
| Meta | Retries for up to 7 days with exponential backoff |
| Twilio | Retries once after 10 seconds, then marks as failed |
| Telegram | Retries with increasing intervals, stops after repeated failures |
| Africa's Talking | No automatic retries |
Payload Format
Each provider sends payloads in their own format. Tavio's channel adapters normalize these into a unified internal message format:
Normalized internal message
json
{
"channel": "whatsapp",
"senderId": "+254712345678",
"message": "What is my balance?",
"messageId": "wamid.abc123",
"timestamp": "2024-01-15T10:30:00Z",
"metadata": {
"phoneNumberId": "123456",
"profileName": "John Doe"
}
}Event Types
Tavio processes the following webhook event types:
| Event | Description |
|---|---|
| message.received | New inbound message from a customer |
| message.delivered | Outbound message confirmed delivered |
| message.read | Outbound message marked as read |
| call.started | Voice call initiated |
| call.completed | Voice call ended |
| ussd.session_start | New USSD session opened |
| ussd.session_end | USSD session terminated |