Universal Links & App Links validator
Paste a domain. We'll fetch its iOS apple-app-site-association and Android assetlinks.json and flag the things that silently stop deep links from opening the app.
We fetch /.well-known/apple-app-site-association and /.well-known/assetlinks.json over HTTPS. Nothing is stored.
What this checks
- Wrong Content-Type on the extension-less AASA file
- A 301/302 redirect in front of the file (Apple won't follow it)
- Malformed JSON or a missing applinks.details block
- appIDs that aren't TEAMID.bundle.id, or missing SHA-256 fingerprints
Why deep links fail silently
Universal Links and App Links have one design flaw in common: when verification fails, nothing tells you. There is no error, no warning, and no log line. The link simply opens the browser, which looks like a product decision rather than a bug — which is why broken association files survive to production so often. These are the five causes worth checking first.
- The file is served as the wrong type
- apple-app-site-association has no file extension, so a lot of servers guess text/html or text/plain. Apple requires application/json. This is the single most common cause, and it's invisible in a browser — the file looks perfect when you open it.
- Something redirects before the file is reached
- Apple follows no redirects when fetching the AASA. Not http to https, not apex to www, not a trailing-slash normalisation, not a CDN's tidy-URL rule. Any hop at all and verification fails silently.
- A signing fingerprint is missing on Android
- You ship under more keys than you'd expect: Play App Signing re-signs your upload with Google's key, sideloaded builds carry your upload key, and each developer machine has its own debug key. If the fingerprint on the device isn't in assetlinks.json, App Links open the browser.
- The appID prefix isn't the Team ID
- appIDs must be prefix.bundle.id. For most apps the prefix is the Team ID, but they differ for apps migrated between teams — and the mismatch produces no error anywhere, just links that don't open.
- You're testing on a device that already decided
- Both platforms cache their verdict. iOS fetches the AASA through Apple's CDN, so Apple's cached copy is what devices see, and Android stamps a per-device result at install time. A device that has already seen your domain tells you what it cached, not what your file says.
Checking it yourself
The validator above does this for you, but these are the commands behind it — worth knowing, because 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.nameIf pm get-app-links reports verified, your assetlinks.json is fine and the bug is elsewhere in your routing. The full walkthrough for both platforms is in the App Links vs Universal Links guide, and the troubleshooting docs cover the LinkTrail-specific cases.
What this tool can't fix
Everything above is configuration. Fix those files and your links work — for people who already have your app installed.
There's a second case, and no configuration file addresses it.
Someone taps your referral link. They don't have your app. The OS can't open an app that isn't there, so they land on your website or the store. They install. They open it.
And they're on your generic home screen. Not the shared product. Not the group they were invited to. Not the referral credit.
Why the files don't help
apple-app-site-association and assetlinks.json answer one question: should this domain be allowed to open in this app? They carry no information about which link was tapped — and in this case the tap happened before your app existed on that device. There is nothing for the OS to pass along.
Making that work is called deferred deep linking. The destination has to survive the install and be handed to the app on first launch, which needs something in the middle that remembers the click and matches it to the install.
Who this hits hardest
- Referral programmes — the new user installs, the referrer never gets credited, and the loop quietly stops working
- Invite flows — invited to a group or a shared list, lands on the home screen instead
- Promo and voucher codes — the code doesn't carry through, so the discount doesn't apply
- Paid campaigns — no attribution on install, so you can't tell which ad actually worked
The 60-second test
Don't take our word for it. On your own phone:
- 1Delete your app
- 2Tap one of your own share or referral links
- 3Install from the store
- 4Open it
If you land on the home screen instead of the thing you tapped, that's the gap. Every install from every share link is doing this right now.
Tired of hand-maintaining these files?
LinkTrail serves verified AASA and assetlinks.json from your own link domain with the correct Content-Type and no redirects, and regenerates them when you add a bundle ID. Set the domain and bundle IDs once.
Universal Links and App Links — 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.
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.
Questions about your setup?
Email support@linktrail.io or see the plans, starting with a free tier.