Validate your Universal Links and App Links setup.
Enter your domain. We fetch its iOS apple-app-site-association and Android assetlinks.json and flag what silently stops links opening your app.
The commands behind the validator. The Android one is the fastest way to settle whether a link problem is your association file or your app code.
# iOS: expect a single 200 and application/json
curl -sIL https://yourdomain.com/.well-known/apple-app-site-association \
| grep -iE 'HTTP/|content-type'
# Android: what has the device actually decided?
adb shell pm get-app-links your.package.name
# Android: force a re-check after fixing assetlinks.json
adb shell pm verify-app-links --re-verify your.package.name
If pm get-app-links reports verified, your assetlinks.json is fine and the bug is elsewhere in your routing. The full walkthrough is in the App Links vs Universal Links guide, and the troubleshooting docs cover the LinkTrail-specific cases.
Someone who taps your link without the app installs it and lands on your home screen, not the page they tapped. LinkTrail carries the link through the install, and serves both files for you with the right Content-Type and no redirects.
Create a free account Free for your first 5,000 users. No card, no sales call.iOS fetches /.well-known/apple-app-site-association and Android fetches /.well-known/assetlinks.json, both over HTTPS. Each host needs its own copy: to both platforms, www and your bare domain are two different domains.
Apple doesn't follow redirects when it fetches the AASA, and Android's verifier rejects them too. Not http to https, not bare domain to www, not a CDN's tidy-URL rule. The file has to answer with a single 200.
Both files must parse as JSON, and the AASA has no .json extension, so many servers guess the type wrong. A text/html response usually means your server sent a 404 or an app's fallback page instead of the file.
AASA appIDs are your Team ID and bundle ID, as TEAMID.bundle.id. assetlinks.json needs the SHA-256 fingerprint of every key that signs a build people install, including Google's Play App Signing key, which you never hold locally.
These files stop at the app store.
apple-app-site-association and assetlinks.json answer one question: may this domain open this app? They say nothing about which link was tapped, so someone who installs from your link lands on your home screen. LinkTrail remembers the click and hands the destination to the app on first launch. Try it on your own phone.
- 1Delete your app, then tap one of your own share or referral links
- 2Install it from the store and open it
- 3Home screen, not the thing you tapped? That's the gap these files can't close
Common questions.
How do I check if my Universal Links are set up correctly?
Fetch your apple-app-site-association from https://yourdomain.com/.well-known/apple-app-site-association and confirm three things: it returns a single 200 with no redirects, the Content-Type is application/json, and the appIDs are in prefix.bundle.id form. The validator above checks all three at once, along with the Android equivalent.
Does the validator test the link I paste?
No. It only uses the link's domain. It fetches that domain's apple-app-site-association and assetlinks.json and checks them; it doesn't open your link or follow where it leads, so it can't tell you how one particular link routes. If both files pass, links on that domain can open your app for people who already have it installed.
Why do my Universal Links open Safari instead of my app?
Almost always because the AASA never validated, and iOS reports no error when it doesn't. In order of likelihood: the file is served as text/plain or text/html rather than application/json, a redirect sits in front of it, the Associated Domains entitlement is missing from the build you installed, or the user previously tapped the breadcrumb back to Safari — iOS remembers that choice per domain.
Why does apple-app-site-association have to be application/json?
Apple's documentation specifies application/json, and that's what you should serve. In practice iOS parses the file whatever the header says, which is why plenty of sites serving it as application/octet-stream still have working Universal Links — the validator above flags that as a warning, not a failure. Fix it anyway for two reasons: only the documented contract is guaranteed to keep working across iOS releases, and a wrong Content-Type usually means the file is being served by accident rather than on purpose. The header that genuinely breaks things is text/html, which almost always means your server answered with a 404 or single-page-app fallback at a 200 status.
Why do my Android App Links open the browser?
Usually a signing fingerprint that isn't listed in assetlinks.json — most often Google's Play App Signing key, which you never see locally. Run adb shell pm get-app-links your.package.name on a device: if it doesn't say verified, the problem is your association file or Google's crawl of it, and no amount of app code will fix it.
How long does it take for changes to take effect?
Longer than you'd like, because there are two caches between your fix and a working link. iOS retrieves the AASA through an Apple-operated CDN, so a delete-and-reinstall is usually the fastest reliable check. On Android, Google re-crawls assetlinks.json on its own schedule and the device stamps its verdict at install — force a re-check with adb shell pm verify-app-links --re-verify.
Does this validator store my domain?
No. The check runs against the two publicly available association files on the domain you enter, and nothing is stored or required — no signup, no account, no email.
Do I still need these files if I use LinkTrail?
You need them, but you don't maintain them. LinkTrail generates and serves both files from your link domain with the correct Content-Type and no redirects, and regenerates them when you add a bundle ID or a signing fingerprint.
Stop hand‑maintaining these files.
LinkTrail serves both from your link domain and keeps them current as you add apps. Free for your first 5,000 users. No card, no sales call.