product / conversation attribution

which ad started each chat, and what it sold.

heysteff records where every WhatsApp, Instagram and Messenger conversation comes from (a Meta ad, a link with UTM tags, a story or a post) and matches it against the orders in your Shopify store. You see how many chats and how many sales each campaign brings and, with your ad account connected, the ROAS of each ad.

A chat that came from an ad used to count as organic

A click-to-WhatsApp or click-to-Instagram-Direct ad ends in a conversation, and the sale closes there, not on a page with a pixel. Meta attaches a referral to the ad in the first message, but if nobody reads it, that chat looks like any other and the campaign gets no sales. heysteff reads it on every incoming message and stores it without slowing down delivery.

Which signals it reads and which one wins

A person can see an ad and later reply to a story. So the origin is decided by priority: the most specific signal wins.

OriginHow it's detectedPriority
Meta adThe referral Meta attaches to the message on click-to-WhatsApp, Instagram or Messenger ads1 (wins)
Tracked linkThe 6-character code from a heysteff link, or the jump to WhatsApp from the on-store assistant2
Instagram storyA reply to or a mention in a story3
PostA comment or the link from a post4
Reply to an automated messageNo earlier signal, and the person replied within 72 hours to an automated heysteff message5
OrganicNone of the above6

The unit is the conversation your plan bills: the 24-hour window that a customer message opens. If a window has no signal, the most recent one from the previous 7 days carries over, because someone who came from an ad on Monday and writes again on Wednesday still belongs to that ad. A sale takes the last origin of its conversation within the 30 days before the purchase; Meta measures messaging ads over 28 days.

UTM links for everything that isn't an ad

For your Instagram bio, a QR code in your shop, an email or a creator collaboration, you create a tracked link with its UTM parameters. Every click generates a 6-character code; if the URL carries different UTM tags, the URL's tags take precedence. On WhatsApp the code travels at the end of the prefilled text and heysteff strips it from the message before saving it, so your team never sees it; on Instagram and Messenger it travels in the link's ref parameter.

Sales by campaign and ROAS by ad

Sales come from the orders in your connected Shopify store. Each sale's campaign is taken from the tracked link's UTM; if there is none, from the Meta campaign; failing that, from the order's UTM. On top of that, every link to your store that goes out through heysteff carries utm_source=heysteff, the channel as utm_medium and the message type as utm_campaign, without overwriting UTM tags you already set. So heysteff shows up as its own channel in Shopify's reports.

For ROAS, you connect your Meta ad account with read-only permission. heysteff syncs the ad catalog and the last 35 days of spend, and calculates ROAS only when the ad account's currency matches your store's. Meta's permission is enabled per workspace: if you don't see the option in your dashboard, write to us. Without it you see the ad title, without campaign or ROAS.

Where you see it

In the dashboard, under Sales → "Conversation origin": every number opens the list of conversations or orders behind it, with the same filter. In the inbox, each thread shows a strip with its origin. In heysteff's Shopify app, the section sits inside "Sales by heysteff". It's also available through the MCP server.

What it doesn't do yet

The purchase isn't sent back to Meta through the Conversions API for messaging. And with an Instagram account connected through Instagram login, an ad that opens a new thread is recorded, but one that reopens an existing thread doesn't come through.

Frequently asked questions

How do I measure ROAS for ads that send people to WhatsApp?

With two pieces of data: which ad opened each chat and how much was sold afterwards. heysteff reads the referral Meta attaches to the first message, matches that conversation with Shopify orders over the next 30 days and, if you connect your ad account with read-only permission, divides those sales by the ad's spend, as long as both currencies match.

How do I know which Meta ad a WhatsApp chat came from?

Meta says so in the first message: click-to-WhatsApp ads carry a referral with the source ad. heysteff stores it when the message arrives and shows it in the thread's "Origin" strip and in the Sales report. Without the ad account connected you see the ad's title; with it, the campaign too.

How do I add UTM tags to a WhatsApp link?

With a heysteff tracked link: you create it with your UTM parameters and every click leaves a 6-character code at the end of the prefilled text. When the person sends that message, heysteff recognizes the code, removes it from the text and ties the conversation to the link and its UTM tags.

How long after the chat does a sale still count for the campaign?

Up to 30 days: a sale takes the last origin of that customer's conversation within the 30 days before the purchase. That's slightly longer than the 28 days Meta uses to measure messaging ads.

What if a customer comes from an ad and then replies to a story?

The ad wins. When a conversation has several signals in the same window, it keeps the highest-priority one: ad, then tracked link, story and post. If the customer writes again within 7 days without a new signal, the conversation still counts for that ad.

Do I need Shopify to see sales by campaign?

For sales, yes: they come from the orders in your connected Shopify store, which is included from the Pro plan and in the Shopify app plans. Conversation origins, on the other hand, are recorded on any plan and supported channel, with or without a store.

◆ next step

Connect your channels and see where each customer comes from, starting with the first chat.

Start free → Get a demo See pricing