Build a blast or drip campaign with the create wizard
The create wizard is the dashboard path for turning on a blast or drip campaign without writing a request. It runs five ordered steps — Setup → Audience → Message → Schedule → Review — and renders the readiness, localization, and compliance panels inline before launch. This guide walks each step in order, maps every form field onto thePOST /campaigns body so you can switch to the API mid-flow, covers drafts, the launch validation gates, and what the campaign detail page gives you after launch.
Two worked examples land at the end: an SMS promo blast, and a three-step onboarding drip whose second step goes out on WhatsApp.
1. Wizard or API — pick the right entry point
Use the wizard when a person is driving the campaign: it enforces validation on every step transition, runs the pre-flight dry-run visually, and gates Launch on the same checks the API enforces server-side. Use the API (see Send a campaign end-to-end) when you’re provisioning campaigns from your own system, templating them, or running them from CI. Launch requires an owner, admin, or developer seat — the same role gatePOST /campaigns enforces. A billing or supervisor seat can compose a campaign but the Review step’s launch call is rejected with 403 INSUFFICIENT_PERMISSIONS; the wizard keeps your input locally so an owner can finish the send. Everything else in this guide — drafts, previews, dry-runs — works in either surface, because the wizard is a client of the same public API.
The wizard lives at Outbound → Campaigns → Create campaign in the dashboard navigation.
2. Step 1 — Setup: name, type, and channel
Setup picks the campaign type (blast, drip, or journey), a name, an optional description, and the primary channel. It also validates the omnichannel fallback chain when you stack channels.
- Name (1–200 chars), mapped to
name. Description (≤1000 chars) →description. - Type →
type. Blast and drip stay in this wizard;journeyand ad campaigns route to their own surfaces (the journey canvas, or the ads console). - Channel →
channel. The selector lists every live or beta channel from the channel registry; “coming soon” channels render disabled and can’t be submitted. - Fallback chain (optional) →
channels. An ordered list of up to 5 channels. Each non-final entry carriesfallback_on(failed/no_delivery/no_engagement) andfallback_after_seconds(60–604,800 seconds). The last entry is terminal. The wizard enforces the same invariants the API does: monotonic order, no duplicate channels, no fallback fields on the final entry. A single-channel campaign sends only the top-levelchannel. - Sender selection (SMS/MMS only) — an optional “Send from” picker for your dedicated numbers, and an optional Messaging Service selector that maps a campaign to a sender pool, opt-out list, and throughput cap. Both persist to
variables.fromandvariables.messaging_service_id; leave either empty to keep account-wide auto-select. Outbound SMS/MMS always terminates through the Devotel wholesale network either way — this chooses which of your identities it presents.
The RCS sender panel
Pickingrcs mounts a per-channel sender panel under the capabilities card. It derives its state from your RCS sender roster with three outcomes: verified (the campaign originates as a carrier-verified agent, with branding: “Sends from your verified sender”), pending (agents mid-verification — build now, launch when cleared), or none (no sender set up; a deep-link to Settings → Channels → RCS). Whichever state, the panel also notes the automatic SMS fallback: recipients whose handset or carrier can’t receive RCS are delivered by SMS on the same dispatch, and you can additionally add SMS as an explicit chain fallback for the no-delivery or no-engagement cases.
3. Step 2 — Audience: lists, segments, CSV, manual picks, CRM
Audience resolves who the send targets. Pick a strategy card:
The Choose contacts card mounts a searchable picker over your contacts: debounced search, a recent-contacts fallback when the query is empty, chip/remove handling, and a 10,000-contact ceiling matching the server-side audience limit. The picker submits raw contact ids; the send path re-resolves each one to a full audience entry at launch. Salesforce list-view sources additionally ask for a target object (Contact or Lead).
Below the strategy, an estimated recipient count updates — the wizard reuses the audience preview (
POST /campaigns/audience/preview) net-projection so the count you see already discounts suppression rows, channel opt-outs, and unreachable addresses. The count snapshot is saved with the campaign (variables.estimated_recipients) so a scheduled send shares it with the Review step.
4. Step 3 — Message: content, templates, A/B variants
The composer holds the campaign body (message_template, up to 100,000 chars — sized for HTML email), personalization tokens in {{token}} form, and per-channel character counters for SMS and other short-body channels.
- Template picker. Load any approved template from your template library (the
/outbound/templatescollection) by name. Loading a template writes its body into the composer — so anything you start from stays editable before launch. Channels with pre-registered content (WhatsApp) resolve against approved templates rather than freeform copy. - Email subject — email campaigns get a subject field (
subject, ≤500 chars), interpolated with the same tokens at send time. Drips carry a per-step subject instead, so this field only applies to blast email. - A/B testing. Enable to add a Variant B (and optionally C/D) with a traffic split. Two variants allow any integer split summing to 100 (presets 50/50, 70/30, 80/20 are shortcuts); three-plus variants get fine-grained per-variant allocations. You also pick the winner metric (delivered / opened / clicked / replied) and an optional holdout percent (≤50) for lift measurement. Everything here persists through a
variables.ab_teststructure plus variant rows synced at launch. - Personalization preview. A recipient picker renders the body with a sample contact’s fields substituted — custom fields (e.g.
{{customer_tier}}) included — and the phone mock shows the resolved sender identity (a dedicated number or the shared Devotel sender for SMS; your brand name for brandable channels).
Localization: the translate-locales dialog
The “Translate for locales” button calls the template translator (POST /campaigns/templates/translate) which rewrites the current body into one or more locales while preserving tokens and the opt-out instruction. You review each generated variant in a dialog — only variants you explicitly approve are saved onto the campaign as variables.locale_variant_set, and the send pipeline routes each recipient to the variant matching their contact’s language, falling back to the base body when no variant matches.
When to translate vs. fork: use the locale variant set when one campaign with per-recipient language routing is the right unit of measurement. Fork into one campaign per locale instead when different locales need different send times, different sender registrations, or separate holdout/ROI accounting.
5. Step 4 — Schedule: fixed time, recurrence, throttling, windows
Schedule decides when and how fast the send fires.- Send now or later. A one-off send (
recurrence: once→ novariables.recurrence) can fire immediately or at a fixedscheduled_attimestamp interpreted in the timezone you pick. The wizard rejects past instants and converts the wall-clock to a UTC ISO string via the same timezone you selected. - Recurrence. For scheduled sends, optionally pick a cadence — daily, weekly (with weekday selection), monthly (with day-of-month), or custom cron (5 fields). Every recurring campaign requires an explicit end condition: never (requires the operator to tick the confirm box acknowledging indefinite sending — a hard gate, not a passive banner), after N occurrences, or on an end date. The recurrence block persists to
variables.recurrenceonly when the send is scheduled and recurring, so a switched-back “Send now” send never inherits a stale cadence. - Throttle. A messages/second ceiling (
throttle_rate, 0–10,000). Zero means “no explicit ceiling” — the platform default of 50 msg/s applies. - Business hours. Restricts sends to business-hours windows (
variables.business_hours_only). - Number validation (HLR). An optional per-recipient lookup (
variables.validate_numbers) checked before send, priced separately from the message rate; the wizard projects its cost including recurring-occurrence totals. - TCPA window notice. For voice and SMS, sends queue only in the 8 AM–9 PM recipient-local federal window; the step renders a banner explaining that out-of-window recipients are deferred rather than failed. The window is enforced server-side at send time; see the send-gating model.
6. Step 5 — Review: readiness, localization recap, compliance, launch
Review assembles the launch surface: the cost estimate, the sending-readiness panel, per-locale variant recap, the compliance checklist, and the launch/submit-for-approval action.Sending-readiness panel
Four enumerated rows fold the live preflight into a verdict (pass / attention / unverified — never a silent pass):- Channel — a channel is selected.
- Route — outbound SMS/MMS always routes via the Devotel wholesale network; other channels report “unknown” rather than a fabricated pass (their setup happens under Settings → Channels).
- Channel connection — whether this account has a dedicated sending number for the channel. SMS-family is the only channel the preflight probes, so WhatsApp/RCS/voice/email connection reads “unknown” rather than green.
- Sender identity — the exact from-identity the send will originate from (your dedicated number’s number, the shared Devotel sender when no dedicated number is attached, or an email sender name).
Compliance checklist
The checklist mixes machine-verified rows (locked to a real signal, not toggleable) with self-attestation rows:- Sending setup (machine) — satisfied when the live preflight returns no blocking issue. Rendered in an advisory register when only advisory issues exist (no dedicated number attached, or a regulated-country destination without an approved profile), and unsatisfied while the check is errored or loading. Remediation deep-links (buy a number, set up a compliance profile) render beside it.
- Opt-out language (machine) — for freeform channels (SMS, MMS, RCS), every launch body — the primary variant plus each non-empty A/B variant — must contain carrier-accepted opt-out language (STOP / UNSUBSCRIBE / OPT OUT / cancel). WhatsApp template sends and email are exempt (Meta handles template opt-out; ESPs carry unsubscribe in headers). For multi-variant tests, an unsatisfied hint names the specific missing variant.
- Recipients opted in (attestation) — confirm the audience consented.
- Content reviewed (attestation) — confirm the copy is accurate.
- Shared-sender acknowledgement (attestation, conditional) — appears only when no dedicated SMS number is connected; the send ships on the shared Devotel sender either way, but launch requires the conscious confirmation.
- Channel-readiness acknowledgement (attestation, conditional) — appears only for channels the preflight can’t verify (WhatsApp, RCS, voice). Unlike SMS, these have no shared-sender fallback, so their connection needs an explicit confirmation before launch.
Launch vs. submit for approval
When the org level requires approval (campaigns/approvals), the primary action becomes Submit for review: the launch parks in the approvals queue instead of sending, and an approver (owner/admin with approval rights) releases it from Outbound → Approvals. The wizard refuses to render a confident one-click launch while the approval policy is unknown.
7. What the wizard posts — field-to-body mapping
Every Review-step launch call chains the same public endpoints the API guide uses, in this order:POST /campaigns(orPUT /campaigns/:idfor an edit) — the campaign row.POST /campaigns/:id/steps— drip steps (drips only).POST /campaigns/:id/variants— A/B variant rows (3+ variants).POST /campaigns/:id/send— the launch. For a futurescheduled_at, this moves the campaign toscheduledstatus without dispatching; the scheduler fires it at the configured time. No call → stuck in draft.
If a mid-chain call fails (steps/variants/send), the campaign row already exists, and the Review step reports the partial-launch state instead of silently leaving a created-but-idle draft — re-launching updates the existing row rather than minting a duplicate.
8. Drafts: saving and resuming
Save draft (Review step) persists the campaign as a draft row. A draft reopens through Campaigns → Drafts tab in the list, or directly via the?edit=<id> deep-link the draft card offers. Reopening routes edits to PUT /campaigns/:id, so repeated saves never mint duplicates. When a launch attempt fails on a non-permission error, the wizard still keeps the draft it minted locally, so retrying updates rather than duplicates.
A draft saved mid-wizard carries its complete form — schedule, recurrence, A/B, locale variants — so “Save draft” from a scheduled send restores the same schedule on reopen.
9. Launch gates — what disables the button, and the error you get
The Review step disables Launch/Submit and lists the blocking reasons beside the button. Gates, in check order:
Server-side,
POST /campaigns/:id/send enforces the same checks — the dry-run buckets (Send a campaign end-to-end) map one-to-one to the Review-step panels, so a failed launch from the API can be diagnosed on the wizard’s dry-run report (audience / cost / quiet-hours / warnings).
10. After launch: the campaign detail page
Launching puts the campaign onto the tracking page (Campaigns → click the row). What you get:- Stats panel — live totals for sent, delivered, failed, opened, clicked, replied; polled while running.
- Pause / resume / cancel — pause stops dispatch and preserves state; cancel terminates (in-flight sends complete); resume continues from where it stopped. A campaign that hit its
credit_cap_usd_centsauto-pauses and tells you why. - Drip analytics (
/campaigns/:id/drip-analytics) — per-step sent/delivered/read/failed plus sequence progress, for drips. - Holdout-lift console (
/campaigns/:id/holdout-lift) — treatment vs. control conversion-rate delta with confidence interval when you set a holdout. - ROAS (
/campaigns/:id/roas+ touchpoints) when you attribute revenue. - Lifecycle webhooks —
campaign.started/paused/resumed/cancelled/completedplus drip-step events; subscribe under webhooks.
11. Troubleshooting
- Wizard stuck in draft. The campaign exists but no send fired — almost always a missing
POST /campaigns/:id/send(the wizard reports the partial-launch chain). Reopen the draft from the Drafts tab and launch again; the wizard will update the existing row. - Launch button disabled. The inline reason list names the gate — work down section 9’s table. The most common are an empty net audience (all suppressed/opted-out/unreachable — rerun the preview with a channel) and a missing opt-out line.
- “403 INSUFFICIENT_PERMISSIONS” on launch. The launch needs owner/admin/developer; a supervisor or billing seat must hand the draft to an owner — the wizard preserves the entry so an owner completes it.
- Dry-run errors from the API. Match them to the dry-run buckets —
audience.deliverable: 0maps to the zero-recipients gate;cost.sufficient: falseto the wallet gate;warnings[](“no provider registered”, “quiet hours fully closed”) to the advisory panels on the Review step. - Recurring send won’t advance past Schedule. Recurrence requires an explicit end condition; a “Never” end requires the confirm tick. Cron needs five fields.
Worked example 1 — SMS promo blast
A scheduled SMS blast to a VIP list with a holdout, no recurrence.- Setup: name
Retail promo — summer sale, typeblast, channelsms. - Audience: Contact List card, pick
list_summerVIPs; the estimate shows net reach. - Message: body
Hi {{first_name}}, early access to our summer sale: 25% off through Sunday. Reply STOP to opt out. - Schedule: schedule a fixed future time, recurrence “once” (no end condition demanded), throttle blank (default).
- Review: pass compliance (opt-out language is in the body), launch.
POST /campaigns with type: "blast", channel: "sms", audience_type: "list", variables.campaign_holdout_percent, and POST /:id/send (see Send a campaign end-to-end).
Worked example 2 — three-step onboarding drip
A welcome drip on signup: welcome email first, WhatsApp follow-up second, SMS nudge third.- Setup: type
drip, primary channel can be any single one — per-step channels override it. - Audience: segment
new-signups. - Message: the drip step editor lists steps you add one at a time. Step 1: email with a subject (
Welcome to Acme). Step 2: WhatsApp — if your account has an approved WhatsApp template, it routes as a template send; the guard re-checks against your approved catalog before launch. Step 3: SMS. - Set each step’s delay (minutes/hours/days/weeks — converted to minutes in the payload), and optionally a per-step send condition (e.g. “previous step read”).
- Schedule: send now (the kick-off sends immediately; steps follow per their delays).
- Review: launch. Drip analytics then report per-step numbers.
Worked example — manual picker, recurring schedule, RCS sender panel
Manual roster: Audience step → Choose contacts → search contacts by name/number → chips accumulate as you pick → the roster becomesvariables.manual_contact_ids on the campaign. Reuse for exec outreach or one-off regulatory notices.
Recurring schedule: Schedule step → send later → pick weekly recurrence with Mon/Wed/Fri → end “after 20 occurrences”. The payload becomes variables.recurrence: { recurrence_type: "weekly", recurrence_days: ["mon","wed","fri"], recurrence_end_type: "after_count", recurrence_end_count: 20 }.
RCS sender panel: Setup step → pick rcs → the panel below the capabilities card names the verified sender (or the “not yet set up” link). It also notes the automatic SMS fallback every RCS blast gets for non-RCS handsets.
Related reading
- Send a campaign end-to-end — the same lifecycle over the API, including the dry-run report.
- Campaign journey builder — the event-driven journey canvas for
type: "journey". - A/B testing campaigns — variants, allocation, and winner metrics.
- Outbound templates — the template library the picker searches.
- Policy scanner — regulatory checks layered under the opt-out and consent posture here.
- Opt-out lists and best practices — suppression and deliverability specifics.