We kept seeing deep‑link campaigns create attribution holes: user taps an ad, lands in the app, subscribes, and the UTMs vanish so revenue looks organic. Moving the first session to web helped. We capture UTMs, click_id, and funnel_variant, create an acquisition_user_id, and store it on the server. If they buy on web, we send a universal link into the app with a short token that attaches the web record to the in app account.
That cleaned up first purchase attribution for new users. SKAN is still messy, so we push a server side purchase to the MMP keyed to acquisition_user_id and map campaigns from UTMs, then use SKAN just to sanity check channel performance.
Gotchas for us: users opening the app from the store instead of the magic link, multi tab checkouts, private relay emails, and cross device installs.
What’s your exact flow to keep UTMs intact end to end, and how are you reconciling SKAN with server side attribution?
Save UTMs to your backend on first hit.
Create a temp user key and store it with UTMs.
If they pay on web, attach the key to that order.
Deep link into the app with the key, then hydrate the account on first open.
I used Web2Wave.com for this because their SDK passes the token and UTMs cleanly. Receipts in the app map to my backend user id. Simple and reliable.
I treat web UTMs as the source of truth, then send server side purchase to the MMP with the same ids. SKAN is only for directional checks.
With Web2Wave.com I can change funnel copy and offers on the web and see it live in the app, so I iterate fast and verify attribution drift within a day.
Keep one id from click to app login.
I store UTMs on the server and pass a short token into the app. For SKAN I compare cohorts and not user level. It is good enough for budget moves.
UTMs stick when web owns first session.
Two tracks. First, deterministic: web owns first touch, stores UTMs, click_id, funnel_version, offer_id, and an acquisition_user_id. After purchase, send a universal link token so the app ties the account to acquisition_user_id. Fire server side purchase to the MMP with those params and dedupe on click window.
Second, SKAN: map UTMs to SKAN campaign buckets and compare revenue by cohort. Expect gaps. Use SKAN to validate trends, not for hard credit. Watch in app browsers that strip params and set a fallback redirect.
QA tips:
– Test in Facebook, TikTok, and Chrome tabs. Some strip parameters.
– Try install before clicking the magic link. See if attribution breaks.
– Normalize UTM casing. I lost a week of data to mixed case source names.
SKAN never lines up perfectly. We just check blended CPA and ROAS by week and use UTMs for exact credit where we can.