Connect a web funnel visitor to their native app install without AppsFlyer, Adjust, Branch, or other MMP — using the identify() method and device matching headers built into every web2wave SDK.
After a user completes a web2wave quiz or paywall in the browser and installs your app, you need their web2wave user_id inside the native app to unlock the subscription.
Most teams get that user_id through a mobile measurement partner (MMP) — AppsFlyer, Adjust, Branch, and similar tools pass it via an install deeplink. That works well if you already run an MMP stack.
If you do not use an MMP, web2wave provides deferred deeplinks as a built-in alternative. Every Mobile SDK sends device-matching headers on API requests and exposes an identify() method (GET /api/user/identify) that matches the installed device against recent web sessions on your project and returns the user_id.
No third-party attribution SDK required.
MMP vs web2wave deferred deeplinks
| MMP (AppsFlyer, Adjust, Branch, …) | web2wave deferred deeplinks | |
|---|---|---|
| Extra SDK | Yes — MMP SDK in the app | No — built into web2wave SDK |
How user_id arrives | Install / deferred deeplink from MMP | identify() on first app open |
| Setup | MMP dashboard + deeplink in project settings | Initialize web2wave SDK + call identify() |
| Best for | Teams already using MMP for ads & attribution | Simpler stacks, no MMP budget, web-to-app only |
These approaches are alternatives, not layers. Pick one attribution path for resolving
user_idon install. If you already use AppsFlyer or Adjust, follow the RevenueCat, Adapty, or direct API guides with your MMP deeplink handler.
You can also use web2wave's custom deeplink page without an MMP — but that still requires the user to open the install link again after downloading the app. Deferred deeplinks remove that extra step.
When to use deferred deeplinks
| Scenario | Recommended approach |
|---|---|
| You use AppsFlyer, Adjust, Branch, etc. | MMP deeplink — see integration guides above |
| You want web-to-app attribution without an MMP | Call identify() on first app launch |
User already known in app (stored user_id) | Skip attribution; use stored value |
Call identify() once per fresh install, typically on first app open and before linking Adapty / RevenueCat / Qonversion profiles.
How deferred deeplinks work
The SDK automatically attaches these HTTP headers to every API call (including identify()):
| Header | Example | Purpose |
|---|---|---|
platform | iOS, Android | Device family |
screen_size | 390x844 | Logical screen resolution |
timezone | UTC+03:00 | Local timezone offset |
os_version | iOS 18.0, Android 14 | OS version string |
api-key | your project key | Project authentication |
The identify() endpoint compares this device context against web sessions collected during quiz/paywall visits on the same project.
Response format
A successful match returns:
{
"success": 1,
"user_id": "identified_user_guid",
"match_method": "match_method_used",
"platform": "iOS"
}If no match is found, success is not 1 or the call returns null / invokes the error callback depending on the SDK.
Integration flow
After you have a user_id, link your paywall SDK and verify entitlement:
setAdaptyProfileID/setRevenuecatProfileID/setQonversionProfileID- Wait 1–2 seconds, then restore purchases in the subscription SDK
hasActiveSubscription(user_id)to unlock content
Code examples
Web2Wave.shared.initialize(apiKey: 'your-api-key');
// No MMP — resolve user_id via deferred deeplink
final identificationData = await Web2Wave.shared.identify();
if (identificationData != null && identificationData['success'] == 1) {
final userId = identificationData['user_id'] as String?;
if (userId != null) {
await Web2Wave.shared.setAdaptyProfileID(
web2waveUserId: userId,
adaptyProfileId: adaptyProfile.profileId!,
);
await Future.delayed(const Duration(seconds: 2));
await Adapty().restorePurchases();
}
}Run network calls off the main thread on Android (Java/Kotlin). Use a background coroutine with
Dispatchers.IOor anExecutorService.
Direct API usage
If you are not using an SDK, send the same headers manually:
curl -X GET "https://api.web2wave.com/api/user/identify" \
-H "api-key: YOUR_API_KEY" \
-H "platform: iOS" \
-H "screen_size: 390x844" \
-H "timezone: UTC+03:00" \
-H "os_version: iOS 18.0"See also: Direct web2wave API integration and GET /user/identify.