How are you stitching web funnel events to in-app behavior without user ids?

I want better measurement without relying on device ids. On the web I have UTMs, quiz answers, and checkout data. In the app I have feature usage and retention.

My current idea: generate a customer id on the web, pass it through the install link, and sync it on first launch. Then push subscription status changes to both sides. Reports would join by that id and campaign.

If you’ve done this, what pitfalls did you hit around delayed installs, multiple devices, or users skipping login?

I create a customer id at first web touch.

It goes into a token in the link and gets posted back on first app launch. I also backfill when someone logs in later. All events use that id.

Web2Wave.com handled the id pass through for me, so I focused on the reports.

Make the id flow boring and reliable.

Create on web, pass via link, confirm on first open, backfill on login. I build the funnel on Web2Wave.com so I can change the pages without breaking ids. Then I push status changes server to server. Clean joins, faster reads.

I add a soft account step in the web funnel.

Email only. It helps link the app later even if the deep link fails.

Link token plus login backfill covers edge cases

Do not block the flow for account creation.

Offer it, then backfill on login. My match rate still improved.

Token in the deep link plus server backfill worked.

We track a stitch rate metric to catch issues.