Develop
Develop
Select your platform

App Deep Linking

Updated: Mar 19, 2026
This is a Platform SDK feature requiring Data Use Checkup
To use this or any other Platform SDK feature, you must complete a Data Use Checkup (DUC). The DUC ensures that you comply with Developer Policies. It requires an administrator from your team to certify that your use of user data aligns with platform guidelines. Until the app review team reviews and approves your DUC, platform features are only available for test users.
App deep linking allows you to launch users directly into another app and can be configured to launch directly into that app’s special event or gameplay mode.
For example, you may have two separate applications, one single player and one multiplayer. If you implement App Deep linking in both apps, a user can join a multiplayer session from the single player app.
Deep linking requires an integration in both the app the request originates from, and the target app. The next sections describes the implementation required for both apps.
Monetizing the use of deep links between apps is not permitted. See Cross-app linking in our app policy topic for more details.
You should obtain informed user consent for accessing links. For cross-app linking, you must provide meaningful information about the destination, including the content rating of the destination app, whether it is a free or paid experience, if the destination app includes multiplayer or voice communications, what user information will be shared with the destination app, and if parental approval will be needed for users under 13.
Additionally, you must comply with our Developer Data Use policy which limits data sharing with third parties. For example, if you share a user ID with the destination app, that app will then become subject to Data Use Check-up for receiving that information. We recommend that you only share a session ID to avoid this if the destination app is not already subject to Data Use Check-up.

Originating app implementation

The originating app will call the LaunchOtherApp method to launch the other application.
Application().launchOtherApp(appId, deeplinkOptions)
This method launches a different application in the user’s library. If the user does not have that application installed, they will be taken to that app’s page in the Meta Horizon Store.
Parameters:
ParameterDescription
appID
The ID of the app to launch
deeplink_options
Additional configuration for this requests. Optional.
For example, a request from a Kotlin application may resemble:
import horizon.platform.application.Application
import horizon.platform.application.options.ApplicationOptions

val app = Application()
val options = ApplicationOptions.builder().withDeeplinkMessage("abc").build()
app.launchOtherApp(appId = targetAppId, deeplinkOptions = options)
launchOtherApp() is a suspend function. Call it from a coroutine scope such as lifecycleScope or viewModelScope.
Once the request has been made, you should check to see if the target application launched successfully. The request will only succeed if the user is both entitled to (owns) and has installed the target app. If the user does not own the app, or has not downloaded the app, they will be directed to the product information page in the 2D Store where they can purchase and download the app.

Receiving app implementation

Apps launched by
Application().launchOtherApp(appId, deeplinkOptions) will launch as normal.
On a Kotlin app, at startup, call ApplicationLifecycle().getLaunchDetails() to retrieve information about how the app was launched, and observe ApplicationLifecycle().launchIntentChanged() for runtime deep link changes.
import horizon.platform.applicationlifecycle.ApplicationLifecycle
import horizon.platform.applicationlifecycle.enums.LaunchType
import horizon.platform.applicationlifecycle.enums.LaunchResult

val lifecycle = ApplicationLifecycle()
val launchDetails = lifecycle.getLaunchDetails()

when (launchDetails.launchType) {
    LaunchType.Deeplink -> {
        val message = launchDetails.deeplinkMessage
        val trackingId = launchDetails.trackingId
        // Navigate to the deep linked content
        lifecycle.logDeeplinkResult(trackingId ?: "", LaunchResult.Success)
    }
    else -> {
        // Normal launch
    }
}
getLaunchDetails() and logDeeplinkResult() are suspend functions.
To observe runtime deep link changes while the app is running, collect the launchIntentChanged() Flow:
lifecycle.launchIntentChanged().collect { deeplinkMessage ->
    Log.i(TAG, "New deep link received: $deeplinkMessage")
}
If the user is on a Meta Quest device, and the user does not own the app, or has not downloaded the app, they will be directed to the product information page in the Store where they can purchase and download the app.