Measurement in a superapp breaks at the boundary between the native shell and its WebView services, in four places: the deep-link hop, the WebView where paid and internal traffic mix, growth stuck on registration, and someone else's in-app browser. Three rules hold across all four: capture the signal at the earliest init, because it exists for a few hundred milliseconds; gate paid attribution to ad-origin sessions; send the money event server-side.
Most measurement advice assumes one of two worlds. Either you have a website - cookies, a pixel, a browser you control - or you have an app, with an SDK and an MMP and a device identifier. Superapps are neither. A superapp is a native shell with a few dozen services living inside it as WebViews, each on its own domain, reached through a deep-link router, behind a session the shell owns and the web page doesn't.
Everything breaks at that boundary. Not dramatically - that's the problem. Nothing throws an error. The pixel loads, the events fire, the dashboards populate, and the numbers are wrong in ways that take a quarter to notice and another quarter to explain.
1. The hop: getting the user in without losing where they came from
Someone taps an ad. If the app is installed, a deep link opens the shell, which opens a WebView on a service domain. Somewhere in that chain - the ad platform's redirect, the router, the Universal Link, the WebView launch - the click ID is dropped, and the session lands in Organic.
This is the first problem because it's upstream of everything else. No source at the door means no source anywhere downstream, and no amount of clever work inside the service can recover it.
→ Deep links for a Halyk-class SuperApp: WebView services, cross-auth, and lossless UTM/MMP attribution - the link contract, cross-auth across domains, and how to carry UTM and MMP data across the hop without losing it.
2. Inside: telling paid traffic apart from the superapp's own
Once the WebView is open, every session looks identical - the ad click, the tap from the app's own menu, the storefront banner. And the internal traffic converts at rates paid traffic never will, because those users are already customers who are already logged in.
Mix the two and you get the most expensive failure mode in the set: an inflated conversion rate on the paid segment, bids that drift upward chasing it, and an algorithm optimising toward people advertising never brought in. The reporting looks great the whole time.
→ Attribution inside a SuperApp WebView: getting the source into Amplitude without polluting the paid channel - reading the launch URL before the router wipes it, gating the MMP attribution to ad-origin launches only, and running the money on a separate server-side layer.
3. Growing the shell itself, past the install
The app-growth side has its own trap. Campaigns get pointed at install and registration, because those are the events the SDK gives you for free - and then the whole media budget optimises toward people who complete KYC and never transact again. Registration is not the product; it's the turnstile.
→ A SuperApp cannot be grown on KYC alone: Firebase events, a value model, and tROAS for product growth - the event set past registration, building a value model that reflects what a user is actually worth, and moving campaigns onto tROAS.
4. The mirror image: someone else's in-app browser opening your site
The same structural problem arrives from the other direction when TikTok or Instagram opens your site inside their WebView. You're now the service inside someone else's shell, with their cookie handling, their referrer behaviour, and their limits on your stack.
It reads as a different topic and it isn't - it's the same boundary, with you on the other side of it.
→ When TikTok and Instagram open your site inside the app: keeping attribution, events, and CAPI working without hacks - what actually survives an in-app browser, and how to keep attribution and CAPI intact without user-agent hacks.

What holds across all four
Read them together and the same three rules keep surfacing, from four unrelated directions.
Capture at the earliest possible moment, then pin the value down. The launch URL is rewritten by the SPA router on first navigation. The click ID is dropped by a redirect. The referrer is gone by the time an in-app browser finishes loading. In every case the signal exists for a few hundred milliseconds and then doesn't, and the fix is always the same shape: read it at the earliest init available and write it somewhere it can't be overwritten. Lazy capture loses the thing you needed.
Gate the paid signal deliberately. Attribution parameters belong on ad-origin sessions and nowhere else. Stamp them on every session - because it's easier, because the MMP will happily hand you a stale value from an earlier attribution - and internal traffic quietly floods the paid segment. This one costs real money and is close to invisible in reporting; the numbers just look better than they are.
The money event goes server-side. Browser ad stacks inside a WebView are frequently switched off by the shell's own kill-switch, and the WebView is where most transactions happen. A pixel that isn't loaded can't report revenue. Push conversions from the backend, dedup them on a single ID generated at the source of the action, and the browser stack stops being load-bearing.
And underneath all three sits a naming problem, which is the boring one nobody writes about: none of this works if purchase means six different things in six different services. Consistent events across a superapp's product portfolio are the substrate the rest of it runs on - collapsing a sprawling one is its own piece of work, and its own article.
Where to start
If you're standing in front of a superapp measurement stack and don't know which end to pick up:
- Check whether the source survives the hop. Look at the share of installs and sessions landing in Organic. If it's implausible, start with piece 1 - nothing downstream is trustworthy until it's fixed.
- Check whether
adj_*-style attribution parameters appear on internal navigation. They should be at zero. If they aren't, your paid segment is diluted right now and piece 2 is the fastest money you'll save. - Check whether revenue is reported by a browser pixel inside the WebView. If it is, find out whether that pixel is even loading. Frequently it isn't.
- Only then worry about campaign structure and bidding. Piece 3 assumes the first two are sound; a value model built on mixed traffic is a confident wrong answer.
FAQ
Which of the four problems should I fix first?
Start with the hop. Look at the share of installs and sessions landing in Organic; if it is implausible, the source is being dropped between the ad and the WebView, and nothing downstream is trustworthy until that is fixed. Then check attribution parameters on internal navigation, then whether revenue comes from a browser pixel inside the WebView. Campaign structure and bidding come last.
How do I tell paid sessions from the superapp's own traffic inside a WebView?
Not by looking at the session: once the WebView is open, an ad click, a tap from the app menu and a storefront banner look identical. The answer is a deliberate gate. Attribution parameters go on sessions launched from an ad and nowhere else. If they show up on internal navigation, the paid segment is already diluted by logged-in customers.
Why can't a browser pixel inside the WebView report revenue?
Because it is frequently not loaded at all. The shell's own kill-switch often turns off browser ad stacks inside the WebView, and the WebView is where most transactions happen. A pixel that is not loaded cannot report revenue. Push conversions from the backend instead and dedup them on a single ID generated at the source of the action.
Does any of this apply when TikTok or Instagram opens my site?
Yes. It is the same boundary from the other side: inside their WebView you are the service in someone else's shell, with their cookie handling, their referrer behaviour and their limits on your stack. The referrer is gone by the time an in-app browser finishes loading, so the same rule applies: capture early and pin the value down.
Seeing this in your own funnel?
Two weeks, fixed scope, read-only access. You get the findings and a 90-day roadmap whether or not we work together afterwards.
