RylvoRylvo

Broadcasts

One composer, every channel.

Send the same campaign to WhatsApp templates, SMS, email, and in-app — with audience uploads, platform rate caps, and audit-grade history baked in. No platform-policy footguns.

One composer, every channel

Author once, dispatch to WhatsApp, SMS, Email, Slack, and 7 more channels. Platform rules are enforced at compose time, not after a failed batch.

Policy-safe by default

Cold-send rules, opt-in checks, template requirements, and rate caps are baked into the composer. The wrong batch is structurally impossible.

Auditable to the row

Every recipient writes a delivery doc with status, provider message ID, and skip reason. Every run writes a parent doc with channel-level stats.

How it works

Audience in. Messages out. Every rule enforced.

Recipients flow through consent checks, cold-send validation, and rate limiting before any channel connector fires. One pipeline diagram, one mental model.

Broadcast dispatch pipeline

audience → validate → dispatch → track

Consent check

opt-in · cold-send

Rate limit

token-bucket

Dispatch

provider API

The composer

Five steps from idea to send — no platform-policy footguns.

The composer encodes platform rules in the same matrix the cron runner enforces. You see the verdict at audience-pick time, not at delivery time. Single source of truth, single mental model.

Composer pipeline

audience → channels → content → schedule → review
01

Audience

02

Channels

03

Content

04

Schedule

05

Review

01

Audience

Pick where the recipient list comes from. Saved segments from the Audience Hub, an ad-hoc CSV / XLSX / paste upload, or every user who has ever chatted with the bot.

  • Saved segment with live count from the Audience Hub
  • CSV + XLSX upload — server-parsed via SheetJS
  • Paste-list of phones and emails, one per line
  • All past chatters of this bot (capped at 1,000 recent users)
  • Optional checkbox: also save uploaded contacts to my audience
02

Channels

Toggle the bot's enabled deployment channels. Each channel is annotated with the platform rule — incompatible combinations are disabled with a clear reason.

  • 11 channels supported, gated by per-channel rule matrix
  • Telegram, Web Widget, Discord blocked for cold-sends with explainer
  • WhatsApp surfaces the approved-template picker for uploaded audiences
  • SMS requires opt-in; Messenger / Instagram honor the 24h session window
  • Email + in-app always available, no channel config required
03

Content

Author the message body with token placeholders for per-recipient personalisation. Optional LLM enrichment rewrites the template using the bot's persona at send time.

  • {{user.displayName}}, {{user.email}}, {{bot.name}}, {{date}} placeholders
  • Per-row variables from your upload merge automatically
  • Toggle LLM enrichment with optional override prompt
  • Falls back to the literal template if the LLM call errors
04

Schedule

Send once or recur on a cadence. 'Send now' pins the run to the next 5-minute cron sweep. Per-channel rate caps protect you from tripping platform throttles.

  • One-time at a specific date/time, or recurring (hourly → monthly)
  • Send now preset — pinned to +60s for the next cron sweep
  • Per-broadcast rate-limit override (lower, never higher than platform cap)
  • Timezone resolved from the operator's browser at create-time
05

Review

Final preview with recipient counts per channel, effective rate caps, and cost / policy warnings — including the WhatsApp template billing reminder when relevant.

  • Per-channel recipient count from the resolved audience
  • Effective rate cap line per selected channel
  • WhatsApp template reference echoed back for confirmation
  • Activate one-time or recurring with a single button

Channels

11 channels, one rule matrix — enforced everywhere.

Every channel is annotated with its cold-send verdict and the platform-derived rate cap. UI gating and runner-time enforcement read from the same source so the two can't drift.

ChannelIdentifierCold-sendCap / minNote
EmailemailOpen send600Resend-backed, generic HTML wrapper
In-appuser idOpen send1,200Drops into dashboard inbox
WhatsAppphoneTemplate only4,800Meta-approved template required for cold-send
SMS (Twilio)phoneOpt-in required60Carrier policy: documented consent required
Messengerchannel id24h window120Template or 24-hour session window
Instagram DMchannel id24h window120Template or 24-hour session window
Slackchannel idWorkspace only60Bot must be in the workspace / channel
Microsoft Teamschannel idWorkspace only60Within the connected tenant
Telegramchannel idNo cold-send30Recipient must /start the bot first
Web Widgetsession idNo cold-send120Requires an active in-page session
Discordchannel idNo cold-send30Interaction model in progress

Safety rails

Designed to fail closed.

