Skip to main content

Senders

A Sender is a messaging profile that represents “who” is sending the message. Senders can be configured with multiple channels (SMS, WhatsApp, Email) and Zavu intelligently routes messages through them.

What is a Sender?

Think of a sender as your messaging identity. It contains:
  • Phone number: For SMS and WhatsApp
  • Email address: For email channel
  • WhatsApp Business Account: For WhatsApp messaging
  • Allowed destinations: Countries you can send to
{
  "id": "sender_12345",
  "name": "Primary Sender",
  "phoneNumber": "+13125551212",
  "isDefault": true,
  "channels": {
    "sms": true,
    "whatsapp": true,
    "email": true
  },
  "webhook": {
    "url": "https://your-app.com/webhooks",
    "events": ["message.inbound", "message.delivered"],
    "active": true
  }
}

Default Sender

Every project has a default sender. When you send a message without specifying a sender, Zavu uses the default.
# Uses default sender automatically
curl -X POST https://api.zavu.dev/v1/messages \
  -H "Authorization: Bearer zv_live_xxx" \
  -d '{"to": "+14155551234", "text": "Hello!"}'
To use a specific sender, include the Zavu-Sender header:
curl -X POST https://api.zavu.dev/v1/messages \
  -H "Authorization: Bearer zv_live_xxx" \
  -H "Zavu-Sender: sender_67890" \
  -d '{"to": "+14155551234", "text": "Hello!"}'

Smart Routing

Zavu’s smart routing system automatically selects the optimal channel for each message based on cost, deliverability, and contact history.
Smart routing only applies to outbound messages. When replying to an inbound message, Zavu always responds on the same channel the contact used.

When Smart Routing Applies

Message TypeRouting Behavior
Outbound (you initiate)Smart routing selects optimal channel
Inbound reply (direct response)Always use the contact’s channel

How It Works

For outbound messages, the router checks if the contact has previously messaged you. If they have, this affects channel availability:
Has contact messaged via WhatsApp in last 24h?
      |
   +--+--+
   |     |
  Yes   No
   |     |
   v     v
WhatsApp    WhatsApp only
available   with template
(preferred)
Since WhatsApp is cheaper than SMS, the router prefers WhatsApp when the 24-hour window is open. This means contacts who have messaged you before will typically receive messages via WhatsApp.

Channel Selection Algorithm

The router evaluates channels in this order:
  1. Filter viable channels: Remove channels that can’t deliver (e.g., WhatsApp without open window)
  2. Sort by cost: Cheapest channels first
  3. Check success rate: Channel must have at least 80% success rate (or fewer than 3 attempts for exploration)
  4. Select best option: First channel meeting all criteria

Cost Optimization

ChannelApproximate Cost
WhatsApp~$0.01/message
SMS~$0.05/message
Smart routing can reduce messaging costs by up to 80% by preferring WhatsApp when available.

WhatsApp 24-Hour Window

WhatsApp has a strict rule: you can only send free-form messages within 24 hours of the last message received from the contact.
Contact sends message ... 24-hour window opens
      |
Within 24h: Send any message type
      |
After 24h: Only template messages allowed
If the 24-hour window is closed and you don’t have a template configured, the smart router will automatically select SMS instead of failing.

Channel Metrics

Zavu tracks delivery metrics for each contact and channel:
{
  "channelMetrics": {
    "sms": {
      "successCount": 45,
      "failureCount": 2,
      "avgDeliveryTimeMs": 3200,
      "lastSuccessAt": "2025-01-15T10:30:00Z"
    },
    "whatsapp": {
      "successCount": 120,
      "failureCount": 1,
      "avgDeliveryTimeMs": 1100,
      "lastSuccessAt": "2025-01-15T14:22:00Z"
    }
  }
}
The router uses these metrics to:
  • Avoid channels with low success rates (below 80%)
  • Prefer faster channels when speed matters
  • Explore new channels (first 3 attempts get a chance regardless of stats)

Automatic Fallback

When a message fails on one channel, Zavu automatically retries on an alternate channel.

Fallback Flow

Send via WhatsApp
      |
      v
  Failed?
      |
   +--+--+
   |     |
  No    Yes
   |     |
   v     v
Done   Wait 5s
         |
         v
   Retry via SMS
         |
         v
     Success?
         |
      +--+--+
      |     |
     Yes   No
      |     |
      v     v
   Done   Mark Failed

Fallback Rules

RuleDescription
Max 2 attemptsEach message is tried on at most 2 channels
5-second delayWait 5 seconds before retry to avoid race conditions
No duplicate channelsNever retry on a channel that already failed
Sender must support bothFallback only works if sender has both channels configured

Enabling/Disabling Fallback

Fallback is enabled by default. Messages track which channels have been attempted:
{
  "id": "msg_abc123",
  "status": "delivered",
  "channel": "sms",
  "attemptedChannels": ["whatsapp", "sms"],
  "fallbackEnabled": true
}
In this example, the message first tried WhatsApp, failed, and was successfully delivered via SMS.

Rate Limiting

Zavu implements fair rate limiting to ensure reliable delivery for all users.

Limits by Channel

ChannelRate LimitLevel
SMS10 messages/secondGlobal
Email14 messages/secondGlobal
WhatsApp60 messages/secondPer WABA

Round-Robin Fairness

