Fire the call inside your deep-link handler — SceneDelegate.scene(_:continue:) on iOS, Intent filter receiver on Android, the equivalent React Native Linking handler, Flutter's uni_links callback. Don't pass the URL or its query parameters.
▸Install the Kotlin (Android) SDK
// build.gradle.kts (app module)
dependencies {
implementation("com.respectlytics:respectlytics-kotlin:3.0.0")
}
Pure Kotlin coroutines implementation. No Java dependencies, no Google Play Services dependencies. ~300KB DEX overhead — compare to roughly 3.8MB for Firebase Analytics (a measurable cold-start improvement on lower-end devices).
▸Initialize Respectlytics in Kotlin (Android)
import com.respectlytics.android.Respectlytics
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Respectlytics.configure(this, appKey = "<YOUR_APP_KEY>")
}
}
Initialize once in Application.onCreate. No additional permissions in the manifest — INTERNET is sufficient. The SDK does not request AD_ID, does not query AdvertisingIdClient, and does not declare ACCESS_NETWORK_STATE.
▸Track the event in Kotlin (Android)
import android.content.Intent
import com.respectlytics.android.Respectlytics
class MainActivity : ComponentActivity() {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (intent.action == Intent.ACTION_VIEW && intent.data != null) {
Respectlytics.track("deeplink_open")
router.handle(intent.data!!) // URL stays in router, not analytics.
}
}
}
Same pattern works for App Links (auto-verified https:// URLs) and custom schemes — both deliver via ACTION_VIEW.
✦Privacy & implementation notes
A deep-link URL often contains the user's tracking ID, the campaign source, the referrer, and sometimes a session token — concatenated into a single free-form string. Respectlytics's API rejects free-form strings as event metadata. Your routing code keeps the URL; analytics gets the event name.
Install attribution and deep-link open are different signals. Install attribution requires server-side callbacks from the App Store / Play Store. Deep-link open is the in-app signal that the user navigated via a link. Don't use the open event as a proxy for install — they fire at different times for different populations.
Many teams discover the com.google.android.gms.permission.AD_ID permission in their merged manifest only after Google Play flags them — usually because a transitive dependency dragged it in. Respectlytics's Kotlin SDK has no Google Play Services dependency at all, so it cannot contribute to that merge.
The SDK is implemented as pure Kotlin coroutines with no Java sources, no RxJava, and no platform channels. Events are queued in a Channel<Event> buffered to a small ring (RAM-only), drained by a coroutine that flushes every 30 seconds or on backgrounding. There is no SharedPreferences usage.
⇋How this compares to other analytics SDKs
| Deep-link open event | Firebase Analytics | Mixpanel | Respectlytics |
|---|---|---|---|
| Full URL stored | Often (via Dynamic Links) | Often | Rejected by API |
| UTM parameters as event properties | Yes (default for web tracking) | Yes | Rejected by API |
| Referral code as parameter | Recommended | Recommended | Use distinct event_name (top-N) or skip |
| Per-campaign attribution | Per-user | Per-user | Session-scoped, top-N campaigns only |
| Click-through rate (link → app open) | With Dynamic Links | With server-side join | Out of scope (use server-side analytics) |
❓Frequently asked questions
How do we know which campaign drove an install?
Server-side, not in product analytics. App Store Connect (Apple Search Ads) and Play Console (Play Store referrer API) deliver install attribution to your backend via server-to-server callbacks. Respectlytics is for in-app product engagement — different question, different system of record.
What about top-N campaign tracking via event names?
If you have a small set of high-volume campaigns (under 10), distinct event names work: deeplink_open_summer_sale, deeplink_open_press_pickup. The long tail bucketed as deeplink_open_other. For high-cardinality campaign ID tracking, use server-side attribution instead.
Should we distinguish Universal Links / App Links from custom schemes?
If your app supports both (which is common during a migration), use distinct event names: deeplink_open_universal, deeplink_open_custom_scheme. The rate of each tells you how successfully you've migrated traffic to the modern API.
What if the deep link triggers in-app navigation but no other events?
Common with deep links to settings or specific content. Fire deeplink_open anyway — the open itself is the signal. If the user goes on to convert in the same session, the funnel groups them together via session_id.