← Back to blog
8 min read

Turning Click-to-WhatsApp ads into measurable ROAS

whatsappattributionads

In short

The attribution chain breaks in one specific place: `ctwa_clid` arrives only in the referral payload of the very first inbound message, and if it is not stored against the conversation at that moment it is gone for good. Close the loop by capturing it on first touch, carrying it with the conversation for as long as the sale takes, and firing a Conversions API event when the order actually closes — not when the chat starts.

Click-to-WhatsApp (CTWA) ads are one of the highest-intent ad formats available to SEA sellers — a shopper who taps "Send Message" has already decided to talk to you. The problem is what happens after the tap: the conversation moves into WhatsApp, the order often closes days later, and the attribution trail between ad spend and revenue quietly breaks.

Most sellers end up reporting on ad spend and chat volume as separate universes, then eyeballing ROAS with a gut feeling. That gap is exactly where CAPI (Conversions API) and message-level attribution are supposed to help — but only if the `ctwa_clid` actually survives the whole journey.

Where the attribution chain breaks

The click id (`ctwa_clid`) arrives inside the referral payload of the very first inbound message. If your inbox tooling isn't built to capture that on the first touch, it's gone — there's no second chance to retrieve it from later messages in the thread.

From there, the id needs to be carried alongside the conversation all the way to the order — through however many messages, however many days, and however many human handoffs it takes to close the sale — and then sent back to Meta as a Conversions API event when the order is confirmed, not just when the chat starts.

Closing the loop, end to end

Capture `ctwa_clid` at first touch and store it against the conversation, not just the message. Conversations span days; the click id needs to outlive the message that carried it.

Fire the CAPI purchase event with `action_source: business_messaging` and the click id in `user_data`, deduplicated by `event_id`, when the order actually closes — whether that's an automatic order-confirmation webhook or a human agent marking the chat converted.

Report ROAS at the ad-account level using the same conversation-to-order link, so the number reconciles with what Ads Manager shows instead of contradicting it.

Why this is worth the engineering effort

Once the loop closes, CTWA stops being a volume play you fund on faith and becomes a channel you can scale on evidence — the same way sellers already scale Shopee ads on measured conversion. The sellers who get there first simply outbid everyone else for the same audience, because they know it's profitable and their competitors are still guessing.

Frequently asked

What is ctwa_clid and where does it come from?
It is the click identifier Meta attaches to a Click-to-WhatsApp ad click. It arrives at the top level of the `referral` object on the first inbound WhatsApp message of that conversation — not nested deeper, and not repeated on later messages.
Why does my CTWA reporting disagree with Ads Manager?
Usually because the two are counting different events: Ads Manager counts conversations started at the click, while your spreadsheet counts orders that closed days later. They only reconcile when the same conversation-to-order link produces both numbers.
Can I recover the click id later if I did not store it?
No. The referral payload rides on the first message only. If it was not persisted against the conversation at that moment, that click is permanently unattributable — which is why capture-on-first-touch is an inbox architecture decision, not a reporting one.

Read in中文Bahasa Malaysia

See it work on your own store

Connect your channels and let Inchat's AI agent handle the repeat questions — day or night.