Tracking a PWA funnel means attributing four events that happen after the click, sometimes days after it, to the click that paid for them: the install, each launch, the push subscription and the conversion. The method is the same one you already use for landers and offers, a click ID that travels through every stage, extended with three extra beacons from the app itself. This article explains how the attribution works, how to set it up, which metrics to watch and what the common breakages look like.

Quick answer

  • Install: reported by the app with the click ID; Android uses the browser's install event, iOS uses the first standalone open.
  • Launch: the app calls the tracker with the click ID; the tracker records it and redirects to the offer.
  • Push subscriber: the subscription is stored with the click ID, campaign and language.
  • Conversion: the network postback carries the click ID back, as with any lander.
  • Reports: visits, LP views, installs, launches, subscribers, conversions and revenue per app, plus install and launch fields per click in the click log.

The click ID is the spine

Everything hangs on one identifier. When a user clicks your ad, the tracker creates a click ID, 25 characters in BATracker, and stores the click with its campaign, path, traffic source, geo, device and sub IDs. The tracker then redirects to the PWA page with the click ID in the query string.

Because the tracker serves the PWA page, it can do three things a static host cannot:

  1. Write the click ID into the manifest's start URL, so the installed app opens with ?launch=1&cid=<click id>.
  2. Keep the click ID in the page's local storage as a fallback.
  3. Accept beacons from the app that carry the click ID and update the stored click.

That is the whole trick. The app does not need an SDK or a device identifier. It knows its click because it was born from it.

The four tracked events

Visit and LP view

The visit is the tracker redirect itself, recorded like any lander visit. The LP view fires when the page has loaded and the engine has booted, which tells you the page actually rendered. A large gap between visits and LP views points at slow pages, blocked scripts or in-app browsers that never finished loading.

Install

On Android, Chrome fires appinstalled when the user accepts the install dialog. The engine sends a beacon to the tracker's install endpoint with the click ID. The tracker marks the click as installed with a timestamp. The beacon is idempotent, so repeated signals from the same install do not inflate the count.

On iOS there is no install event, so the engine treats the first open in standalone mode (full screen, from the home-screen icon) as the install. The same idempotent beacon is sent.

Because the install is stored on the click, you can group installs by anything the click already carries: campaign, zone, creative, country, OS, browser, hour of day.

Launch

Every time the user opens the icon, the app opens at its start URL with the click ID. The engine shows a splash and, on the first launch, the notification gate. It then calls the tracker's launch endpoint with the click ID. The tracker:

  1. Looks up the click. If it exists and belongs to the same workspace, it records a lander-to-offer click on it, which is the same field used when a visitor clicks the call to action on a normal lander.
  2. Redirects to the offer that was selected for this click when it was first processed, with tokens such as {click_id} and {sub1} filled in.
  3. If the click has expired from hot storage (BATracker keeps click data for 90 days and renews it on every launch), it redirects to the app's fallback CTA URL instead, or shows a short "unavailable" page if none is set.

Launches therefore appear in the standard reports as LP clicks on the PWA lander, and the app's stats tab shows them as launches.

Push subscription

When the user grants notification permission, the app sends the push subscription to the tracker with the click ID. The tracker stores the subscriber with the click, campaign, language and user agent, and from then on every launch re-sends the subscription so a failed first attempt is repaired. If a subscription cannot be created, the reason is reported and shown in the app's Push tab. The push notifications article covers the permission flow and failure reasons.

Conversion

The launch redirect delivers the click ID into the offer URL. The network fires its postback with that ID, the tracker attributes the conversion and revenue to the click, and because the click is marked as a PWA install with launch counts, the conversion is now attributable to an install. Nothing changes in your postback setup; the S2S postback guide applies as is.

