VibotSending campaignsSend a campaign

Send a campaign

A campaign in Vibot is a one-shot send of one approved WhatsApp template to a list of recipients. This page walks the full wizard top-to-bottom, calls out the safety checks at each step, and explains exactly what every preflight verdict means.

Template → Contacts → Review & Launch — the three-step wizard.

Before you start

Five preconditions. If any one is missing, the wizard will block at the relevant step.

  • Your WhatsApp number is Connected (green badge on the Connect page).
  • You have at least one APPROVED template (the Templates page). PENDING and REJECTED templates are filtered out of the picker.
  • Your account is on Lite plan or higher. Campaigns are not available on Free.
  • Your wallet has enough credits to cover the send at your plan’s per-template rate. See Pricing.
  • If this is your first send on the number, you’ve read Warm up a new number.

Step 0 — Open the wizard

Sidebar → Campaigns → top-right + New Campaign button.

Step 1 — Pick a template

Vibot lists every APPROVED template on your WABA. Each card shows:

  • Template name (e.g. welcome_v2).
  • Category pillMarketing / Utility / Authentication. The category determines wallet rate when sending.
  • Quality pill — Green / Yellow / Red / Unknown. Vibot reads this directly from Meta.
  • Language — locale (en, hi, en_IN).
  • Body preview — the first ~120 characters.

Click a card to select. The right-side preview pane fills with the full template content and a live preview of the message bubble.

⚠️

Don’t blindly click the prettiest template. Pick the one whose category genuinely matches the message intent:

  • Order shipped / appointment reminder → Utility
  • Promotional offer / sale announcement → Marketing
  • OTP / 2FA code → Authentication

Category mismatch is one of Meta’s top reasons for template rejection AND a frequent quality-rating-drop trigger.

Click Next to advance.

Step 2 — Choose recipients

Two paths:

Path A — From Contacts

If you’ve imported contacts into the Contacts page, this is the cleaner path. Vibot lets you filter by:

  • Label — multi-select. Recipients matching ANY selected label are included.
  • Opted-out — auto-excluded for Marketing templates; can be included for Utility/Authentication.

Below the filters, Vibot shows the live count of matching contacts.

Map template variables

If your template body has {{1}} {{2}} placeholders, Vibot prompts you to map each variable to a contact field:

VariableMaps to
{{1}}First name / Last name / Full name / a custom field
{{2}}Same

If your template has no variables, this section doesn’t appear.

Path B — CSV upload

Upload a .csv or .xlsx file. Required columns:

  • phone — E.164 format with + (e.g. +919876543210). Vibot normalises common variants but + is required for unambiguous parsing.
  • var1, var2, … — one column per template variable, in order.

Optional column: name — used for display only.

Vibot shows a preview of the first 5 rows so you can verify mapping before launching.

File-size limit: 5 MB. Recipient cap: depends on plan + tier. The 24-hour-tier ceiling (250 / 1,000 / 10,000 / etc.) is enforced regardless of file size.

Click Next to advance.

Step 3 — Review & Launch

This is where Vibot runs the preflight check and produces a traffic-light verdict.

Reading the preflight panel

The panel has three rows:

Verdict pill — one of:

  • 🟢 Ready to send. No blockers, no warnings. Launch is enabled.
  • 🟡 Review warnings before launch. Soft issues. Launch is enabled after you tick the “I’ve reviewed the warnings above and want to launch anyway” checkbox.
  • 🔴 Sending blocked. Hard blockers — launch is disabled until you fix the source list.

Count pills — six numbers at a glance:

PillWhat it counts
AcceptedWill actually be sent. The number on the Launch button.
Skip — length overflowRendered body > 1,024 chars (Meta’s limit).
Skip — opted outMarketing campaigns only; recipients with optedOut: true are skipped.
Skip — not on WhatsAppCached 131026 (last 30d) or live-check confirmed invalid.
Skip — already receivedSame template sent to this recipient within the dedupe window (default 7 days).
WarningsSendable but at risk (recently spam-blocked, dead-number warnings, tier-cap unverified).

Warning list — full text of each soft warning, e.g.:

Verified the first 250 recipients against WhatsApp’s contact list — 4,750 more were not checked because that would exceed Meta’s per-day verification budget for this number. Your messaging tier is TIER_250. Those will be sent unverified.

The full list of blocker types

If the verdict is RED, one or more of these will be in the blockers list. Fix the source, then Back → Step 2 and re-import.

  • Recipient list is empty. — no recipients matched your filters or CSV.
  • No sendable recipients — every row was filtered out. — common after a fresh sender’s first big import: all 100 rows were dead numbers + opt-outs.
  • Your phone number's verification with Meta has expired. — the SMS-OTP re-verification has expired. Fix via Connect WhatsApp → Verify Number (see troubleshooting).
  • Template '{name}' has a RED quality score on Meta. — the template itself has been quality-dropped. Recreate with cleaner copy under a new name, or pause for 24–72h.
  • Insufficient wallet balance. — wallet check is the very last gate. Top up via Billing → Add Credits.

