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
- User clicks a Rift link on mobile (via web SDK or landing page)
- iOS: the full link URL is copied to the clipboard (e.g.
https://go.yourcompany.com/summer-sale) - Android: the link ID is appended to the Play Store URL as
referrer=rift_link%3Dsummer-salein the install referrer - User installs the app and opens it
- App reads the clipboard (iOS) or install referrer (Android) to get the link URL/ID
- App extracts the link ID and calls
GET /r/{link_id}withAccept: application/jsonto get link data - App calls
POST /v1/attribution/reportto record the attribution - App routes user to the deep link destination
2
Using the native SDKs (recommended)
The iOS SDK and Android SDK provide parseClipboardLink() and parseReferrerLink() helpers that handle URL parsing for you. See those pages for full integration guides.
3
iOS — Manual integration
The landing page copies the full link URL to the clipboard. On first launch after install, read the clipboard, extract the link ID from the URL path, and resolve:
func checkDeferredDeepLink() async {
guard let clipboard = UIPasteboard.general.string,
let linkId = parseClipboardLink(text: clipboard) else { return }
UIPasteboard.general.string = "" // Clear after reading
// Fetch link data
let url = URL(string: "https://api.riftl.ink/r/\(linkId)")!
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Accept")
guard let (data, _) = try? await URLSession.shared.data(for: request),
let link = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
return
}
// Report attribution
let installId = UIDevice.current.identifierForVendor?.uuidString ?? UUID().uuidString
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "unknown"
let rift = RiftSdk(publishableKey: "pk_live_YOUR_KEY")
let _ = try? await rift.reportAttribution(
linkId: linkId,
installId: installId,
appVersion: appVersion
)
// Navigate to the deep link
if let deepLink = link["ios_deep_link"] as? String {
handleDeepLink(deepLink)
}
}Note: The
parseClipboardLink() function handles both the URL format (https://go.example.com/summer-sale) and the legacy rift:<link_id> format.4
Android — Manual integration
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) {
resolveAndAttribute(linkId)
}
}
client.endConnection()
}
override fun onInstallReferrerServiceDisconnected() {}
})
}
suspend fun resolveAndAttribute(linkId: String) {
// Fetch link data
val url = URL("https://api.riftl.ink/r/$linkId")
val conn = url.openConnection() as HttpURLConnection
conn.setRequestProperty("Accept", "application/json")
val link = JSONObject(conn.inputStream.bufferedReader().readText())
// Report attribution
val rift = RiftSdk(publishableKey = "pk_live_YOUR_KEY")
rift.reportAttribution(
linkId = linkId,
installId = getInstallId(),
appVersion = BuildConfig.VERSION_NAME
)
// Navigate to the deep link
link.optString("android_deep_link")?.let { handleDeepLink(it) }
}5
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",
"metadata": { "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
}
}