# 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](https://www.statista.com/statistics/259329/ios-and-android-app-user-retention-rate), with a large gap between top performers and weaker categories. [Verified App Links](https://developer.android.com/training/app-links/about) are the difference between a link that opens your app and a link that dumps users in a browser.

## What Android App Links actually are

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](https://developer.android.com/training/app-links/deep-linking), 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](https://developer.android.com/training/app-links/create-deeplinks).
- Android App Links are verified web links. The system routes them straight to your app.

Android App Links are a [special deep linking capability](https://developer.android.com/training/app-links/about) 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](https://developer.android.com/codelabs/android-app-links-introduction) 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](https://developer.android.com/training/app-links/create-deeplinks), 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.

## How to set up and verify your App Links

Verification has 2 parts: a [manifest declaration](https://developer.android.com/training/app-links/add-applinks) in your app and a [JSON file](https://developer.android.com/training/app-links/configure-assetlinks) on your domain. Both must agree on the [target domain](https://www.anything.com/docs/launch/domains) and your [signing certificate](https://developer.android.com/training/app-links/configure-assetlinks).

### 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](https://developer.android.com/guide/topics/manifest/intent-filter-element) 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](https://developer.android.com/guide/topics/manifest/intent-filter-element).

```xml
<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](https://developer.android.com/training/app-links/verify-applinks) 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](https://developer.android.com/training/app-links/verify-android-applinks?hl=tr) 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.

### Step 3: Create and host assetlinks.json

The file must live at `https://<domain>/.well-known/assetlinks.json`. The Digital Asset Links protocol calls this the [official file location](https://developers.google.com/digital-asset-links/v1/getting-started) for a statement list on a site. Statement lists in any other location or with any other name are not valid.

```json
[{
  "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](https://developer.android.com/studio/write/app-link-indexing), regardless of whether your intent filter includes `https`. If you declare a wildcard host like `*.example.com`, publish the file at the [root hostname](https://developer.android.com/training/app-links/verify-android-applinks?hl=tr), `example.com`.

### Step 4: Install and wait for verification

After you install the app, Android runs verification asynchronously. Wait [at least 20 seconds](https://developer.android.com/training/app-links/verify-applinks) for it to complete. In practice the full process can take up to [5 minutes](https://developer.android.com/codelabs/android-app-links-introduction), 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](https://developer.android.com/training/app-links/deep-linking), 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](https://developer.android.com/training/app-links/troubleshoot) 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](https://developer.android.com/training/app-links/troubleshoot).
- **Wrong Content-Type:** The server must send `Content-Type: application/json` with [HTTP status 200](https://developer.android.com/identity/credential-manager/prerequisites).
- **Not served over HTTPS:** Android verifies the file over [encrypted HTTPS only](https://developer.android.com/studio/write/app-link-indexing).
- **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](https://support.google.com/google-ads/answer/16434983?hl=en) crawling of `/.well-known/assetlinks.json`, verification fails. [Allow](https://developer.android.com/identity/credential-manager/prerequisites)`/.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>`.

## Tools that test links before you publish

You can test links before you [publish your app](https://www.anything.com/docs/launch/publish), and several tools validate the setup against a connected device or directly against your hosted file.

The Statement List [Generator and Tester](https://developer.android.com/training/app-links/test-applinks) checks an existing statement file for you. The [Digital Asset Links API](https://developers.google.com/digital-asset-links/reference/rest/v1/assetlinks/check) confirms the file is properly hosted through a [simple GET request](https://developers.google.com/digital-asset-links/reference/rest/v1/assetlinks/check) 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:

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

The Play Console [Deep Links dashboard](https://developer.android.com/training/app-links/tools) 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](https://developer.android.com/training/app-links/add-applinks), 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](https://www.anything.com/docs/share/export) 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](https://capacitorjs.com/docs/guides/deep-links) 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](https://www.anything.com/docs/share/export) 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](https://developer.android.com/training/app-links/instant-app-links)`/.well-known/assetlinks.json`; [iOS uses](https://developer.apple.com/documentation/xcode/supporting-associated-domains)`/.well-known/apple-app-site-association`. They coexist because the filenames differ.

iOS adds its own wrinkle. On [iOS 14 and later](https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.associated-domains), devices fetch the association file through an [Apple-managed CDN](https://developer.apple.com/documentation/bundleresources/entitlements/com.apple.developer.associated-domains), which requests it [within 24 hours](https://developer.apple.com/documentation/xcode/supporting-associated-domains). 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.

7 min read