Setting it up in BATracker

  1. Domain. Add and verify a custom domain for the app. SSL is automatic.
  2. App. Create a PWA App on that domain, either from the template builder or by uploading your own page. Publishing creates a lander of type PWA automatically, pointing at https://<domain>/app/<slug>/.
  3. Campaign. Create a campaign with a path that uses the PWA lander and your offer. Apply the traffic-source preset so the source's parameters map to sub IDs.
  4. Offer URL. Make sure the offer URL carries {click_id} in the parameter your network uses for the postback, for example tid={click_id} for ClickBank-style networks or s1={click_id} on many CPA networks.
  5. Postback. Set your BATracker postback URL in the network, returning the click ID and payout.
  6. Test on a phone. Open the campaign URL on Android: install, open the icon, confirm the browser lands on the offer with the click ID in the URL. Open the app's Setup and Stats tab: visits 1, LP views 1, installs 1, launches 1. Repeat on an iPhone through add-to-home-screen.
  7. Fallback. Set the app's fallback CTA URL, ideally a direct-link campaign URL for the same offer with a sub ID that marks it as a fallback, so dormant installs still produce tracked clicks after the hot click data expires.

The metrics that matter

Metric Formula Why it matters
Install rate installs / LP views Quality of the page and the traffic; compare by OS and source
Launch rate launches / installs Whether installed users come back; the point of the format
Launches per install total launches / installs over 7 and 30 days Re-engagement strength; rises with good push
Subscriber rate push subscribers / installs Gate wording and timing; audience size you can message
Cost per install cost / installs Bid and zone decisions
Cost per launch cost / launches The real cost of a visit to the offer
EPC on PWA traffic revenue / visits Compare against a direct-link path on the same traffic
Revenue per install revenue / installs The number that justifies the extra funnel step

Two reading rules. First, give the PWA path at least a week before judging it against a direct link, because launches, pushes and their conversions arrive over days. Second, split every metric by operating system: iOS will show lower install rates and higher launch quality, and mixing the two hides both facts.

In BATracker the app's stats tab shows visits, unique visits, LP views, installs, launches, conversions, revenue and cost per day for 1 to 90 days. The campaign reports show the same traffic grouped by any dimension, and the click log lists the install and launch fields for each click when you add those columns. Conversions attributed to installs appear in the conversion log with the originating click's campaign and sub IDs.

Common breakages and how to spot them

Visits but no LP views. The page did not finish loading or the engine did not boot. Causes: a bundle that still includes its own old service worker or install script, root-relative asset paths that break under /app/<slug>/, or traffic from in-app browsers. BATracker's bundle checker warns about the first two at upload time and rewrites root-relative paths.

LP views but few installs on Android. The install button is not bound to the engine (mark it with data-pwa="install"), the page is not served over a verified domain, or the traffic is from in-app browsers where Chrome's prompt does not exist and the page must open itself in Chrome first.

Installs but no launches after several days. Either users never opened the icon, which is a creative and push problem, or an older service worker from a previous build is serving stale files. Republish the page so the service worker's cache name changes, which forces installed apps to refetch.

Launches but no conversions. Check that the offer URL includes the click ID token and that the network postback is firing; both are visible in the click log and conversion log. A launch redirecting to the fallback URL rather than the routed offer means the click expired from hot storage, which happens after 90 days without a launch.

Installs without push subscribers. Look at the Push tab's missed-subscriptions card for the reason split. Mostly permission not granted (fix the gate) or push service refused (device mix).

Duplicate installs. Reinstalling the same app from the same click is one install; the beacon is idempotent. Installing from a new click, for example after a new ad click, is a new install on a new click, which is correct: you paid for that click too.

Privacy and data notes

The PWA tracking described here uses the tracker's own click ID, which is a random identifier tied to the click rather than to the device. No device advertising ID, no fingerprinting, no third-party cookies. The click ID lives in the app's manifest and local storage on the user's phone and in the tracker's data. Push subscriptions contain an endpoint URL and encryption keys for that one device, stored with the click. Set your data retention in line with your plan and your market's rules, and describe the tracking in your privacy policy as you would for any lander.

Bottom line

PWA tracking is lander tracking with three more beacons, all carrying the same click ID. Serve the app from your tracker so the ID is baked in, mark the install button so the engine can bind to it, test the full path on both platforms, and set a fallback URL for dormant installs. Then read the funnel per operating system over a week: install rate tells you about the page and traffic, launch rate and launches per install tell you whether the format is doing its job, and revenue per install tells you whether the extra step paid off. The complete PWA guide covers the rest of the funnel, and flows and traffic routing explains how the path that holds your PWA lander chooses the offer.