Android App Links setup, step by step

Set up Android App Links end to end. Add an autoVerify intent filter, host assetlinks.json with the right fingerprint and verify each domain with adb.

Short answer: Android App Links need an intent filter with android:autoVerify="true" for your http and https hosts, and an assetlinks.json file at https://<host>/.well-known/assetlinks.json naming your package and the SHA-256 fingerprint of the key that signs the installed app. Verify with adb shell pm get-app-links and look for verified.

What is an Android App Link?

Android App Link: an http or https URL on a domain you have verified with Digital Asset Links, which Android opens directly in your app without asking the user to choose.

A plain deep link (a custom scheme, or an unverified web URL) can be claimed by other apps and may show a chooser. Google says custom schemes have no web fallback and can be claimed by other apps. Verified App Links avoid both problems.

Step 1: add the intent filter

In AndroidManifest.xml, add a filter to the activity that handles links:

<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="example.com" />
</intent-filter>
  • autoVerify: Google says it "is required for App Links".
  • BROWSABLE: "Without it, clicking a link in a browser cannot resolve to your app."
  • Schemes: include http and https. Google's sample notes: "Do not include other schemes, as this will prevent verification."
  • Merging: multiple <data> elements in one filter are merged into every combination, so use separate filters for distinct scheme and host pairs.

Step 2: get the right fingerprint

The fingerprint must match the certificate that signs the app users install.

  • Without Play App Signing: run keytool -list -v -keystore my-release-key.keystore and copy the SHA-256 value.
  • With Play App Signing: open Play Console > Protected with Play > Play Store distribution > Play app signing, and copy the app signing key's SHA-256. Google says a local keytool fingerprint "will usually not match the one on users' devices".

A valid value is 32 uppercase hex pairs joined by colons, 95 characters long. You can list several fingerprints, for example debug and release.

Step 3: write and host assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "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"]
  }
}]

Host rules from Google:

  • At https://<host>/.well-known/assetlinks.json, over HTTPS.
  • Served as application/json.
  • No 301 or 302 redirects; anything other than a 200 gives an empty statement list.
  • On every host in the manifest. For *.example.com, publish at the root hostname.

Check the published file with curl -I https://example.com/.well-known/assetlinks.json and Google's Statement List tester.

Why do App Links open the browser on Android 12?

From Android 12, Google says a web intent only opens your app if the app is approved for that specific domain; otherwise it resolves to the default browser.

How hosts are judged also changed:

  • Android 11 and lower: all hosts in the manifest must verify, or none do. One staging or VPN-only host breaks everything. See one host fails.
  • Android 12 and later: each host is verified separately.
  • Apps targeting lower SDKs can opt into the new verification for testing with adb shell am compat enable 175408749 PACKAGE_NAME.

Step 4: verify on a device

Install the app, wait at least 20 seconds, then run:

adb shell pm set-app-links --package com.example.app 0 all
adb shell pm verify-app-links --re-verify com.example.app
adb shell pm get-app-links com.example.app

The device must be online. Wait a few minutes before reading the result. Only verified means success. Other states include none, approved, denied, legacy_failure and codes of 1024 and above for verifier errors.

Then fire a test link:

adb shell am start -W -a android.intent.action.VIEW -d "https://example.com/product/1" com.example.app

Step 5: check with Google's tools

  • Digital Asset Links API: https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls shows what Google reads.
  • Google's Statement List tester: tests a published statement file.
  • Play Console > Grow > Deep links: lists deep links and configuration errors.
  • Android Studio App Links Assistant: validates the setup from Tools > App Links Assistant.

When you change the file later, remember the timing. On Android 14 and lower, updates are usually picked up on install or update. On Android 15 and later, changes can take up to seven days. Re-run adb shell pm get-app-links before each release.

FAQ

Common questions

Do App Links need both http and https in the filter?

Google's guidance is to declare `http` and `https` data schemes with your hosts in the verified filter. The file itself must always be served over HTTPS.

Why do App Links work on my debug build but not from Google Play?

Play App Signing re-signs the app with Google's app signing key. Add that key's SHA-256 from Play Console to assetlinks.json; see [wrong fingerprint](/errors/assetlinks-wrong-fingerprint/).

What does legacy_failure mean in get-app-links?

It is one of the states Google lists for a domain that is not verified. Only `verified` means verification succeeded, so check the file, the host and the filter.

Can two of my apps handle the same domain?

Only one app at a time can be associated with a domain on a device. If two apps resolve the same host and path, the most recently installed one wins.

What happens if the app is not installed?

The link opens in the browser, so the URL should work as a web page. Restoring the destination after install needs [deferred deep linking](/guides/deferred-deep-linking/).

What are UTM parameters?

UTM parameters are tags added to the end of a link, such as utm_source and utm_campaign, that tell analytics tools where a visit came from. They let you see which campaign, channel and ad brought each visitor.