The fastest way to get an account suspended is one bad batch. Broadcasts make the wrong batch impossible by surfacing rules at the right step.

Channel-rule guard

Cold-send block-list with platform-derived reasons surfaced at audience selection time, not after a failed dispatch.

Per-channel rate caps

Token-bucket limiter respects the documented platform ceiling. Operators can lower per-broadcast, never raise above it.

Fail-closed semantics

Missing template, missing opt-in, or mismatched identifier kind writes a skipped delivery row — never a half-sent batch.

Consent honoured

Segments inherit consent scope from the Audience Hub; the dispatch endpoint re-validates compatibility per recipient.

Delivery tracking

Auditable down to the wamid.

Every recipient writes a delivery row. Every run writes a parent doc with channel stats. Every lifecycle event lands in the audit log.

Per-recipient rows

Every send writes a botBroadcastDeliveries doc: queued → sent / failed / skipped, with provider message IDs where available.

Run history

Each broadcast firing emits a run doc with per-channel stats (sent / failed / skipped) and a 50-row error sample for triage.

Audit log

broadcast.created, broadcast.scheduled, and broadcast.deleted events land in the org-wide audit log with actor metadata.

Provider IDs

Twilio SIDs and Meta wamid values are stored on delivery rows so you can correlate against provider dashboards.

Lifecycle

Every message, tracked from queue to inbox.

Each recipient progresses through four stages. Failures and skips branch off with a reason code so you can triage without guessing.

Delivery lifecycle

queued → validated → dispatched → delivered

Audience

Get recipients in — your way.

Four ways to pick who gets the broadcast. Uploads stay ephemeral by default, with a one-click opt-in to mirror them into your reusable Audience Hub.

Saved segments

Reusable filters from the Audience Hub. Live-resolved at send time so the count stays fresh.

CSV / XLSX upload

Server-parsed with SheetJS. Auto-detects identifier kind, deduplicates by row.

Paste-list

Drop phones and emails one per line. Comma, semicolon, and pipe separators welcome.

All past chatters

Every user who has ever messaged this bot, capped at the 1,000 most-recent.

Questions

Frequently asked.

What channels can I broadcast on?

11 channels: WhatsApp (approved templates), SMS via Twilio, Telegram, Slack, Discord, Microsoft Teams, Messenger, Instagram DM, Web Widget, Email, and In-app notifications. Each channel is annotated with platform cold-send rules — if a channel can't reach an audience without prior contact, the composer blocks it before you send.

How do I upload a recipient list?

Three ways: CSV, XLSX (parsed server-side via SheetJS), or paste a list of phones and emails one per line. The server classifies each row, deduplicates by identifier, and returns a preview with warnings before you commit.

Do I have to add uploaded recipients to my audience?

No. By default uploads are ephemeral — they live on the broadcast doc. Tick 'Also save these contacts to my audience' to mirror them into endUsers via the same idempotent CSV write path the Audience Hub uses.

How does WhatsApp cold-send work?

Meta requires an approved business template for outbound messages outside the 24-hour session window. Authoring lives in Meta Business Suite; Rylvo pulls the approved-template catalog into the composer's picker via the Meta Graph API and dispatches the chosen template through the WhatsApp Cloud API.

How are rate limits enforced?

Every channel has a platform-derived rate cap encoded as a token bucket in the cron runner. Operators can lower per-broadcast but never raise above the documented ceiling. This prevents a hot run from tripping Twilio QPS limits or Meta per-number throughput throttles.

Can I see per-recipient delivery status?

Yes. Every dispatched recipient writes a row in botBroadcastDeliveries with status (queued / sent / failed / skipped), the provider message ID where available (Twilio SID, Meta wa-id), and a short error or skip reason. The History view groups these by channel and status.

Does the broadcast feature respect consent?

Yes. Channel rules encode regulatory and platform policy — SMS requires opt-in, WhatsApp requires a template, Telegram and Web Widget require prior contact. Audience segments already filter by consent scope, and the dispatch endpoint re-validates compatibility per recipient before calling the connector.

Can I schedule recurring broadcasts?

Yes. Pick a cadence — hourly, daily, weekly, biweekly, or monthly — and the cron runner advances nextRunAt automatically. For one-off blasts pick a date/time, or click 'Send now' for an immediate dispatch (the runner sweeps every 5 minutes).

Ship your first broadcast in minutes.

Sign in, pick a bot, upload a list — Rylvo handles the rest. Platform rules, rate caps, and delivery tracking are on by default.