web2wave deferred deeplinks

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 SDKYes — MMP SDK in the appNo — built into web2wave SDK
How user_id arrivesInstall / deferred deeplink from MMPidentify() on first app open
SetupMMP dashboard + deeplink in project settingsInitialize web2wave SDK + call identify()
Best forTeams already using MMP for ads & attributionSimpler stacks, no MMP budget, web-to-app only
📘

These approaches are alternatives, not layers. Pick one attribution path for resolving user_id on 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

ScenarioRecommended approach
You use AppsFlyer, Adjust, Branch, etc.MMP deeplink — see integration guides above
You want web-to-app attribution without an MMPCall 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()):

HeaderExamplePurpose
platformiOS, AndroidDevice family
screen_size390x844Logical screen resolution
timezoneUTC+03:00Local timezone offset
os_versioniOS 18.0, Android 14OS version string
api-keyyour project keyProject 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:

  1. setAdaptyProfileID / setRevenuecatProfileID / setQonversionProfileID
  2. Wait 1–2 seconds, then restore purchases in the subscription SDK
  3. 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.IO or an ExecutorService.

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.

Related guides