Free tool

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.

https://

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.name

If 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.

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 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.