RiftRift

Deep Linking

Deferred Deep Linking

Route users to specific content even if they didn't have the app installed when they clicked. Rift passes the link URL through the install flow and delivers it to the app after install.

1

How it works

  1. User clicks a Rift link on mobile (via web SDK or landing page)
  2. iOS: the full link URL is copied to the clipboard (e.g. https://go.yourcompany.com/summer-sale)
  3. Android: the link ID is appended to the Play Store URL as referrer=rift_link%3Dsummer-sale in the install referrer
  4. User installs the app and opens it
  5. App reads the clipboard (iOS) or install referrer (Android) to get the link URL/ID
  6. App extracts the link ID and calls GET /r/{link_id} with Accept: application/json to get link data
  7. App calls POST /v1/lifecycle/attribute to record the attribution
  8. App routes user to the deep link destination
2

iOS — SDK (recommended)

The SDK does everything in one call: it checks the pasteboard for a URL, reports attribution, and returns the link data for navigation.

// On first launch
if let result = try await rift.checkDeferredDeepLinkFromPasteboard() {
    if let deepLink = result.iosDeepLink {
        handleDeepLink(deepLink)
    }
}
Note: checkDeferredDeepLinkFromPasteboard() uses UIPasteboard.detectPatterns(for: [.probableWebURL]) to check for a URL without reading the contents — so it only reads the pasteboard (and only triggers the iOS 16+ paste banner) when a URL is actually present. On launches with nothing to defer, it's a silent no-op.

If you need to supply the clipboard text yourself (custom gating, testing), the lower-level call is still available:

if let result = try await rift.checkDeferredDeepLink(
    clipboardText: UIPasteboard.general.string
) {
    if let deepLink = result.iosDeepLink {
        handleDeepLink(deepLink)
    }
}
3

Android — SDK (recommended)

On Android, use the install referrer to get the link ID, then resolve and attribute:

import com.android.installreferrer.api.*

fun checkDeferredDeepLink() {
    val client = InstallReferrerClient.newBuilder(this).build()
    client.startConnection(object : InstallReferrerStateListener {
        override fun onInstallReferrerSetupFinished(code: Int) {
            if (code == InstallReferrerResponse.OK) {
                val referrer = client.installReferrer.installReferrer
                val linkId = parseReferrerLink(referrer)
                if (linkId != null) {
                    lifecycleScope.launch {
                        rift.attributeLink(linkId = linkId)
                        val link = rift.getLink(linkId = linkId)
                        link.androidDeepLink?.let { handleDeepLink(it) }
                    }
                }
            }
            client.endConnection()
        }
        override fun onInstallReferrerServiceDisconnected() {}
    })
}
4

Resolve a link (API)

To get the link data for routing, send a JSON request to the public resolve endpoint:

curl https://api.riftl.ink/r/summer-sale \
  -H "Accept: application/json"

Response:

{
  "link_id": "summer-sale",
  "ios_deep_link": "myapp://promo/summer-sale",
  "android_deep_link": "myapp://promo/summer-sale",
  "web_url": "https://example.com/promo/summer-sale",
  "social_preview": { "title": "Summer Sale — 50% Off" },
  "agent_context": {
    "action": "purchase",
    "cta": "Get 50% Off"
  },
  "_rift_meta": {
    "status": "active",
    "tenant_domain": "go.yourcompany.com",
    "tenant_verified": true
  }
}