What is the difference between Universal Links and Android App Links?

Universal Links are Apple’s verified HTTPS links for iOS. Android App Links are Google’s verified HTTPS links for Android. Each platform checks a file on your domain before it will open the app instead of the browser. Deeplink (deeplink.in) serves those files for the link domain and stores the app ids the files must contain.

Same idea, different files

Both systems start from an HTTPS URL. The phone will not open an app for that URL until it has fetched a signed statement that the app owner controls the domain. On iOS the statement is the apple-app-site-association file, often called the AASA file. On Android it is assetlinks.json, the Digital Asset Links statement. Custom URL schemes skip this check, which is why they are easier to spoof and harder to use from the web.

iOS looks up the AASA file for the domain, typically at /.well-known/apple-app-site-association, and compares it with the Associated Domains entitlement in the app. The file lists the team id and the bundle id. If they match, a tap on that domain can open the app. The file is JSON and must be served without a redirect that breaks Apple’s fetch.

Android looks up /.well-known/assetlinks.json. The statement includes the package name and the SHA-256 certificate fingerprints of the signing key. The app’s intent filters declare the hosts and paths it handles, and android:autoVerify tells the system to check the statement. When verification succeeds, the link opens the app without a disambiguation dialog.

What Deeplink configures

The API process serves both files. Requests to /.well-known/assetlinks.json and /.well-known/apple-app-site-association are handled by the backend so each link domain can publish the apps configured for it. In the dashboard, an Android app is stored with a package name and SHA-256 fingerprints. An iOS app is stored with a bundle id and an Apple team id. Those are the values the association files have to agree with.

The link itself still has a path and a fallback URL. Verification only answers “may this app open this domain?” The path answers “which screen?” The fallback answers “where does the browser go if the app does not open?” You need all three. Verification without a path mapping dumps people on the app home screen. A path without verification leaves them on the website even when the app is installed.

Link hosts are a chottu.link subdomain or a custom domain you verify. The association files have to be reachable on the host that appears in the campaign URL. Pointing the AASA file at www.deeplink.in does not verify a link that people actually tap on your-app.chottu.link or on your own domain.

Differences that affect testing

iOS caches the AASA file. After you change the file or the entitlement, an already installed build may keep the old decision until the system refreshes it. Android verification is tied to the install and to the signing certificate. A debug keystore and a Play App Signing key have different SHA-256 fingerprints. The dashboard has to list the fingerprint of the build you are testing, or auto-verify fails and the browser keeps the link.

Neither file makes deferred deep linking happen by itself. They only cover the installed-app case. A phone without the app still needs the fallback and, if you want the screen after install, the deferred flow. Treat a successful Universal Link or App Link test and a successful first-open-after-install test as two separate checks.

TODO: [fact needed] any extra path-pattern limits Deeplink writes into the AASA or asset links files, if the team wants those patterns documented beside the platform rules.

Steps

  1. Collect the app identifiers. Android: application id and the SHA-256 of the key that signs the build you ship. iOS: bundle id and Apple team id, plus the Associated Domains entitlement for the link host.
  2. Save them on the Deeplink app. Enter those values in the dashboard so the generated association files match the binaries.
  3. Confirm the files on the link host. Fetch /.well-known/apple-app-site-association and /.well-known/assetlinks.json on the domain you put in campaigns. They should return JSON, not an HTML error page.
  4. Tap a real link on a device. Install the matching build, tap an HTTPS link to that host, and confirm the app opens. Then repeat with the app uninstalled to see the fallback.

Universal Links and Android App Links

iOS Universal LinksAndroid App Links
Association fileapple-app-site-associationassetlinks.json
Identity in the fileTeam id and bundle idPackage name and SHA-256 fingerprints
App-side settingAssociated Domains entitlementIntent filter with autoVerify
If verification failsLink stays in Safari or the in-app browserA chooser or the browser handles the link

Example

You ship com.example.shop signed by a Play app signing key, and an iOS app with bundle id com.example.shop under team ABCDE12345. Both ids are saved on the Deeplink app. A campaign uses https://go.example.com/product/42 on a verified custom domain. iOS opens the app only if the AASA on go.example.com lists ABCDE12345.com.example.shop. Android opens the app only if assetlinks.json lists com.example.shop and that signing certificate’s SHA-256.

Frequently asked questions

Can one HTTPS link serve both platforms?

Yes. Universal Links and Android App Links are both HTTPS. One host can publish both association files, and one path can be the campaign URL. Deeplink is built so that host is the link domain for the app, with both files generated from the ids you stored.

Why does the link open the website even though the app is installed?

The usual causes are a missing or mismatched association file, an entitlement or intent filter that names a different host, or an Android fingerprint for the wrong keystore. Fetch the well-known files on the exact host in the URL and compare them with the installed build. A custom scheme can still open the app when HTTPS verification has not succeeded, but that is a separate link.

Get started

Create a Deeplink account to make a link, set a web fallback, and review click and install analytics.

Create a Deeplink accountRead about Deeplink pricingOpen the Deeplink documentation