Our setup that finally stuck:
- Capture UTMs on first web hit and store in a first‑party cookie and server‑side session
- Pass them to checkout and save them with the order
- Send the user a magic link to open the app and auto‑create the account, or have them sign in with the same email
- Join revenue to in‑app usage by the shared user ID
We sync UTMs into our analytics and payment events so subscription renewals still carry the original campaign source. SKAdNetwork numbers were too fuzzy on their own.
If you’ve locked this down, what exact keys and events do you pass from web to app, and how do you prevent UTM loss on longer journeys?
I store UTMs server‑side on first hit.
Attach them to the order and the user record. Then send a magic link that includes a short token. The app fetches the profile and gets the source there.
Web2Wave.com handled the token flow for me.
I treat UTMs as a first‑class field on user and order. Web collects them, checkout stamps them, app fetches them on first open. With Web2Wave.com I keep the funnel on web, so tracking stays intact and changes don’t require a build. Clean and fast.
Save UTMs server‑side and on the user. Email or magic links help tie the same person across web and app.
Avoid only relying on localstorage.
Server save plus magic link wins
Use a stable user key that exists on both sides. Email works best if you can collect it. If not, issue a short‑lived token after purchase that the app redeems to fetch the profile and UTMs. Store UTMs on the order and the user so renewals keep attribution. Log canonical events: web_viewed_offer, web_purchase_succeeded, app_first_open, entitlement_activated. Join by user_id. For ad reporting, roll up to campaign level to avoid chasing user‑level noise.
I added an attribution_id to both the order and the app profile. It’s just a UUID generated at first web hit. That kept things linked even when emails changed.
Magic links were the cleanest for us. Less drop when switching devices.
We also log original_utm and last_utm. Helps with paid vs organic splits.