Deep Linking
How deep linking works across iOS and Android, from Universal Links and App Links to routing users into the right screen in your app.
Deep links are URLs that take users directly to specific content inside a mobile app instead of a web page. WarpLink creates short links that resolve at the edge and route users to the right destination based on their platform. See Deep linking for the commercial overview of what this unlocks for your app.
How It Works
When a user taps a WarpLink URL (e.g., https://aplnk.to/abc123):
- Edge resolution: WarpLink resolves the link at the edge (sub-10ms redirects, how we measure this)
- User-Agent parsing: WarpLink parses the browser's User-Agent to detect the platform (iOS, Android, desktop)
- Bot detection: If the UA matches a known bot (social media crawlers, search engines), WarpLink returns an HTML page with OG/Twitter Card tags for rich previews
- Platform redirect: Real users get a 302 redirect to the appropriate destination:
- iOS with app installed: Universal Link opens the app directly
- Android with app installed: App Link opens the app directly
- iOS without app: Redirect to the App Store (or custom fallback URL)
- Android without app: Redirect to the Play Store (or custom fallback URL)
- Desktop: Redirect to the web destination URL
Universal Links (iOS)
Universal Links are Apple's mechanism for deep linking. When configured correctly, tapping a link opens your app without going through Safari.
Requirements:
- An Apple App Site Association (AASA) file hosted at
/.well-known/apple-app-site-associationon the link domain - The
Associated Domainsentitlement in your app (applinks:yourapp.aplnk.to) - The app must be installed on the device
WarpLink generates and hosts the AASA file automatically when you register your iOS app. It's regenerated whenever you update your app configuration. If a link still opens Safari, Apple App Site Association Not Working walks through the fault-isolation checks, from curl to swcutil.
App Links (Android)
App Links are Android's equivalent of Universal Links. They require a Digital Asset Links file for domain verification.
Requirements:
- An
assetlinks.jsonfile hosted at/.well-known/assetlinks.jsonon the link domain - An intent filter with
android:autoVerify="true"in your AndroidManifest.xml - The app must be installed and verified
WarpLink generates and hosts assetlinks.json automatically when you register your Android app with your package name and SHA256 signing key fingerprint. If verification fails, Android App Links autoVerify Failed lists the adb checks and the Play App Signing fingerprint trap.
Where the Link Configuration Comes From
Every deep link decision, the platform detected, the app installed state assumed, and the fallback chosen, reads from a link configuration that has to be available on every request, at edge latency, everywhere. Postgres is the source of truth: a link write always lands there first. From there it's pushed to a globally distributed key-value cache, and it's that cache the redirect path actually reads from on the hot path, since a database round trip on every tap would break sub-10ms redirects.
Every link is written to the database first and then to the edge cache. If a request misses the cache, the redirect path reads the link from the database.
Fallback URLs are part of that same cached configuration, not a separate lookup: the app's store URL is resolved and baked into the link's cached record at write time, so the redirect path never has to make an extra decision about which app a link belongs to while a real visitor is waiting on it.
Fallback Cascade (2 Tiers)
When a user doesn't have the app installed, WarpLink determines the fallback destination using a cascade:
| Priority | Source | Example |
|---|---|---|
| 1 | Link-level fallback URL | ios_fallback_url on the specific link |
| 2 | App-level store URL | App Store URL from app registration |
Fallback URLs are baked into the link configuration at write time, so redirects require no extra lookups.
Short Links
Every WarpLink URL uses a short slug format:
- App links:
https://yourapp.aplnk.to/{slug}(an app that existed before subdomains can also usehttps://aplnk.to/{slug}) - Existing links with no app:
https://aplnk.to/{slug} - Custom domains:
https://yourdomain.com/{slug}
Slugs are auto-generated (6-character alphanumeric via NanoID) or custom-chosen. Custom slugs must be 2-100 characters, lowercase alphanumeric with hyphens.
An app that existed before subdomains keeps aplnk.to for good. Links already on it stay there and keep opening your app, and aplnk.to stays one of the app's allowed domains. Each such app also has its own address to set up when it is ready. Existing apps keep using the domain of their most recent link by default (aplnk.to when that domain cannot serve new links), and any team member can change it per app in the app's Settings, at any time. Choosing a default never changes a link you already have. After a rename, the old subdomain keeps working. If we later move its links to the new one, each old URL redirects with a permanent 301. See Your app's own link address.
Every SDK recognizes aplnk.to out of the box. Declare your app's subdomain and any custom domain in the SDK so links on them resolve from the very first launch: see Use it in your app.
Click Analytics
Every tap that reaches a link is recorded, but only unique taps count toward your plan's monthly click allowance. A tap is unique the first time it arrives from a given visitor on that link within a rolling 24 hour window, so repeat taps from the same visitor in that window are recorded in your analytics but are not billed. The link's analytics page splits recorded taps under Where clicks came from:
- Browser redirects: the tap reached the link in a browser and WarpLink issued the 302
- In-app opens: a verified Universal Link or App Link opened your app directly and the SDK resolved the link, so the tap never touched a browser
In-app opens appear in analytics alongside browser redirects. The get_link_analytics MCP tool returns the same split under sources.
Nothing is recorded for a request WarpLink refuses, such as an expired link or a password-protected one, and nothing is recorded for a known bot. A social crawler fetching a preview never inflates a link's count.
Troubleshooting
The most common deep linking problem is a link that opens the browser instead of the app, even though the app is installed. This has three usual causes:
- Associated Domains or App ID not enabled. On iOS, the
Associated Domainscapability (applinks:yourapp.aplnk.to) must be added in Xcode and the same capability must be enabled on the app's App ID at developer.apple.com. On Android, the intent filter needsandroid:autoVerify="true". Missing either one means the platform never attempts verification, so it falls back to a browser. - AASA or assetlinks not verified. Even with the capability enabled, the platform still has to fetch and validate the association file (
apple-app-site-associationon iOS,assetlinks.jsonon Android) against the app's signing details. A stale device cache, a mismatched Team ID or SHA-256 fingerprint, or a file that fails validation all produce the same silent fallback to the browser. - Testing on a simulator. On the iOS Simulator,
xcrun simctl openurl bootedopens a Universal Link only when the app's Associated Domains entitlement lists the host and the domain serves a valid apple-app-site-association file that matches the path, and because tapping a link inside the Simulator is unreliable, confirm on a physical device. Android emulators can verify App Links, but results are less reliable than a physical device, so confirm a failure on a real device before troubleshooting further.
For a full diagnostic walkthrough, see Universal Links Not Opening: Every Cause and How to Fix Each One and Apple App Site Association Not Working: The iOS Universal Links Debug Checklist for iOS, and Android App Links autoVerify Failed for Android. To check both association files for a domain in one step, use our deep link checker.
Related
- Deferred deep links: route users to the right screen even when the app is installed after the tap.
- Install attribution: match every install back to the link that drove it.
- Quickstart: add WarpLink to iOS, Android, React Native, or Flutter.
- The complete guide to deep linking: a longer conceptual walkthrough for mobile developers, including Universal Links, App Links, and deferred deep links.
Concepts
The core concepts behind WarpLink: deep linking, deferred deep links, install attribution, analytics, social previews, password protection, and custom domains.
Deferred Deep Links
How deferred deep links preserve their destination and context through an app install, routing new users to the right place after first launch.