One link, three outcomes: it opens your app at the right screen if the app is installed, sends a phone without it to the right store, and shows a web page on a laptop. That is a solved problem, it is free, and — despite what most of the pages ranking for this query imply — it needs no SDK. What it needs is two files on your domain and one app release.
Verified against Apple’s associated-domains documentation and Google’s Android App Links verification guide on 31 August 2026.
The whole mechanism, in four parts
Universal Links and App Links are an operating-system feature. The chain is short, and nothing in it is proprietary:
- 1. Two files on your domain. Apple fetches
/.well-known/apple-app-site-association; Google fetches/.well-known/assetlinks.json. Each one names your app. - 2. A claim inside the app. The Associated Domains entitlement on iOS, an
android:autoVerifyintent filter on Android. - 3. One release. The claim only exists in a shipped build. There is no way around this, for anyone — the same is true of every paid service in this category.
- 4. Your own routing. The OS hands your app the URL. What happens next is a few lines in your router, matching on the path.
Once that is done, a tap on your link never reaches any server: the phone recognises the address and opens your app directly. That is worth stating plainly, because it explains both why the feature is reliable and why the click numbers in any dashboard undercount.
iOS: the entitlement and the AASA file
Add the Associated Domains capability in Xcode, with one entry per domain in the form applinks:links.yourapp.com. Then serve a file named apple-app-site-association — no extension — from the .well-known directory of that domain. Apple is explicit that it must be served over https:// with a valid certificate and with no redirects.
www rule or a CDN page rule is the usual culprit.The file names your app as TEAMID.bundle.id and lists the paths it should handle. Scope those paths. If you also host a marketing page or your privacy policy on the same domain, a file claiming * tells iOS to open your app for those pages too.
Android: the intent filter and assetlinks.json
Add an intent filter to the activity that should receive the link, carrying android:autoVerify="true", the VIEW action, both the DEFAULT and BROWSABLE categories, and your https host. Then serve /.well-known/assetlinks.json over HTTPS, naming your package and its SHA-256 signing certificate fingerprints. Android verifies this at install time.
Then get the fingerprint right, because this is where most setups fail. The fingerprint has to match the certificate the installed APK is actually signed with. If your app uses Play App Signing — the default for new apps — Google re-signs your upload with a key you have never seen, so the fingerprint from your own keystore verifies nothing. Publish the one from Play Console → Test and release → App signing, and list your upload key as well so locally-installed debug builds keep working. The file accepts an array of fingerprints for exactly this reason.
You can check what Google itself sees with its Digital Asset Links checker, which reports whether your site grants your package permission to handle its links.
The one thing that genuinely does not work
“Tap a link for a product, don’t have the app, install it, and land on that product.” This is called deferred deep linking, and it is not a routing problem. When the user opens your freshly installed app from the home screen, it launches cold: no intent, no activity, no launch URL. The operating system preserved nothing across the install, so your route handler is fine — it simply never fires.
| Platform | Deferred deep linking | Why |
|---|---|---|
| Android | Works, exactly | Add ?referrer=… to the Play Store URL. Play carries it through the install and hands it to the app on first launch via the Install Referrer library (ReferrerDetails.installReferrer, available for 90 days). |
| iOS | Probabilistic at best | Apple provides no mechanism that carries a payload through an App Store install. SKAdNetwork postbacks go to ad networks, AdServices covers Apple Search Ads only, and the clipboard trick now shows the user a banner. |
What is left on iOS is matching a new install against a recent click by IP address, device model and time window. That breaks in cafés, offices and anywhere behind carrier NAT, breaks entirely under iCloud Private Relay, and is exactly the practice privacy regulators single out. Treat anyone claiming reliable iOS deferred deep linking with suspicion.
The workaround nobody advertises is free and completely reliable: after installing, tap the original link again. The Universal Link now fires and lands on the right screen. Plenty of well-known apps say precisely this on their post-install screen.
Why every deep-link dashboard undercounts
When the mechanism works, the OS opens your app without contacting a server — so that tap is invisible to us, to Branch, to AppsFlyer, and to you. Any number you see is the fallback traffic: visitors without the app, desktop browsers, and in-app webviews. That is a property of the platform, not a bug in a tool, and a dashboard that does not explain it is training you to read it wrongly.
When a link opens the browser: the checklist
- Wrong Android fingerprint. Upload key instead of the Play App Signing key. The single most common cause.
- A redirect on the file. Apple will not follow one; check with a tool that shows the status code, not a browser.
- A cached copy. Apple fetches the AASA through its CDN and caches it, so a corrected file is not instant. Purge
/.well-known/on your own CDN too. - The release hasn’t shipped. The entitlement exists only in a build users have installed.
- Paths not scoped, or scoped wrongly. The file has to claim the path your links actually use.
- An in-app browser. Instagram, Facebook and TikTok webviews routinely swallow Universal Links. A custom URI scheme still works inside them, which is why a fallback page that tries the scheme first is worth having.
Where a hosted option helps
Nothing above needs a vendor — but all of it needs a domain you control, serving two exact paths over HTTPS, and most indie developers have no server at all. That, rather than the mechanism, is the actual gap.
Edok Studio gives each app a domain (or connects yours), serves both association files from it, and lets you create and change links afterwards without touching the app again — with QR codes, click analytics, and a live check that fetches your files the way Apple and Google do and tells you which of the failure modes above you have hit. Android deferred deep linking is supported deterministically through the install referrer; we do not claim the iOS version, because it does not work.
Set up your app links
Design once with device frames and export every required App Store & Google Play size in one ZIP — watermark-free on the free plan.
Start free — no card