← All

Android app links explained for solo developers

Android app links explained for solo developers

You ship an Android app, send users a link to your latest content, and the link opens a browser instead of your app. The user stares at a login page, gives up, and never comes back. That broken handoff costs you the re-engagement you worked to earn.

Recent retention data varied widely by category, with a large gap between top performers and weaker categories. Verified App Links are the difference between a link that opens your app and a link that dumps users in a browser.

Use verified App Links when you want Android to open website URLs directly in your app without a chooser. Custom schemes and plain web links can send users through routing you do not control.

Android recognizes 3 deep link types, and each one creates a different routing risk.

  • Custom deep links use a custom scheme like example://products/123. They can trigger a disambiguation dialog if another app claims the same scheme.
  • Standard web links use http or https. On Android 12 and later, Android usually opens them in the browser by default.
  • Android App Links are verified web links. The system routes them straight to your app.

Android App Links are a special deep linking capability in Android 6 and later that opens your verified website URLs directly in your app, with no app picker.

The trust comes from a Digital Asset Links statement hosted on your website, which establishes a secure, verified association between your domain and your app. An unauthorized app cannot handle your links, because Android must verify the link against a website you own before it qualifies.

Why Android 12 made verification non-optional

Verify your domains if you expect web links to open your app on modern Android. Starting in Android 12, API 31, a generic web intent resolves to your app only if your app is approved for that domain. If Android has not approved your app, the intent resolves to the user's default browser app instead.

That change reset the baseline for web-to-app routing. Plain http or https deep links without App Links verification send users on Android 12 and later to a browser.

Verification has 2 parts: a manifest declaration in your app and a JSON file on your domain. Both must agree on the target domain and your signing certificate.

Step 1: Add the autoVerify intent filter

Your app needs an intent filter in AndroidManifest.xml that declares the domain and tells Android to verify it. The android:autoVerify attribute tells the system verification whether your app belongs to the URL domains in your intent filters. Android sets the default to false, and Android introduced it in API level 23.

<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <data android:scheme="http" />
  <data android:scheme="https" />
  <data android:host="www.example.com" />
</intent-filter>

Android auto-verifies intent filters that include these entries:

  • android.intent.action.VIEW
  • android.intent.category.BROWSABLE
  • android.intent.category.DEFAULT
  • The http or https scheme

Miss one, and verification will not run.

Step 2: Get your release SHA-256 fingerprint

You need the SHA-256 fingerprint of the certificate that signs your release build. You can pull it from Play Console under Release > Setup > App signing, or run keytool against your keystore. This fingerprint is a frequent silent failure point, so check it before you debug anything else.

The file must live at https://<domain>/.well-known/assetlinks.json. The Digital Asset Links protocol calls this the official file location for a statement list on a site. Statement lists in any other location or with any other name are not valid.

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.puppies.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

The hosting rules are strict. Serve the file as Content-Type: application/json. Your domain must make it accessible over HTTPS, regardless of whether your intent filter includes https. If you declare a wildcard host like *.example.com, publish the file at the root hostname, example.com.

Step 4: Install and wait for verification

After you install the app, Android runs verification asynchronously. Wait at least 20 seconds for it to complete. In practice the full process can take up to 5 minutes, so do not panic if the first check shows nothing.

One design rule shapes where your link should land. The deep link should take users directly to content, with no prompts, interstitial pages, or logins. Users should see the app content even if they never opened the app before.

The verification failures that waste your weekend

Most App Link failures trace back to the same handful of hosting and certificate mistakes, and each one can delay a release.

  • HTTP redirects: Verification fails if the assetlinks.json response returns a 301 or 302 redirect.
  • Wrong Content-Type: The server must send Content-Type: application/json with HTTP status 200.
  • Not served over HTTPS: Android verifies the file over encrypted HTTPS only.
  • Fingerprint mismatch: The sha256_cert_fingerprints must match the certificate that signed the app.
  • Missing autoVerify: The intent filter needs the android:autoVerify="true" attribute.
  • Blocked by robots.txt: If robots.txt blocks crawling of /.well-known/assetlinks.json, verification fails. Allow /.well-known/ for all user agents.

Start with the hosted file and certificate before you rerun verification. Those checks catch the silent failures that usually make App Links look broken.

The fingerprint mismatch deserves special attention if you use Play App Signing. Play re-signs your app with a different key than your local keystore, so use the fingerprint from Play Console under Release > Setup > App signing. Local debug and upload keys are the wrong fingerprints for release verification.

When you need to diagnose a live device, the adb command tells you the real state. Run adb shell pm get-app-links <your-package-name> to see whether a domain shows verified, none, or legacy_failure. To force another attempt, run adb shell pm verify-app-links --re-verify <your-package-name>.

You can test links before you publish your app, and several tools validate the setup against a connected device or directly against your hosted file.

The Statement List Generator and Tester checks an existing statement file for you. The Digital Asset Links API confirms the file is properly hosted through a simple GET request that reports whether the assets are linked. Both work before any app upload.

Inside Android Studio, the App Links Assistant under the Tools menu parses and validates your assetlinks.json with detailed error explanations and a Link and Verify button. To test a specific link from the terminal, run:

adb shell am start -W -a android.intent.action.VIEW -d <URI> <PACKAGE>

The Play Console Deep Links dashboard under Grow > Deep links shows domain verification status and fix guidance. The catch: it requires an uploaded app first, so it is not part of your pre-upload checklist.

What AI app builders still have to confirm

Whatever tool builds your app must produce the correct manifest intent filter, and your domain must host a valid assetlinks.json. Before you trust the setup, confirm your platform exposes those controls or lets you export the code to add them.

Code export and GitHub Sync let you inspect the project. If your builder gives you the actual project, you can add the autoVerify intent filter and host the JSON yourself, instead of hoping a closed platform handled it. Some platforms point you elsewhere for link management.

Capacitor documents App Links configuration directly, and the Capacitor App API handles deep links on startup. If you build with us, confirm the release target before promising native Android behavior. Our Android support is in development, so use export the code and GitHub Sync when you need to inspect or adapt platform files.

If you build for Android and iOS, plan for separate files on the same domain. Android uses /.well-known/assetlinks.json; iOS uses /.well-known/apple-app-site-association. They coexist because the filenames differ.

iOS adds its own wrinkle. On iOS 14 and later, devices fetch the association file through an Apple-managed CDN, which requests it within 24 hours. Updates can propagate slower than Android's on-demand re-verification.

How to lock this in for your next release

Get your Play App Signing fingerprint, write it into assetlinks.json, host that file as JSON over HTTPS with no redirects, add the autoVerify intent filter for each domain, then validate with the App Links Assistant or the Digital Asset Links API before you ship.

If you build with us, start with code export, inspect the Android manifest, and test link routing on a real Android 12 or later device before your first user taps a link.