Everyone uses "deep link," "universal link," and "App Link" interchangeably, but on a real device they describe different mechanisms with different failure modes. This guide pins each term down using the platform vendors' own definitions, then maps out how they relate.

The one-sentence version

A deep link is any URL that opens a specific screen in an app. An Android App Link and an iOS Universal Link are both the verified, HTTPS-only kind of deep link, where the operating system has confirmed your app is allowed to handle a website's links and so opens the app without asking the user first. Same idea on both platforms, different name and a different association file.

"Deep link" is the umbrella term and the verified variants live underneath it. A Universal Link is a deep link, an App Link is a deep link, and a custom myapp:// scheme is also a deep link, yet they behave very differently. The rest of this guide unpacks that hierarchy.

Deep links: the umbrella term

Google defines deep linking as "a standard Android platform capability that takes advantage of the intents system to route deep links to your app," handling "several types of deep links, from custom URIs to standard web schemes and domains." That covers two very different addressing styles:

  • Custom URI schemes, like myapp://product/42. Private to your app, simple to register, and fine when the app is installed. When it is not, the system has nothing to hand the link to, so the user gets a "cannot open page" error. There is no web fallback, because the scheme is not a web address.
  • Web URLs, like https://example.com/product/42. They use the http and https schemes, so the same URL can open your app on a phone and your website on a desktop. This is the style the verified variants build on.

A plain deep link without verification is "subject to the system disambiguation dialog," the "Open with" chooser shown when more than one app, or an app plus the browser, can handle a URL. Removing that chooser is exactly what App Links was designed for.

Android App Links: verified deep links on Android

Google calls an App Link "an enhanced deep linking capability that verifies deep links to your own website," so that after verification they "immediately open corresponding content in your app, without requiring the user to select your app from a disambiguation dialog." They are supported on Android 6 and later on devices with Google services, and are the recommended approach for links to your own site. To qualify, a URL clears three bars:

  • It uses HTTPS. The intent filter declares android:scheme="https" (and usually http too).
  • The intent filter opts in. It carries android:autoVerify="true" and declares the android.intent.action.VIEW action with the android.intent.category.DEFAULT and android.intent.category.BROWSABLE categories.
  • The website vouches for the app. You publish a Digital Asset Links file at https://yourdomain.com/.well-known/assetlinks.json naming your package and signing fingerprint. Android fetches it at install time and marks the domain verified if it matches.

When all three line up, the link opens your app with no chooser. When one is off, Android falls back to Chrome, which is the most common "my deep link is broken" report. We cover that exact symptom in why your App Link opens the browser.

iOS Universal Links: verified deep links on iOS

Universal Links are Apple's equivalent: a real HTTPS URL that opens your app when installed and your website when not, no chooser, backed by an association file. The parts have different names:

  • The Associated Domains entitlement, where the app claims domains with entries of the form applinks:example.com.
  • The apple-app-site-association file, a JSON file with no extension hosted at https://example.com/.well-known/apple-app-site-association. It lists your appID (TEAMID.bundleID) and the path patterns your app handles.

One iOS-specific gotcha: if a user long-presses a Universal Link and picks "Open in Safari" for a domain, iOS remembers it and stops routing that domain to your app. Long-press again and choose "Open in [App]" to reset. This catches people during testing, because the link looks broken when the real cause is a choice made earlier.

Side by side

There are really only three things, and the verified two are the same idea in different clothes:

  • Custom URI scheme (myapp://): registered in AndroidManifest.xml on Android and Info.plist on iOS. Works when installed, no web fallback, no verification.
  • Android App Link (verified HTTPS): autoVerify intent filter plus assetlinks.json. Opens the app when verified, falls back to the browser otherwise.
  • iOS Universal Link (verified HTTPS): Associated Domains entitlement plus apple-app-site-association. Opens the app when the association checks out, falls back to Safari otherwise.

The verified variants are HTTPS and the legacy variant is a custom scheme. Almost every behavioural difference flows from that: HTTPS links have a website to fall back to and an association file to verify against, custom schemes have neither.

Which one should you ship?

For links into your own product, use the verified HTTPS variant on each platform: App Links on Android, Universal Links on iOS. They give the cleanest experience and are what both vendors recommend. Keep a custom scheme only where an HTTPS URL does not fit, such as app-to-app handoffs or older integrations. The cost is the association file: you need control of the domain and have to host a small JSON file, served correctly, which is where most setups fail.

Test what you actually shipped

The only thing that settles an argument is a real link on a real device. Generate a clickable link or QR code with the Deep Link Tester, scan it, and watch what opens. To drive it from the terminal on Android, the adb deep link testing guide walks through adb shell am start.

Keep reading

Official docs


Last updated · June 2026 · by Belchior, mobile engineer