Skip to main content

Install → Onboarding Funnel & Cross-Surface Identity

This page is for the growth team. It explains the funnel events, which surface and identifier owns each one, how the website and desktop journeys merge into a single Amplitude user, and the limits of that merge.

The funnel

HabitatZero Download Started → HabitatZero Desktop App Installed → Onboarding Started → Onboarding Completed
EventSurface that emits itIdentifier before mergeWhen
HabitatZero Download StartedWebsite (apps/frontend)web device_id W (anonymous)Visitor clicks a /download/mac or /download/win link. Carries platform (mac/windows).
HabitatZero Desktop App InstalledDesktop (apps/desktop)desktop device_id D (anonymous)First app launch after install, once per installation.
Onboarding StartedDesktopfirebaseUserId (identified)After Google sign-in, first tracked session.
Onboarding CompletedDesktopfirebaseUserId (identified)Permission screen marks onboarding complete.

App Open (every launch) and On App Background (window hidden) are also emitted by desktop but are not funnel steps. Install via Referrer is a separate cross-promo acquisition event (once per attributed install), named to match the Fabulous/iOS data repos.

How the surfaces merge into one user

There are two anonymous Amplitude device_ids and one user_id that unifies them. The merge key is always firebaseUserId — the Firebase Auth user id. Both desktop (setUserId(firebaseUserId) at sign-in) and the backend Identify call use this exact id. A Google sub, email, or internal database id would silently fail to merge.

  • Desktop → user (reliable). The anonymous desktop events on device_id D (App Installed, App Open, On App Background) re-associate to the user when the desktop calls setUserId(firebaseUserId) at sign-in. No cross-surface work is needed; this always connects.
  • Website → user (best-effort). At the Google /auth-start bridge — opened in the same browser as the website visit — the web device_id W is forwarded to the backend, which calls Amplitude's server-side Identify with { device_id: W, user_id: firebaseUserId }. This merges Download Started (and the website visit) into the same user.

Attribution limitation (read this before trusting website→install numbers)

The website → install link only works when Google sign-in starts in the same browser context as the download. It will undercount when:

  • the user downloads in one browser and signs in from another,
  • the browser is in incognito/private mode,
  • storage was cleared between download and sign-in, or
  • the Amplitude SDK's storage is blocked.

In all those cases the install → onboarding funnel (desktop only) still works fully — only the website → install join undercounts. Treat website attribution as a floor, not an exact count.

Mac vs Windows interpretation

App Installed fires at first app launch, the industry-standard proxy for install (the DMG/installer has no analytics SDK).

  • Windows: the NSIS installer auto-launches the app on finish, so first launch ≈ install completion — a tight proxy.
  • macOS: no auto-launch — the user drags the .app from the DMG and launches it manually (possibly later), so App Installed ≈ first manual launch. Some users drag but never launch; those are unmeasurable.

Amplitude auto-captures the OS, and desktop events report platform as macOS or Windows (web surfaces stay Web), so segment the funnel by OS/platform to compare the two side by side.

Expected one-time bump

There is intentionally no migration guard for users already installed when this release ships. The installed base is small, so the first launch after upgrading may emit App Installed once for existing users. Discount the release-week spike when reading the funnel.

How to validate the merge

In Amplitude User Lookup on staging, with a single browser:

  1. Click a download link on the website (fires Download Started).
  2. Launch the desktop app and sign in with Google (same browser for the /auth-start bridge).
  3. Confirm one Firebase user_id shows HabitatZero Download Started, HabitatZero Desktop App Installed, Onboarding Started, and Onboarding Completed together.

If the website event does not join, check that sign-in happened in the same browser as the download and that the SDK could read its stored device_id.