When multiple projects are sending messages, Zavu uses round-robin scheduling to ensure fairness:
Without round-robin:
Project A: 10 messages = A1, A2, A3... A10 (1 second)
Project B: 1 message  = B1 waits 1 second

With round-robin:
A1 (0ms), B1 (100ms), A2 (200ms), A3 (300ms)...
B1 only waits 100ms instead of 1 second
This prevents high-volume senders from blocking smaller senders.
Messages are never dropped due to rate limiting. They’re queued and sent at the next available slot.

Email Channel

Email works differently from SMS and WhatsApp. It’s a separate channel that must be explicitly selected and does not participate in smart routing or automatic fallback.

Key Differences

FeatureEmailSMS / WhatsApp
Smart RoutingNo - must specify channel: "email"Yes - auto-selected
Automatic FallbackNoYes (SMS / WhatsApp)
Recipient TypeEmail addressPhone number (E.164)
Delivery TrackingNo webhooksYes - status updates
Setup RequiredDomain verification (DKIM)Phone number

Why Email is Separate

Email addresses and phone numbers are fundamentally different identifiers. A contact might have both, but they represent different communication preferences. Smart routing between email and SMS/WhatsApp doesn’t make sense because:
  • Recipients are different (email vs phone)
  • User expectations differ (email is async, SMS/WhatsApp is immediate)
  • Delivery semantics differ (no read receipts, different spam handling)

Sending Email

To send an email, explicitly set channel: "email" and provide a subject:
await zavu.messages.send({
  to: "user@example.com",
  channel: "email",
  subject: "Your order has shipped",
  text: "Hi John, your order #12345 has shipped!"
});

HTML Emails

You can send rich HTML emails by including htmlBody:
curl -X POST https://api.zavu.dev/v1/messages \
  -H "Authorization: Bearer zv_live_xxx" \
  -d '{
    "to": "user@example.com",
    "channel": "email",
    "subject": "Welcome to Zavu",
    "text": "Welcome to Zavu! We are excited to have you.",
    "htmlBody": "<h1>Welcome to Zavu!</h1><p>We are excited to have you.</p>",
    "replyTo": "support@yourcompany.com"
  }'

Email Requirements

FieldRequiredDescription
toYesValid email address
channelYesMust be "email"
subjectYesEmail subject line (max 998 chars)
textYesPlain text body
htmlBodyNoOptional HTML version
replyToNoReply-To address

Domain Verification

Before sending emails, your sender must have a verified domain. This involves:
  1. Adding your domain in the Zavu dashboard
  2. Adding DKIM records to your DNS
  3. Waiting for verification (usually minutes)
This ensures emails are delivered and not marked as spam.
Emails sent without proper domain verification may be rejected or land in spam folders.

Managing Senders

List Senders

curl https://api.zavu.dev/v1/senders \
  -H "Authorization: Bearer zv_live_xxx"

Create Sender

curl -X POST https://api.zavu.dev/v1/senders \
  -H "Authorization: Bearer zv_live_xxx" \
  -d '{
    "name": "Marketing Sender",
    "phoneNumber": "+13125559999",
    "setAsDefault": false
  }'

Update Sender

curl -X PATCH https://api.zavu.dev/v1/senders/sender_12345 \
  -H "Authorization: Bearer zv_live_xxx" \
  -d '{
    "name": "Updated Name",
    "setAsDefault": true
  }'

Webhook Configuration

Each sender can have one webhook configured to receive real-time notifications for events like incoming messages and delivery updates.

Create Sender with Webhook

curl -X POST https://api.zavu.dev/v1/senders \
  -H "Authorization: Bearer zv_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support",
    "phoneNumber": "+15551234567",
    "webhookUrl": "https://your-app.com/webhooks",
    "webhookEvents": ["message.inbound", "message.delivered", "message.failed"]
  }'
The response includes the webhook secret (only shown once):
{
  "id": "sender_12345",
  "name": "Support",
  "webhook": {
    "url": "https://your-app.com/webhooks",
    "events": ["message.inbound", "message.delivered", "message.failed"],
    "secret": "whsec_abc123...",
    "active": true
  }
}

Update Webhook

curl -X PATCH https://api.zavu.dev/v1/senders/sender_12345 \
  -H "Authorization: Bearer zv_live_xxx" \
  -d '{
    "webhookUrl": "https://new-url.com/webhooks",
    "webhookEvents": ["message.inbound"],
    "webhookActive": false
  }'

Regenerate Webhook Secret

If your webhook secret is compromised:
curl -X POST https://api.zavu.dev/v1/senders/sender_12345/webhook/secret \
  -H "Authorization: Bearer zv_live_xxx"

Available Webhook Events

EventDescription
message.inboundCustomer sent you a message
message.sentYour message was sent to the carrier
message.deliveredYour message was delivered
message.failedMessage delivery failed
conversation.newFirst message from a new contact
For more details on webhook payloads and security, see the Webhooks guide.

Best Practices

Configure Multiple Channels

Set up both SMS and WhatsApp on your sender to enable automatic fallback.

Use Templates for Outreach

When initiating conversations, use WhatsApp templates to avoid 24-hour window issues.

Monitor Metrics

Check your contact metrics to understand channel performance in your region.

Set Allowed Destinations

Restrict senders to specific countries to control costs and compliance.

Next Steps