Fallback channels

Most outreach campaigns under-perform on a single channel. Saaya lets you cascade, try voice first, fall back to WhatsApp on no-answer, fall back to SMS as a last resort, and stitches the conversation together so the user does not start from scratch on each channel.

Declaring a cascade

cascade.ts
await saaya.campaigns.create({
  name:    "April reactivation",
  agentId: "agt_2N3rH...",
  source:  { type: "csv", uploadId: "upl_…" },
  channels: [
    { channel: "voice",    attempts: 2, retry: { afterMinutes: 60 } },
    { channel: "whatsapp", attempts: 1, gate: "voice.noAnswer" },
    { channel: "sms",      attempts: 1, gate: "whatsapp.unread", afterHours: 24 },
  ],
});

Retry policy

Each channel has its own retry config: number of attempts, minimum gap between attempts, and an exponential backoff (default 2x). Saaya respects per-region etiquette, never two voice calls inside an hour, no late-night WhatsApp, no SMS outside daylight.

Cross-channel context

When the same row escalates from voice to WhatsApp, the agent opens with a short recap ("Hi Anu, we just tried calling, here's the gist"). The full transcript travels with the session id so the agent can pick up mid-thought instead of restarting.

Compliance per channel

Each channel has its own opt-out list and quiet hours. Saaya merges them per contact: a "STOP" on SMS removes the row from all channels for that contact, not just SMS.

Inspecting a cascade

On the campaign view, every row carries a chip per attempted channel, green for connected, amber for in-progress, grey for skipped. Click a row to see every session, transcript, and the reason a channel was skipped.

Was this page helpful?