What is a triggered campaign?
A triggered campaign is a set of WhatsApp messages sent automatically when a customer event occurs: an account is created, a cart is abandoned, an order is delivered, an item comes back in stock, or a customer has not bought for 60 days. Each customer receives the message at their own moment, about the thing they just did, which is why triggered messages usually outperform a calendar broadcast of the same content.
Under the hood it is event-driven. Your store, app or CRM emits an event, often as a Webhook or a message on a queue. A rules engine checks whether this customer is eligible (opted in, not messaged too often, not already converted), waits any configured delay and then calls the Cloud API's messages endpoint. If the customer messaged you within the last 24 hours, the 24-hour customer service window allows a free-form message; if not, the trigger must send an approved message template, whose category depends on what it says.
The closest neighbour is the Drip Campaign: a time-based sequence that everyone on a list moves through on a schedule (day 0, day 3, day 7). A triggered campaign has no schedule of its own; it waits for behaviour. The two are often combined, such as a sign-up trigger that starts a short drip, and both are forms of Workflow Automation.
Key takeaways
- A triggered campaign sends a message because a customer did something (signed up, abandoned a cart, bought, went quiet), not because a date arrived.
- Every trigger needs an event, eligibility rules, a delay and a cancel condition such as 'stop if the order has been placed'.
- If the customer wrote to you in the last 24 hours a free-form message is allowed; otherwise the trigger must send an approved template.
- The template's category follows its content: a delivery confirmation is utility, a cart reminder or win-back offer is marketing.
- A drip campaign runs on a fixed schedule; a triggered campaign reacts to each customer's own events.
How does a triggered campaign work?
- Step 1
Define the event and its payload
Name the event (
cart.abandoned,order.delivered,customer.inactive_60d) and include what the message needs: customer ID, WhatsApp number in E.164, items, and a cart or order token. Emit it once per real occurrence, with a unique event ID. - Step 2
Set eligibility rules
Before anything is queued, check marketing opt-in for marketing triggers, the suppression list, a frequency cap shared across all campaigns, and quiet hours. A utility trigger such as a dispatch notice relies on the customer's transaction, not a marketing opt-in.
- Step 3
Add a delay and a cancel condition
Most triggers wait: 30–60 minutes for an abandoned cart, a day after delivery for a review request. Re-check at send time and cancel if the goal already happened, such as the order being placed.
- Step 4
Choose free-form or template
If the customer's last inbound message is under 24 hours old, a free-form message is allowed. Otherwise send an approved template of the right category with its body variables and button parameters.
- Step 5
Send once and record the outcome
Deduplicate on the event ID so a retried job never sends twice, store the returned
wamid, and attribute later clicks, replies and orders back to the trigger that caused them.
A triggered campaign in code
// Worker for a delayed "cart.abandoned" job (Node.js 20+, built-in fetch).const GRAPH = "https://graph.facebook.com/v26.0";const DAY_MS = 24 * 60 * 60 * 1000;export async function onCartAbandoned(event) {const c = await db.customers.get(event.customerId);// 1. Eligibility: marketing consent, suppression list, shared weekly capif (!c.marketingOptIn || c.suppressed) return "skip:no-consent";if ((await db.sends.countMarketing(c.id, 7)) >= 3) return "skip:capped";// 2. Cancel condition, re-checked after the 45-minute delayif (await db.orders.placedSince(c.id, event.occurredAt)) return "skip:converted";// 3. Free-form only if the customer wrote to us in the last 24 hoursconst windowOpen = c.lastInboundAt && Date.now() - c.lastInboundAt < DAY_MS;const item = event.items[0].name;const message = windowOpen? { type: "text", text: { body: "Still thinking about the " + item + "? Your cart is saved." } }: {type: "template",template: {name: "cart_reminder_v2", // approved MARKETING templatelanguage: { code: "en" },components: [{ type: "body", parameters: [{ type: "text", text: item }] },{ type: "button", sub_type: "url", index: "0",parameters: [{ type: "text", text: event.cartToken }] },],},};// 4. One send per event, even if the job is retriedif (!(await db.sends.claim(event.id))) return "skip:duplicate";const res = await fetch(GRAPH + "/" + process.env.PHONE_NUMBER_ID + "/messages", {method: "POST",headers: {Authorization: "Bearer " + process.env.ACCESS_TOKEN,"Content-Type": "application/json",},body: JSON.stringify({ messaging_product: "whatsapp", to: c.waId, ...message }),});const data = await res.json();if (!res.ok) {await db.sends.release(event.id); // let the queue retrythrow new Error(data.error?.message ?? "send failed");}await db.sends.record(event.id, c.id, data.messages[0].id, "cart_reminder");return "sent";}
Check consent and caps, re-check the cancel condition after the delay, pick free-form or template by the window, then claim the event ID so a retry cannot double-send.
Example: Three triggers at a Bengaluru meal-kit app
A meal-kit subscription in Bengaluru runs three triggers. When a trial user adds a kit but does not pay within 45 minutes, a marketing template shows the kit with a button back to checkout; if payment arrives during the wait, the job cancels itself. When a box is marked delivered, a utility template confirms it and offers a 'Report an issue' quick reply. When a subscriber skips two weeks in a row, a win-back marketing template offers to pause rather than cancel. All three check one shared cap of three marketing messages per customer per week, so a customer who abandons a cart on the day a win-back offer goes out receives only one of them.
Common mix-ups
Common mistakes with a triggered campaign
No cancel condition
A reminder that lands after the customer has already paid is the fastest way to look careless. Re-check the goal at send time, not only when the event arrives.
Capping each trigger separately
Five triggers that each allow two messages a week can send ten. Apply one frequency cap across every trigger and campaign, and decide which wins when two fire together.
Assuming the window is open
A free-form message to someone who has not written in 24 hours fails with error 131047. Check the time of the last inbound message and fall back to an approved template.
Submitting reminders as utility
Meta's categorisation treats cart reminders and win-back offers as marketing, even when the customer asked for them. Submit them as marketing and budget for the marketing rate.
Firing on duplicate events
Event buses and webhooks deliver at least once, so the same event can arrive twice. Claim the event ID before sending and skip anything already claimed.
A triggered campaign: key facts and limits
- Started by
- A customer event, not a calendar date
- Typical delays
- 30–60 min (cart), 1 day (review), 30–90 days (win-back)
- Outside the 24-hour window
- Approved template required
- Cart and win-back reminders
- Marketing category, ₹0.94 per delivery in India
- Order and delivery updates
- Utility category, ₹0.19 per delivery in India
- Duplicate protection
- Deduplicate on your event ID before calling the API
Why the difference matters
Why does a triggered campaign matter?
Recipients judge a WhatsApp message on timing and relevance, and a triggered message has both by construction: it arrives minutes or days after the customer acted, about what they did. That makes triggers the best use of paid marketing deliveries for most stores and apps; Cart Recovery, Back-in-Stock Alerts and win-back offers are all triggers. For developers the plumbing matters as much as the copy, because duplicated events, missing cancel checks and sends to people without consent are what turn a helpful reminder into a complaint.
Rules of thumb
Best practices for a triggered campaign
- Start with the three triggers closest to revenue: abandoned cart, post-purchase and win-back.
- Log every skip with its reason (no consent, capped, converted); skips explain campaign numbers better than sends.
- Give each trigger its own template name and UTM campaign so analytics can separate them.
- Respect quiet hours: hold a trigger that fires at 1 am until morning and re-check the cancel condition when it is released.
Triggered Campaign FAQs
What is the difference between a triggered campaign and a drip campaign?+
Do triggered WhatsApp messages need an approved template?+
Are triggered messages marketing or utility?+
How quickly should a trigger fire?+
Can I run triggered campaigns without writing code?+
* Per-message rates for India, ex-GST: marketing, utility and authentication effective 1 July 2026; service messages ₹0.145 since 1 October 2026 (they were ₹0 until 30 September 2026). Volume commitments earn discounts — final rate is confirmed on your account; applicable GST extra. Rates for other countries differ (see the international rate table on /pricing).