Growth
How to measure WhatsApp campaign ROI: metrics, UTM links and attribution that holds up
A practical method to prove what a WhatsApp campaign earned: delivery and reply metrics, UTM-tagged button links, coupon codes, a holdout group, Click-to-WhatsApp conversion events and the cost side.
By Broadchat teamPublished 7 min read
In short
WhatsApp campaign ROI is the revenue a campaign caused minus what it cost, divided by what it cost. The campaign report tells you delivery, reads and replies; revenue has to come from your store or billing data, joined through UTM-tagged button links, campaign-specific coupon codes and replies you can trace. A holdout group that receives nothing is the most honest way to separate caused sales from sales that would have happened anyway.
Key takeaways
- Delivery, read and reply counts show reach and interest, not revenue; ROI needs sales data from your store, POS or billing system.
- Put UTM parameters on every template URL button so your web analytics can attribute visits and orders to the campaign.
- A holdout group of opted-in customers who receive nothing shows how many sales the campaign actually caused.
- Count all costs: Meta's per-message charges, your provider's markup and subscription share, creative work and discounts given.
- For Click-to-WhatsApp ads, send conversion events back to Meta with the ad click ID so Ads Manager can optimise for buyers, not chats.
WhatsApp campaign ROI answers one question: did the money and attention you spent on a campaign come back as profit? The formula is simple, (revenue caused by the campaign − campaign cost) ÷ campaign cost, but both halves are easy to get wrong. This article explains which numbers a WhatsApp campaign report gives you, how to connect them to sales with UTM links, coupon codes and a holdout group, and how to track Click-to-WhatsApp ads back to purchases. It is written for marketers and owners who already send campaigns and want numbers they can defend.
What the campaign report tells you, and what it does not
Every WhatsApp campaign produces message-level statuses from Meta's webhooks. In Broadchat, open CRM → Bulk Campaign and click a campaign to see:
| Metric | What it means | What it is good for |
|---|---|---|
| Sent | Accepted by Meta for delivery | Checking the audience size went out |
| Delivered | Reached the customer's phone | The base for cost: Meta charges per delivered template message |
| Read | Opened, as reported by the customer's WhatsApp | Creative and timing comparisons, with a caveat (below) |
| Replied | The customer wrote back after the campaign message | Interest, and the start of a customer service window |
| Failed | Not delivered, with Meta's error code | List hygiene and limits, for example error 131049 |
Each recipient row also shows the sent, delivered, read and replied times. You can filter by Read Status, Reply Status, Replied In (24h, 48h or 7d) and Reply is (Stop Notification or Other), then Retarget the filtered group in a follow-up campaign. Export CSV downloads every message of the campaign, and Export Report via Email sends the same file to your login email.
None of these is revenue. A campaign with a high read rate can sell nothing; a campaign with few replies can drive many website orders. Treat the report as the top of the funnel and bring in sales data for the rest.
Tag every link with UTM parameters
Most campaign revenue happens off WhatsApp: on your website, app or store. To connect it, add UTM parameters to the URL in your template's URL button. Google Analytics and most other analytics tools read them automatically. Broadchat does not track link clicks itself, so this tagging is what makes the click and the order visible in your analytics.
Meta's template components allow two kinds of URL button:
- Static URL: the full link is fixed in the template, for example
https://rangolihome.in/diwali?utm_source=whatsapp&utm_medium=broadcast&utm_campaign=diwali_2026. - Dynamic URL: the template stores the base URL and a
{{1}}suffix you fill per send, for examplehttps://rangolihome.in/{{1}}with the suffixdiwali?utm_source=whatsapp&utm_medium=broadcast&utm_campaign=diwali_2026&utm_content=segment_a. This lets one approved template carry a different campaign or segment tag each time.
Keep a naming convention and stick to it:
| Parameter | Use | Example |
|---|---|---|
utm_source | Always the channel | whatsapp |
utm_medium | Type of send | broadcast, reminder, chatbot, ctwa |
utm_campaign | The campaign name, lowercase | diwali_2026 |
utm_content | Variant or segment | segment_a, image_v2 |
Use coupon codes for sales you cannot tag
UTM links miss orders placed by phone, in the shop or by replying I'll take the blue one. Give each campaign its own coupon code, such as WADIWALI26, and use it nowhere else. When the code appears on a bill, you know where the customer came from. For replies that turn into orders in the chat, tag the contact with the campaign name in the inbox so the order can be linked later.
Measure lift with a holdout group
Your best customers often buy during Diwali whether or not you message them. If you count all their orders as campaign revenue, ROI looks better than it is. A holdout group fixes this:
- Build the campaign segment of opted-in customers in CRM → Segment.
- Randomly set aside about 10% of it, for example by exporting the list and moving every tenth row to a separate tag, and send the campaign only to the rest.
- After the campaign window, compare the purchase rate of the two groups from your sales data.
- The difference in purchase rate, multiplied by the size of the sent group, is the number of orders the campaign caused; multiply by the average order value for revenue.
A holdout costs you some sales in the short term, so use it on recurring campaigns where the learning pays off, not on a one-off launch.
Attribute Click-to-WhatsApp ads to purchases
When someone taps a Click-to-WhatsApp ad, their first message carries a referral from the ad, including a click ID (ctwa_clid). Broadchat saves the ad details and the click ID on the contact. When the lead later buys or qualifies, the chatbot step Send Conversion Event reports it to Meta's Conversions API with an event such as Purchase, LeadSubmitted or QualifiedLead, plus optional value and currency. The dataset it reports to is set on the channel (Channels → Conversions API dataset).
This matters because Ads Manager otherwise only sees chats started, not sales. With conversion events coming back, you can compare ads by purchases and let Meta optimise towards people who buy. Setup details are in our guide to setting up Click-to-WhatsApp ads.
A worked ROI example (illustrative)
Illustrative figures. Rangoli Home sends a Diwali bedsheet campaign to an opted-in segment of 10,000 customers, holding back 1,000 as a holdout. It sends to 9,000; 8,700 are delivered.
| Line | Sent group (9,000) | Holdout (1,000) |
|---|---|---|
| Customers who ordered within 7 days | 315 (3.5%) | 20 (2.0%) |
| Average order value | ₹2,349 | ₹2,349 |
Revenue caused. The extra purchase rate is 1.5 percentage points. 1.5% of 9,000 is 135 orders caused by the campaign, or ₹3,17,115 in revenue. At a 40% gross margin, that is ₹1,26,846 in gross profit.
Cost. Meta’s rate card effective 1 Oct 2026 lists ₹0.8631 per delivered marketing message to India, excluding GST, so 8,700 deliveries cost ₹7,508.97 in Meta charges. Add the provider’s markup and a share of the subscription (say ₹2,000 here), creative work (₹3,000) and the 10% discount, which every one of the 315 buyers used: ₹73,994 on ₹7,39,935 of orders. Total: about ₹86,503.
ROI. (₹1,26,846 − ₹86,503) ÷ ₹86,503 ≈ 0.47, or 47%. Counting all 315 orders as campaign revenue (₹2,95,974 gross profit) would have shown about 242%. The gap comes from two things a simple report hides: 180 of the buyers would probably have ordered anyway, and they still received the discount.
Run your own cost side through the WhatsApp pricing calculator, and see WhatsApp API pricing for how wallet charges work.
Pitfalls that distort ROI
- Counting reads as results. Reads are undercounted (read receipts) and are not purchases.
- Ignoring failures. Per-user marketing limits cause some 131049 failures on most sends; those people saw nothing, so do not count them in the sent group. See error 131049 explained.
- An attribution window that is too long. Choose the window before the campaign (for example 7 days for a festive sale) and stick to it.
- Leaving out the discount. A 20% coupon on orders that would have happened anyway is a cost, not a gain.
- Ignoring opt-outs. Check the Reply is → Stop Notification filter after every send; a rising stop rate is a cost to future campaigns.
Building a measurement habit
Measure every campaign the same way: report export, UTM-tagged links, a coupon code, and a holdout on recurring sends. After four or five campaigns you will know your normal reply and purchase rates and can spot a weak campaign within a day. This is part of the wider WhatsApp marketing strategy; for audience and timing choices, read the broadcast best practices. Agencies reporting ROI to many clients can run campaigns and exports under their own brand through the partner program.
Sources
- Message template components (URL buttons) — Meta for Developers, checked 12 October 2026
- Conversions API parameters (ctwa_clid, action_source) — Meta for Developers, checked 12 October 2026
- Pricing on the WhatsApp Business Platform — Meta for Developers, checked 12 October 2026
- Per-user marketing template limits — Meta for Developers, checked 12 October 2026
- [GA4] URL builders: Collect campaign data with custom URLs — Google Analytics Help, checked 12 October 2026
Broadchat team · Product and partner success team
The people who build and support Broadchat, the white-label WhatsApp Business API platform. We write from what we see while onboarding partners and their clients on the official WhatsApp Cloud API, and we check every article against Meta's current documentation.
Last updated:
Frequently asked questions
How do I calculate WhatsApp campaign ROI?
Subtract the campaign's total cost from the revenue it caused, then divide by the cost. Revenue caused is best measured as the difference in purchase rate between customers who got the campaign and a holdout group that did not. Costs include Meta's message charges, your provider's fees, creative work and discounts.
Does WhatsApp track link clicks in campaigns?
The campaign report shows sent, delivered, read, replied and failed statuses, not link clicks. Add UTM parameters to the template's URL button so your web analytics records visits and orders from the campaign.
Why is my WhatsApp read rate lower than expected?
Customers who switch off read receipts never send a read status, so they appear unread even if they opened the message. Read rates are useful for comparing your own campaigns, not as an absolute figure.
How do I track sales from Click-to-WhatsApp ads?
The first message from an ad carries a click ID (ctwa_clid). Keep it on the contact and send a conversion event, such as Purchase, to Meta's Conversions API when the lead buys. In Broadchat the chatbot's Send Conversion Event step does this using the dataset set on the channel.