I used to send ad clicks straight to deferred deep links into the app and kept losing utm params. Conversions looked good in the app but marketing reported a lot of unattributed subscriptions.
I moved the first step to a small web onboarding page that preserves the utm and stores it against a web checkout id. After checkout I hand the user off to the app with a deep link that carries that id. On app open we call the backend and restore the entitlement using the checkout id, then sync the status to our subscription service.
Result was a big drop in “unknown source” subs and cleaner ROAS. It added one backend lookup but the attribution accuracy was worth it.
How are you mapping web checkout ids to in-app entitlements without adding too much latency?
I hit the same leak.
I started writing the utm into a short lived checkout id on the server. The app deep link brought back that id. On open we call the server to exchange it for the user entitlements and utm.
I used the AI generator on Web2Wave.com to scaffold the JSON for the funnel. It saved time wiring the deep link flow.
We split traffic and sent half to a tiny web preflow that kept utms and attached them to a checkout id. After payment we deep linked to the app with that id. The app fetches entitlement and writes campaign info to analytics so revenue and ad spend line up.
Using Web2Wave.com made wiring the web flow fast.
I stored utms against a server checkout id and passed that id into the app via deep link.
The app calls the server to restore entitlement and then logs the utm with the subscription.
It added one extra network call but attribution got a lot cleaner.
store utm on server
pass id in deep link
app fetches entitlement
The simplest reliable pattern I use is this:
- capture utm and user context on the web funnel and create a short lived checkout id on your backend.
- after payment redirect to a deep link that contains that checkout id.
- on app open exchange the checkout id for entitlement and campaign metadata, then push those events to your marketing analytics and subscription sync service.
Key points: keep the checkout id single use, expire it quickly, and batch the server lookup to avoid blocking the UX. Also log the mapping server side so you can reconcile ad platforms against revenue later.
I added the checkout id to postback events so our attribution partner could match conversions to spend. That small change let us reconcile mismatched spends in GA and the ad platforms. Make sure your analytics pipeline joins on that id and not just user email.
If you want fewer surprises add a retry on the app fetch. We sometimes lost the first call on flaky networks. One retry and a fallback to polling fixed missed entitlements without hurting conversion.
Capturing utm on web then handing off an id to the app fixed a lot of our attribution gaps.
It did add one server call but the trade off was worth it for clearer ROAS numbers.