Skip to main content
Supported on: Android SDK 1.0.33+
The deep links module handles deferred deep links — routing users to the correct screen on first launch after installing from a link. This enables attribution tracking, referral programs, and contextual first-launch experiences. A deferred deep link works across the install boundary:
  1. User clicks a link on the web (e.g., https://yourapp.com/workout/123?ref=instagram)
  2. User is redirected to the Play Store and installs your app
  3. On first launch, the SDK resolves the original link and returns the destination
AppDNA.checkDeferredDeepLink { deepLink ->
    if (deepLink != null) {
        // deepLink.screen = "/workout/123"
        // deepLink.params = mapOf("ref" to "instagram")
        navigate(deepLink.screen, deepLink.params)
    }
}
checkDeferredDeepLink is a static method on AppDNA. It should be called once on first launch, typically after configure() completes. The SDK uses the Google Install Referrer API plus AppDNA’s visitor-context resolution. It returns null if no deferred link is found or if the app was not installed from a link.
checkDeferredDeepLink is a top-level method on AppDNA, not part of the deep links module:
AppDNA.checkDeferredDeepLink { deepLink ->
    if (deepLink != null) {
        navigate(deepLink.screen, deepLink.params)
    }
}

Module Access

val deepLinks = AppDNA.deepLinks

Module Methods

MethodSignatureDescription
setDelegatesetDelegate(delegate: AppDNADeepLinkDelegate?)Set a delegate for deep link callbacks
handleURLhandleURL(url: String)Pass an incoming deep link URL to the SDK for processing
PropertyTypeDescription
screenStringTarget screen path (e.g., "/workout/123")
paramsMap<String, String>Additional parameters (e.g., referrer, campaign)
visitorIdStringThe visitor identifier from the originating link

AppDNADeepLinkDelegate

Register a delegate for deep link events:
interface AppDNADeepLinkDelegate {
    fun onDeepLinkReceived(url: String, params: Map<String, String>)
}

Example Implementation

import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.AppDNADeepLinkDelegate
import android.net.Uri

class LinkHandler : AppDNADeepLinkDelegate {

    override fun onDeepLinkReceived(url: String, params: Map<String, String>) {
        // Route based on the incoming URL
        val path = Uri.parse(url).path ?: "/"
        route(path, params)
    }

    private fun route(screen: String, params: Map<String, String>) {
        when {
            screen.startsWith("/workout/") -> {
                val id = screen.removePrefix("/workout/")
                showWorkout(id)
            }
            screen == "/referral" -> showReferralWelcome(params["ref"])
            else -> showHome()
        }
    }

    private fun showWorkout(id: String) { /* ... */ }
    private fun showReferralWelcome(referrer: String?) { /* ... */ }
    private fun showHome() { /* ... */ }
}

AppDNA.deepLinks.setDelegate(LinkHandler())

Platform Setup

To support App Links on Android:
  1. Add intent filters to your AndroidManifest.xml:
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https" android:host="yourapp.com" />
</intent-filter>
  1. Host a Digital Asset Links file at https://yourapp.com/.well-known/assetlinks.json.

Handling in Activity

Pass the incoming intent’s data URL to the SDK:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    intent?.dataString?.let { AppDNA.deepLinks.handleURL(it) }
}

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    intent.dataString?.let { AppDNA.deepLinks.handleURL(it) }
}

Auto-Tracked Events

EventTrigger
deep_link_handledA deep link URL is processed
deferred_deep_link_resolvedA deferred deep link is resolved on first launch

Full Example

import ai.appdna.sdk.AppDNA
import ai.appdna.sdk.AppDNADeepLinkDelegate
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity(), AppDNADeepLinkDelegate {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        AppDNA.deepLinks.setDelegate(this)

        // Check for deferred deep link on first launch
        AppDNA.checkDeferredDeepLink { deepLink ->
            if (deepLink != null) {
                // User installed from a link — route to the target screen
                route(deepLink.screen, deepLink.params)

                // Track the visitor as a user trait
                AppDNA.identify(
                    userId = currentUserId,
                    traits = mapOf("visitor_id" to deepLink.visitorId),
                )
            } else {
                // Normal install — show default onboarding
                showOnboarding()
            }
        }

        intent?.dataString?.let { AppDNA.deepLinks.handleURL(it) }
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        intent.dataString?.let { AppDNA.deepLinks.handleURL(it) }
    }

    // AppDNADeepLinkDelegate

    override fun onDeepLinkReceived(url: String, params: Map<String, String>) {
        val path = Uri.parse(url).path ?: "/"
        route(path, params)
    }

    private val currentUserId: String get() = "user-123"
    private fun route(screen: String, params: Map<String, String>) { /* ... */ }
    private fun showOnboarding() { /* ... */ }
}
Deep link routes are configured in the Console under Engagement > Deep Links. The SDK resolves deferred links by checking the Google Install Referrer plus AppDNA’s stored visitor context on first launch.