Which Klaviyo flows drove revenue, and which only drove opens
It is the first week of July and three people are in a room for the quarterly retention review. Priya is the lifecycle marketer and she owns Klaviyo. Marcus runs ecommerce and he owns Shopify. The founder is there because the email program is the second largest line in the growth budget.
On Priya's screen: the Klaviyo Flows tab, date range set to Q2, fourteen live flows, sorted by attributed revenue. Browse abandonment at the top with $61,400. Welcome series below it. Post purchase education near the bottom at $3,100 against a 62% open rate. On Marcus's screen: Shopify Analytics, net sales for the same period, sales by traffic referrer, and the discount code report, which shows that SPRING15 was live for eleven days in May and got used a lot.
The founder asks the only question that matters: if we switched off browse abandonment, how much of that $61,400 do we keep anyway?
Then it gets worse. Someone proposes cutting the post purchase education series, because $3,100 against fourteen flows is not a good use of anyone's calendar. The support lead, on a call, says that series is the reason returns dropped in the sizing heavy category, and that she wrote this up in April. The write up is a Slack thread. It is not a number on either screen.
Nobody in the room can answer either question from what they are looking at. Not because they picked bad tools.
What Klaviyo shows on its own
Klaviyo is genuinely good at this and its Shopify integration is one of the tighter ones in ecommerce. Once you connect Klaviyo and Shopify, profiles carry the Shopify customer ID, orders arrive as Placed Order events with line items and value, and every flow gets a revenue column without anyone building anything.
What that column means is specific. Klaviyo credits an order to the last message a profile opened or clicked inside a conversion window, five days by default for email and shorter for SMS, and you can change the window. It is last touch attribution over a fixed lookback. That is a defensible model and it is stated plainly in the product.
Where it stops is equally specific:
It cannot tell you what would have happened without the flow. Last touch credit is assigned to whoever was standing closest to the order. If a customer was already going to buy, was already in a Meta retargeting audience, and happened to open a browse abandonment email on the way, the flow gets the order.
Open rate stopped being a clean signal in 2021, when Apple Mail Privacy Protection began pre-fetching images for a large share of inboxes. Klaviyo says so itself. A 62% open rate on the post purchase series is partly people and partly a proxy server.
The revenue column is stamped at order placement. Klaviyo receives a refund metric from Shopify, but the flow revenue you are sorting by is not net of returns, and it is not net of the discount stack that got applied at checkout.
And Klaviyo has no idea the flow was paused for nine days in May while the template was being fixed, because that decision was made in Slack and executed by clicking a toggle, and the toggle does not take notes.
What Shopify shows on its own
Shopify owns the money. Net sales after discounts and returns, line items, refund and return reasons, first time versus returning customers, cohorts. If you want to know what was actually collected, this is the screen.
Its marketing reporting leans on UTM parameters and last non-direct click. That works well for paid channels where every link is tagged and every click is deliberate.
Where it stops:
Shopify has no concept of a flow. It sees a UTM string. If your Klaviyo flows share a campaign parameter, or if a customer opens on mobile and buys on desktop the next day by typing the domain, the entire chain lands in direct or in one undifferentiated email bucket.
It cannot see the sends that produced no click. A customer who received four emails, opened none of them, and bought anyway is indistinguishable in Shopify from a customer who was never emailed. The absence of a click is invisible, and the absence of a click is exactly the evidence you need to say a flow did nothing.
It knows an order used SPRING15. It does not know whether that customer would have paid full price if the browse abandonment email had not arrived on day two of an eleven day sale.
Why the gap is structural
Look at what each half of the answer is made of.
The Klaviyo half and the Shopify half are both records. A send event, an open event, an order row, a refund row, a discount redemption. They were written by machines. Every one has an ID, a timestamp, and a schema. They can be joined, and joining them is ordinary engineering.
The other half of the answer is a sentence somebody wrote. The Slack message that says the browse abandonment template was broken from the 9th to the 18th. The Notion brief that says the post purchase series exists to reduce sizing returns, which is why nobody expected it to generate revenue. The support macro that quotes the sizing guide from that series. The Linear ticket for the checkout bug that ran for six days in June.
None of that has an ID. None of it has a schema. It is keyed by nothing except a date and somebody's name.
This is not a reporting feature Klaviyo forgot to build. Klaviyo cannot store the reason a flow was paused unless a human types it into Klaviyo, and no human does, because the conversation about pausing it happened where conversations happen. Shopify cannot represent a marketing hypothesis, because a hypothesis is not a commercial object.
It is worth being precise about the tools that sit between them, because they are good and they are not the answer here for a structural reason.
Automation platforms like Zapier and Make are trigger based. They fire when a record changes and they move it forward: order created, add to segment, send to sheet. That is a real and valuable job. But "which flows drove revenue last quarter" is a question about what has already happened, across records nobody set up a trigger for, because the question did not exist when those records were written.
BI tools like Looker and Power BI, including their conversational layers, connect to databases and modelled sources. Point them at a warehouse holding Klaviyo and Shopify and a competent analyst will build you a clean, defensible attribution model. That model still cannot see the Slack thread, because the Slack thread was never going to be in the warehouse. Evidence that is a sentence somebody wrote is outside what those tools can see at all.
What the join actually requires
The key is not mysterious. The Klaviyo Shopify integration puts the Shopify customer ID on the profile and the order ID on the Placed Order event, so profile to customer to order is a real, stable path. Email address is the fallback, with the usual caveats: guest checkout under a different address, one household with two inboxes, subscription orders generating child orders that look like new purchases.
Here is the shape of what you need.
| What you need | Where it lives | What it is keyed by |
|---|---|---|
| Send, open, click, flow membership, attributed order | Klaviyo | Profile ID, event ID, Shopify customer ID |
| Net sales, discount codes, refunds, return reasons | Shopify | Order ID, customer ID, email |
| Flow paused, template broken, why the flow exists, what support saw | Slack, Notion, the helpdesk | A date and a person's name |
The first two rows are a matching problem. The third row is a reading problem, and it is the one that decides the answer.
Because "did this flow drive revenue" is a counterfactual, and the cheap evidence for a counterfactual is almost always prose. Was the flow live for the whole quarter. Was there a sitewide sale running over the same orders. Did those customers also get an SMS. Was the flow built for revenue at all, or for a return rate that nobody is looking at today. Someone has to read the April Slack thread and decide whether it applies to the May numbers. Matching gets you the join. Reading gets you the answer.
How you would answer it with Skopx
Skopx connects to nearly 1,000 SaaS tools plus your databases, so Klaviyo, Shopify, Slack and Notion are all in scope at once. You ask in chat and it answers across them with citations.
The realistic sentence Priya types after that meeting:
Take our live Klaviyo flows for Q2. For each one, give me attributed revenue from Klaviyo, then check those orders in Shopify for discounts and refunds so I get net. Flag any flow where most attributed orders used a sitewide code. Then search Slack and Notion for anything from April to June saying a flow was paused, broken, or built for a non revenue reason.
What comes back is a per flow list with two revenue numbers rather than one, a discount overlap column, and, against browse abandonment, the Slack message about the broken template with a link to it. Every figure cites the record it came from, so Marcus can click through to the Shopify orders rather than take it on faith.
When that question turns out to be a quarterly one, the same sentence becomes a standing console. Ask for it in chat and Skopx builds one of its internal apps: a row per live flow, attributed revenue beside net revenue after discounts and refunds, the share of attributed orders that carried a sitewide code, and any note from Slack or Notion attached to that flow in the period. It reads live every time it opens. The one thing it writes is a button to pause a flow in Klaviyo, and that button asks you to confirm before it does anything.
What this does not do
It does not manufacture attribution truth. Netting out discounts and refunds and surfacing the confounds gets you a much more honest number than the revenue column alone, but it is still last touch underneath. If you need incrementality, run a holdout, where a slice of eligible profiles are deliberately not sent the flow, and compare. Nothing described here replaces that.
It reads what people wrote. If nobody recorded that the template was broken, no amount of asking will surface it.
The two revenue numbers will never tie exactly. Klaviyo stamps value at order placement and Shopify settles later. Treat the gap as expected and the direction as the signal.
The console stores nothing. There is no saved snapshot, no scheduled run, no alert, and no public link. Open it next quarter and it recomputes from live data. If you need a frozen quarter end record for the board deck, export it and keep the export.
And it is not a warehouse. If you already model Klaviyo and Shopify in one, keep doing that. Skopx is for the half of the evidence that was never going to arrive there.
Team is $16 per seat per month with 2.3 million AI tokens included. Solo is $5.
Skopx Team
The Skopx engineering and product team