PWA Funnel: From Click to Deposit
What is PWA and how does it work
PWA (Progressive Web App) — a web application that is installed on the home screen of a phone and works like a native app: icon, fullscreen mode, push notifications.
Why arbitrageurs use PWA instead of native apps:
Bypassing moderation: advertising networks (FB, TikTok) check content by URL. PWA is installed from a neutral domain, and the money offer opens already in the installed app
Quick launch: no need for Google Play / App Store, no developer signature required. The PWA builder in Adset.Pro — created in minutes
Push notifications: after installation, permission for push notifications is requested — a free base for retargeting
No APK download required: installation through the browser (Add to Home Screen) — faster and safer from the user's perspective
Types of PWA in Adset.Pro:
Type | Description |
|---|---|
| PWA created in the Adset.Pro builder (Step-by-Step builder) |
| PWA on an external service (connected via URL) |
| iOS App — a separate funnel for iOS devices |
Complete PWA Funnel
Each step of the funnel is recorded as a separate event in the tracker:
[FB/TikTok/Push Ad]
↓
SOURCE_CLICK ← the tracker generates event_click_id (UUID), determines GEO/device/IP
↓
SOURCE_FILTER ← [if filters are not passed] click is blocked → White Page
↓
[In-App WebView?] ← FB/Instagram/TikTok/Telegram?
↓ YES ↓ NO
Bridge Page Landing / PWA
(kick in Chrome/Safari)
↓
LAND_VIEW ← user opened the pre-landing
↓
LAND_CLICK ← clicked the "Install" / "Next" button
↓
PWA_VIEW ← opened the PWA page (sees install prompt)
↓
PWA_INSTALL ← accepted the install prompt, PWA installed on the home screen
↓
[Subscription Page] ← request for push notifications
↓
NOTIFICATION_REQUEST ← native push request shown
NOTIFICATION_SUBSCRIBE ← user agreed (or DECLINE — refused)
↓
[Redirect to offer] ← click_id is passed to the partner through paramTemplate
↓
CPA_HOLD ← registration on the partner's site (postback)
↓
CPA_ACCEPT ← first deposit / FTD (postback)
↓
CPA_REDEP ← repeat deposit (postback)
Additional events:
PWA_OPEN— re-opening an already installed PWA (after days/weeks)IOS_INSTALL— installation on iOS (Redis deduplication, once per clickId)POSTLANDING_VIEW/POSTLANDING_CLICK— page between PWA subscription and redirect to offer
Key Metrics of the Funnel
All metrics are available in Adset.Pro statistics:
Basic Metrics
Metric | Formula | Group | What it shows |
|---|---|---|---|
| Unique | Traffic | Reach: how many people clicked |
|
| PWA | How many reached the installation page |
|
| PWA | How many installed PWA |
|
| PWA | Repeated openings of the installed PWA |
|
| PWA | Installations on iOS |
Conversion Metrics
Metric | Formula | What it shows |
|---|---|---|
|
| Main funnel performance metric |
|
| Conversion of the PWA page to installation |
|
| Registrations through PWA |
|
| FTD (first deposits) |
|
| Install → Registration |
|
| Install → FTD |
|
| Click → Registration |
|
| Click → FTD |
Postlanding Metrics
Metric | Formula | What it shows |
|---|---|---|
|
| Views of the postlanding page |
|
| Clicks on postlanding |
|
| CTR postlanding |
Where Users Drop Off: Funnel Analysis
Each step of the funnel is a potential point of loss. Let's analyze in order:
Click → PWA_VIEW (loss on pre-landing/transition)
Typical reasons for losses:
Slow loading — mobile traffic, poor internet in Tier-3 GEO. The PWA template is heavy (JS, images)
In-App WebView — FB/Instagram/TikTok open the link in an embedded WebView. Adset.Pro provides a Bridge Page for kicking into an external browser, but some users are lost
Cloak filters — if bot filtering or Stream Set filters triggered, the user goes to a White Page instead of PWA
How to diagnose:
Compare
LAND_VIEW / clicksratioCheck
SOURCE_FILTER— how many clicks were blockedGroup by
user_device/user_browser— where losses are greater
PWA_VIEW → PWA_INSTALL (conversion of the PWA page)
Factors affecting install_rate:
PWA Design: icon (does it look like a real app?), name, color scheme
Install prompt: On Android (Chrome) — native banner "Add to Home Screen". On iOS (Safari) — no native prompt, instructions needed through UI
Browser: Chrome > Samsung Browser > Safari (by install_rate)
iOS specifics:
No
beforeinstallpromptevent — PWA usesPwaManagerwith fallback instructionsInstallation is recorded through
IOS_INSTALLwith Redis deduplication (once per clickId)Install rate on iOS significantly lower — usually 3-5 times lower than Android
How to diagnose:
pwa_view_to_instal_ratewith group byuser_device/user_os/user_browserCompare Android vs iOS — the difference should be expected (if not — there is a problem in the iOS funnel)
PWA_INSTALL → CPA_HOLD (install → registration)
Typical reasons for losses:
Offer quality: the partner's landing does not motivate registration
Bonus offer: irrelevant currency for GEO, outdated bonus
Redirect speed: after installing PWA → redirect to offer. If slow — the user leaves
Subscription page: after PWA_INSTALL, a page requesting push notifications (
subscribe-template) is shown. If the user closes at this stage — they do not reach the offer
How to diagnose:
pwa_install_to_hold_rate— typical value 20-50% for gamblingGroup by
cmp_offer/cmp_cpa— which offer converts better
CPA_HOLD → CPA_ACCEPT (registration → deposit)
Typical % for gambling/betting:
Tier-1 GEO (DE, UK, CA): 30-50% registrations → deposit
Tier-2 GEO (UA, KZ, PL): 20-40%
Tier-3 GEO (NG, IN, BD): 10-25%
What influences:
Status mapping: if
holdis not set up in the CPA network — conversion "disappears"Payment methods: availability of local payment methods for the user
Partner onboarding: verification, KYC, minimum deposit
Metric: cpa_accept / cpa_hold or click_to_dep / click_to_reg
Analysis by Groupings
The funnel can be broken down by any slice:
Group Key | What you analyze |
|---|---|
| Which GEO converts better |
| Android vs Desktop vs iOS |
| Android vs iOS (principally different install_rate) |
| Chrome vs Samsung Browser vs Safari |
| Compare two PWA designs |
| Compare two campaigns |
| Compare two offers |
| Compare flows within a campaign |
Case: A/B test of two PWAs
Task: One campaign launched with two PWAs through Flow 50/50.
How to view:
Statistics → period last 7 days
Metric:
pwa_view_to_instal_rateGroup by:
cmp_pwaAdditionally:
click_to_instal_rate,pwa_install_to_accept_rate
Interpretation: If PWA-1 shows an install_rate of 35%, and PWA-2 — 25%, with comparable CPA → scale PWA-1.
iOS vs Android: Important Differences
Parameter | Android + Chrome | Android + Samsung | iOS + Safari |
|---|---|---|---|
Install Prompt | Native | Similar native prompt | No native — instructions through UI |
PWA Install | Best conversion | Works well on Galaxy | Significantly lower install_rate |
Standalone Mode | Works | Works |
|
Push | FCM | FCM | FCM (with limitations) |
Event |
|
|
|
WebView kick |
|
|
|
iOS App in Adset.Pro:
Separate type of PWA (
ios-app) — special handling for iOSUses
IOS_INSTALLinstead ofPWA_INSTALLfor accounting installationsRedis deduplication through
acquireInstallGate(clickId)— guarantees one install event per clickIdSupport for
ios26query parameter for iOS 26 specifics
Practical advice: Separate iOS and Android traffic into different campaigns or different Stream Sets. Reasons:
Different install_rate (Android 30-40%, iOS 5-15%)
Different funnel (native prompt vs instructions)
Different PWA designs are optimal for each platform
Push Subscription in the PWA Funnel
After installing PWA, the user lands on the subscription page (subscribe-template), where a request for push notifications is shown:
Event | What happens |
|---|---|
| The browser showed a native push request |
| User agreed → FCM token is saved in Subscription |
| User declined |
| Unsubscribed later (through browser settings) |
Behavior after subscription:
If
SUBSCRIBE→ redirect to offer + record in Subscription (clickId, country, campaign, pwa, fcmToken)If
DECLINE→ still redirect to offer (but without push subscription)If PWA is already in standalone mode + already subscribed → immediately opens the offer through Chrome Custom Tab
Business value of the push base:
Usually, 40-70% of those who installed PWA subscribe to push notifications
Subscribers are a retargeting audience: free repeated touches through push campaigns
Connection with LTV: users who receive push notifications make more redeposits (trigger push notifications after REGISTRATION and DEPOSIT)
The push base "ages" (~10-20% FAIL per month) — it is necessary to constantly replenish with new subscribers
Standalone mode (installed PWA):
If the user opened PWA from the home screen (standalone) and is already subscribed to push notifications — the subscription page is skipped
Transition to the offer through Chrome Custom Tab (CCT) — the URL opens in Chrome over PWA, context is not lost
Cookie
push_statusis used to determine the subscription status during repeat visits
Funnel Configuration in the Campaign
At the Flow level in the Stream Set, the following is configured:
Parameter | Description |
|---|---|
| Which PWA to use (internal / external / ios-app) |
| Pre-landing before PWA (optional) |
| Use landing as PWA (without a separate PWA page) |
| Page between push subscription and redirect to offer |
Funnel options:
Full: Landing → PWA → Subscribe → Postlanding → Offer
Without pre-landing: PWA → Subscribe → Offer (short funnel)
Landing as PWA: Landing (in PWA mode) → Subscribe → Offer
Without PWA: Landing → Offer (if
pwa = null)
Frequently Asked Questions
Q: Why are pwa_installs in Adset.Pro statistics higher than FTD in the partner's cabinet?
This is normal. PWA installation ≠ deposit. There are still several steps in between:
PWA installed → need to go to the offer
Offer opened → need to register
Registered → need to deposit
Typical conversion install → FTD: 10-30% (depends on GEO, offer, quality of PWA).
Q: The user installed PWA, but the deposit was not attributed to our click — why?
Possible reasons:
click_id was not passed — paramTemplate is set up incorrectly, or the user went to the offer through another link
Sticky Flow is off — when re-entering through PWA_OPEN, a new click_id is generated if
stickyFlowKeepClickId = falseAttribution window expired — the user deposited a week later, and the cookie with click_id was cleared
User opened the offer directly — accessed the partner's site through the browser, bypassing PWA
Q: How to check that paramTemplate correctly passes click_id?
Create a test click on the tracking link
Check the URL you are redirected to (offer URL)
Ensure that the parameter with click_id is present and contains UUID
Example: if paramTemplate =
?sub1={event.event_click_id}, then the offer URL should behttps://partner.com/offer?sub1=35d542f6-56ec-...If click_id is missing — check that the CPA template and paramTemplate are set up correctly
Q: What is the difference between PWA_INSTALL and IOS_INSTALL?
PWA_INSTALL— standard installation event throughbeforeinstallprompt(Android: Chrome, Samsung Browser)IOS_INSTALL— special event for iOS, where there is no native install prompt. Recorded through Redis deduplication (guarantees one event per clickId). Used whenuser_os = iOSor?ios=1is passed
Q: What is landingAsPwa and when to use it?
If landingAsPwa = true, the landing works in PWA mode — the user sees the landing, is offered to install on the Home Screen, and after installation, is redirected to the offer. This is a simplified funnel without creating a separate PWA in the builder. Suitable for quick testing.
