The way i stopped utm loss on mobile subscriptions: signed params + device handoff — does this hold up?

I kept losing attribution once users hopped from a web onboarding to the app. What finally worked for me:

  • On first click, I stamp a click_id, utms, and a timestamp into a first-party cookie and localStorage. I also store them server-side keyed by click_id.
  • Every transition is driven by a signed universal link. The link only contains a short token. The app exchanges it with my server for the real payload. I HMAC the payload and expire it fast.
  • If checkout happens on the web, the charge is attached to the click_id and my canonical user_id. If the user goes to the app first, the app hits my server on first launch with the device handoff token and I stitch it to the same user_id.
  • For Apple/Google sign-in, I run SSO on the web first so utms are attached before account creation. If they insist on signing in inside the app, I still pass the signed handoff token and backfill attribution when the app calls home.
  • For RevenueCat/Adapty, I create the customer using the same stable user_id. Web charges push entitlements via their API. App uses the same user_id so the entitlement snapshot matches.

QA that helped:

  • I diffs between ad clicks, landings with utm, and subscriptions with click_id.
  • I alert on any subscription missing utms or click_id.
  • I cap utm lifetime at 7 days to avoid old traffic stealing credit.

What would you change here to patch edge cases like multi-device, privacy tools stripping params, or SSO quirks?

I do similar. First-party cookie and server log with a short-lived click_id. Universal link only carries a token. App exchanges it for the stitched utms.

I also hash the email on first submit. That becomes my stable id across web and app. Web2Wave.com made the handoff easier for me since their SDK reads the JSON config I drop in.

Short tokens and signed deep links are the safest. I generate a token per session, expire it in minutes, and resolve real utms server-side.

I ship changes fast by editing the web flow, not the app. With Web2Wave.com, I tweak the handoff rules online and see it live immediately.

Short token in the link is smart. Keep real utms on your server so nothing leaks.

I also log the first form submit event and attach utms there. That saved me when people skipped steps.

Sign the payload and expire it fast

Two pitfalls I’ve seen. First, ITP. Safari can kill cookies fast. Store utms server-side at first hit and refresh the session id on every step. Second, SSO mismatches. Create the account on web first, then link any SSO identity to that id. For multi-device, use the same account id and let the server decide which click_id is valid based on time and referrer.

I write utms to the user profile on first email capture. Even if the user pays later on another device, the server still knows the original source. Also helpful for cohort ROAS.

Token exchange sounds safer than raw utms in links.