> Source: https://docs.virtuo.in/vibot/sending/send-campaign
> End-to-end walkthrough of Vibot's campaign wizard — template pick, audience selection, preflight, launch options, and what happens after Send.
# 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.
## Before you start
Five preconditions. If any one is missing, the wizard will block at the relevant step.
- [x] Your WhatsApp number is **Connected** (green badge on the Connect page).
- [x] You have at least one **APPROVED** template (the Templates page). PENDING and REJECTED templates are filtered out of the picker.
- [x] Your account is on **Lite** plan or higher. Campaigns are not available on Free.
- [x] Your **wallet** has enough credits to cover the send at your plan's per-template rate. See [**Pricing**](/vibot/pricing).
- [x] If this is your first send on the number, you've read **[Warm up a new number](/vibot/sending/warm-up-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 pill** — `Marketing` / `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:
| Variable | Maps 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:
| Pill | What it counts |
|---|---|
| **Accepted** | Will actually be sent. The number on the Launch button. |
| **Skip — length overflow** | Rendered body > 1,024 chars (Meta's limit). |
| **Skip — opted out** | Marketing campaigns only; recipients with `optedOut: true` are skipped. |
| **Skip — not on WhatsApp** | Cached 131026 (last 30d) or live-check confirmed invalid. |
| **Skip — already received** | Same template sent to this recipient within the dedupe window (default 7 days). |
| **Warnings** | Sendable 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](/vibot/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**](/vibot/sending/warm-up-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:
| Counter | Meaning |
|---|---|
| **Total** | Rows on the campaign. |
| **Sent** | Meta accepted the API call (returned a `wamid`). |
| **Delivered** | Meta's delivery webhook fired. |
| **Read** | Customer opened the chat. |
| **Failed** | Meta returned an error (131026, 131049, etc.). |
| **Skipped** | Pre-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**](/vibot/sending/failed-sends).
## 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**](/vibot/sending/failed-sends).