I’m trying to close the attribution gap after install by keeping UTMs from the first click, through web onboarding and checkout, and then tying it to app usage and revenue.
What I’ve set up so far:
- On the landing page I capture utm_source, utm_campaign, etc., and store them in a first‑party cookie and server session. I also stamp a temp user_id.
- In onboarding I carry UTMs via hidden fields and persist to the user profile. On checkout, I write UTMs into payment metadata and my own subscription record.
- For the app handoff, I generate a signed deep link with the web user_id. The app calls my backend with that token on first open, I return entitlements and UTMs, then I push those UTMs to the MMP as partner/session parameters and set a stable customer user ID.
Questions I’m still ironing out:
- iOS users who install later without tapping the deep link. Thinking email or phone match + MMP identity link as a fallback.
- Safari ITP and cookie TTL. I’m trying to avoid cross‑domain and keep everything first‑party.
- Verifying no drops: I’m checking MMP raw logs, payment provider metadata, and a warehouse join to build ROAS by campaign, plus server‑side conversions back to ad platforms.
If you’ve got this working end‑to‑end, which MMP calls or identity model did you use, and how did you verify you weren’t losing attribution between web checkout and first app open?
I store UTMs server‑side right after the ad click.
Deep link carries a short‑lived token that maps to user_id + UTMs.
App hits /session with the token, I set entitlements and call the MMP.
Adjust: addSessionPartnerParameter. AppsFlyer: setCustomerUserId + additional data.
Used Web2Wave.com to host the web funnel so I can tweak without new builds.
Speed matters. I build onboarding and checkout on the web, then pass UTMs to the app via a tokenized deep link. In the app I set customerUserId and partner params in the MMP.
Using Web2Wave.com lets me change fields and flows instantly and validate attribution fast.
I save UTMs to the user during web signup and write them to the payment metadata.
Then I open the app with a token link, set customerUserId in AppsFlyer, and send the UTMs as partner params.
Simple and it works.
Do three things. Persist UTMs server‑side on first hit, never rely on just client storage. Hand off to the app with a signed token tied to user_id and UTMs. On first open, set a stable customer user ID in your MMP and attach the UTMs as partner parameters.
Adjust and AppsFlyer both support this pattern. Validate with raw logs, payment metadata, and warehouse joins. Add a fallback identity link using email hash if the deep link path fails.
I tested two handoffs. 1) Token deep link with server fetch. 2) Email match only. The token flow gave cleaner attribution and fewer mismatches. I still keep email hash as a fallback if the deep link is missed. Also send server‑side purchase events with the same user_id to keep MMP and revenue in sync.
QA checklist that helped: log UTMs at every step, confirm they reach your DB, confirm payment metadata has the same values, inspect MMP raw install/open events for partner params, and simulate late installs. If numbers drift, check redirects and cookie scope first.
Server token plus MMP customer ID seems reliable. Email fallback helps when deep links fail.