The launch warning modal (first-send heads-up)

If this is your first ever campaign on the number OR the first use of this specific template, Vibot pops the amber “First send on this WhatsApp number” modal before the actual launch.

Pick:

  • Send slow on first launch ← recommended. Applies Conservative drip (5 → 10 → 25 → 50/h).
  • Send normally, I accept the risk — bypasses drip, uses default 50-msg batches.

See Warm up a new number for why “send slow” is almost always the right answer.

Choose send time

Two options:

  • Send now — campaign starts immediately on click.
  • Schedule for later — pick a date + time. Vibot enqueues the launch as a delayed BullMQ job; recipients are not held in some staging table, they’re sent at the scheduled moment.

Name the campaign

The campaign name appears in your Campaigns list and in CSV exports. Use something descriptive — “Diwali Sale Push”, “Order Status Reminder Oct 12”, etc. Don’t use names that contain sensitive info (e.g. customer phone numbers).

Click Launch

Final click: Launch to N contacts. The button shows the Accepted count, not the total — so if your list has 1,000 rows but 200 are pre-skipped, the button says “Launch to 800”.

After click:

  • Wallet balance check → debits the predicted cost.
  • Campaign row created (status: RUNNING).
  • Recipients inserted (status: PENDING for sendable, status: SKIPPED with skipReason for pre-filtered).
  • First batch (or first canary cohort if eligible) enqueued.

You’re redirected to the campaign detail page.

After launch — what to watch

The campaign detail page is the single source of truth for live status.

Overview tab

Top of page: status pill (RUNNING / COMPLETED / CANCELLED) + canary banner (visible only when canary is in progress / failed / passed).

Below: six counters that auto-refresh every 4–6 seconds:

CounterMeaning
TotalRows on the campaign.
SentMeta accepted the API call (returned a wamid).
DeliveredMeta’s delivery webhook fired.
ReadCustomer opened the chat.
FailedMeta returned an error (131026, 131049, etc.).
SkippedPre-filtered (opt-out, dead, dedup) — never sent.

Send-progress bar shows (Sent + Failed + Skipped) / Total.

Recipients tab

Per-row view with status + (if failed) the Meta error code. Filter by status to focus on FAILED rows for retry.

Insights tab

After the campaign completes: funnel chart (Sent → Delivered → Read → Replied), top-10 reply messages, top-10 failure reasons (by code + count).

Cancelling a campaign mid-flight

There’s no UI button for customers to cancel a running campaign. If you need to halt one, the canary or 15% halt will catch most safety-critical issues automatically. If you need to force-stop:

  • Contact support@virtuo.in or use the in-dashboard Vibot Assistant — admins can issue a force-cancel.
  • Note: in-flight 50-msg batches may continue to completion before the cancel takes effect. Future batches will be drained as SKIPPED, skipReason='admin_cancel'.

After a cancelled or partial campaign — Resume Skipped

If your campaign was cancelled (canary abort, manual cancel, 15% halt) or has FAILED recipients, you have two recovery paths from the campaign detail page:

Resume Skipped (N)

Re-targets recipients whose status is SKIPPED with a resumable skipReason. Opens a modal asking for the drip preset:

  • Conservative — 5 → 10 → 25 → 50 per hour. Default after a canary abort. Recommended.
  • Moderate — 10 → 25 → 50 every 30 min. Safe for known-clean lists.
  • Aggressive — 25 → 50 every 15 min. Gated (≤ 200 recipients, no prior chain abort, requires acknowledgement).
  • Custom — your own stages + delays.

The Resume button is disabled with a tooltip if a cool-off window is active (6h after a first abort, 24h after a second abort on the same chain).

Resume creates a NEW campaign row linked to the parent via resumedFromCampaignId. Conversation history with each recipient is preserved.

Retry Failed (N)

Re-targets recipients whose status is FAILED. Use sparingly — most FAILED rows are dead numbers or recipients globally spam-blocked, and retrying them costs you wallet credits to fail again. See Why sends fail.

Frequently asked

Q. Can I edit a campaign after launch? No. Campaigns are immutable once launched. To change message body or recipient list, cancel and create a new one.

Q. Can I A/B test two templates? Not via a single campaign. Launch two separate campaigns with different templates on different audience segments, compare reply rates in Insights.

Q. What’s the practical max recipients per campaign? 50,000 rows per campaign (Vibot’s CSV-import ceiling). Beyond that, split into multiple campaigns. Your 24h tier cap will limit how many actually send within a given day regardless.

Q. Why does my Accepted count not equal Total - Skipped? Some warning categories (recently-spam-blocked-131049, dead-number-warnings) are still in Accepted because they’re warn-only, not skip-skip. They’ll appear in the campaign report as FAILED if Meta confirms.

Q. How is the cost calculated? (Accepted count) × (per-template rate for your plan and the template category). Marketing / Utility / Authentication each have their own rate. Wallet is debited at launch as a prediction; if some sends are SKIPPED or FAILED, those refunds happen at campaign completion.

Next step

Sends failing in ways you don’t understand? → Why sends fail.