On this page: Learn how to author deep links in email and SMS content, configure them in Adobe Journey Optimizer, and handle the tracked links in your iOS and Android apps so recipients land on the right in-app screen.
Deep links help you take recipients from an email or SMS message to a specific screen or piece of content in your mobile app. It helps bring people straight to the intended in-app experience, without routing them through a web browser or an app store, so the journey stays relevant and on-brand.
When your recipients click the deep link, they are taken directly to the intended in-app content - provided you have completed:
-
the configuration steps in Journey Optimizer;
-
the mobile app implementation steps for iOS and Android in your mobile app.
/ee/v1/mclick/*) to ensure compatibility and click tracking.Authoring deep links authoring
Email authoring-email
For email messages, you have two options to insert a deep link:
-
Email Designer: Make sure link tracking is enabled. Select the element you want to link (text, button, or image), click Insert link in the contextual toolbar, and choose Deeplink to enter your deep link URL. Learn more on inserting links
-
Personalization editor (code): Insert the deep link directly into the HTML using the following snippet:
code language-html <a class="arc-link" data-nl-type="DEEPLINK" href="<<deeplink_url>>" id="acr-link-7821368" style="text-decoration:underline;" target="_blank" data-tracking-type="DEEPLINK">Click Here</a>note tip TIP Replace <<deeplink_url>>with your actual deep link URL and use a uniqueidfor each block to avoid conflicts.
SMS authoring-sms
For SMS, deep links are authored using the Url helper function in the personalization editor. Learn how to add links to SMS content in this section.
To insert deep links in SMS content, use the following syntax:
{{url originalUrl='<<url>>' type='DEEPLINK' action='CLICK'}}
<<url>> with your actual deep link URL.Configuration in Journey Optimizer configuration
To be able to use deep links in emails and SMS for your mobile apps, complete the configuration steps below.
-
In Journey Optimizer, delegate the subdomain where deep linking is enabled. Learn more
-
Host the AASA file for iOS and the assetLinks.json file for Android on your subdomain. Contact Adobe Customer Care or your Adobe representative with the details below:
-
For iOS (AASA):
- Delegated subdomain
- App bundle ID
-
For Android (assetLinks.json):
- Delegated subdomain
- App bundle ID
- SHA-256 certificate fingerprint
-
/ee/v1/mclick/*, which Adobe hosts and resolves.Mobile app implementation mobile-implementation
This section explains how to implement mobile deep links with Adobe Journey Optimizer so that, in a typical HTTPS setup (universal links and app links), a single URL can:
- Open a specific screen inside your mobile app when the app is installed, or
- Open your website as a fallback when the app is not installed.
When link tracking is enabled for your message, Journey Optimizer continues to track these clicks, includes them in reporting, and can use them in content experiments if you run them on the message.
This section provides common implementation patterns for deep links. Your exact setup depends on your app architecture and routing framework.
iOS (Universal Links) ios-implementation
-
In Xcode, select your target through Signing & Capabilities > + Capability > Associated Domains.
-
Add entries for your delegated subdomains, for example:
code language-text applinks:www.mybusiness.com applinks:data.email.mybusiness.com -
Handle Universal Links in the app and get the original link from the response header.
accordion Example: iOS 13+ with scenes code language-swift class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb, let incomingURL = userActivity.webpageURL else { return } handleUniversalLink(url: incomingURL) } private func handleUniversalLink(url: URL) { // Only handle AJO tracked mobile clicks guard url.host == "data.email.mybusiness.com", url.path.hasPrefix("/ee/v1/mclick") else { // Could also handle direct www.mybusiness.com links here return } resolveTrackedUrlAndRoute(url) } private func resolveTrackedUrlAndRoute(_ trackedUrl: URL) { var request = URLRequest(url: trackedUrl) request.httpMethod = "GET" URLSession.shared.dataTask(with: request) { _, response, error in guard error == nil, let httpResponse = response as? HTTPURLResponse, let locationValue = httpResponse.allHeaderFields["Location"] as? String, let finalUrl = URL(string: locationValue) else { return } DispatchQueue.main.async { self.routeToDestination(finalUrl) } }.resume() } private func routeToDestination(_ url: URL) { // Example: map URL paths to screens // https://www.mybusiness.com/dashboard/offers/coupons // → OffersViewController for Coupons } }
mclick URL and read the Location header, then route based on the final URL.mclick URL in Safari; that defeats the purpose of deep linking.Android (App Links) android-implementation
-
Add App Link intent filter in your Android app.
code language-xml <activity android:name=".DeepLinkActivity" android:exported="true"> <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="https" android:host="data.email.mybusiness.com" android:pathPrefix="/ee/v1/mclick" /> </intent-filter> </activity> -
Implement the deep link handler.
accordion In Kotlin: code language-kotlin class DeepLinkActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val trackedUri = intent?.data if (trackedUri == null || trackedUri.host != "data.email.mybusiness.com" || !trackedUri.path.orEmpty().startsWith("/ee/v1/mclick")) { finish() return } resolveTrackedUrlAndRoute(trackedUri) } private fun resolveTrackedUrlAndRoute(trackedUri: Uri) { lifecycleScope.launch(Dispatchers.IO) { try { val finalUrl = followRedirect(trackedUri.toString()) withContext(Dispatchers.Main) { routeToDestination(finalUrl) finish() } } catch (e: Exception) { // Optionally log error, fallback to browser finish() } } } private fun followRedirect(trackedUrl: String): Uri { val client = OkHttpClient.Builder() .followRedirects(false) // We want to read Location ourselves .build() val request = Request.Builder() .url(trackedUrl) .get() .build() client.newCall(request).execute().use { response -> val location = response.header("Location") ?: throw IllegalStateException("Missing Location header") return Uri.parse(location) } } private fun routeToDestination(finalUri: Uri) { // Example: interpret https://www.mybusiness.com/dashboard/offers/coupons // and open the correct Activity / Fragment } }
mclick URL and use the Location header to determine the final destination.followRedirects(false) so you control redirect handling and can log analytics accurately if needed.Recommended practices deeplink-best-practices
- Use stable paths: Prefer routes that are resilient to app UI changes (for example
/account/ordersinstead of/tab/3/view/2). - Account for tracked paths: When link tracking is enabled, the clicked link may use tracked path patterns (for example
/ee/v1/mclick/). Make sure your router can parse the final URL after resolving the tracked link. - Keep parameters predictable: Define a consistent parameter scheme (for example
?orderId=12345). - Avoid sensitive data in URLs: Do not put secrets or personal data directly into the deep link URL.
- Test your deep link: Send a proof and click the deep link on a device where the app is installed.
- Validate on real devices: Universal links and tracked-link resolution behaviors are more reliable to validate on physical devices rather than simulators.
- Validate the app-side routing: If the deep link does not open the expected screen, validate the app-side routing and the URL format (host/path/query and URL encoding).
- Keep app initialization in mind: App Links / Universal Links behavior is most reliable after the app has been installed and opened at least once.
Troubleshooting and FAQ troubleshooting-faq
- Verify the URL matches the host and path patterns your app is registered to handle, including tracked click paths when link tracking is enabled (for example paths under
/ee/v1/mclick/). - For iOS universal links and Android app links, confirm domain association (AASA /
assetlinks.json) is correctly configured and reachable. - Test on a real device (simulators/emulators can behave differently for link association).
- Confirm the app-side router correctly parses the URL path/query.
- Check URL encoding: reserved characters should be URL-encoded.
- Validate parameter names and values match what the router expects.
- If the same HTTPS URL can be served by your website, the link can open a web page as a fallback when the app is not installed (configure your web destination and routing accordingly).
-
Create a proof with a deep link, click it on iOS and Android devices (installed and not installed scenarios).
-
Validate:
- The final email or SMS link value (host/path/query)
- The OS-level association (if using universal links / app links)
- The in-app routing outcome
assetlinks.json configuration for each subdomain that should support the feature.appname://path)?appname://path), but the recommended approach is a universal link or app link (https://), which matches the HTTPS-based setup in the configuration and implementation sections on this page.Location header when your app performs a GET on the mclick URL, so you can use them for in-app analytics./ee/v1/click/ URLs?mclick flow described on this page.This section contains structured knowledge intended to support interpretation, retrieval, and question answering related to this topic.
For complete understanding, this information should be combined with the documentation on this page. Neither source is intended to stand alone; the page describes the feature, while this section provides additional context that helps disambiguate terminology, intent, applicability, and constraints.
- TL;DR: This page explains how to author deep links in email and SMS content, configure them in Journey Optimizer, and handle the tracked links in iOS and Android apps so recipients land on the right in-app screen.
Intents:
- Author a deep link in email (Email Designer or Personalization editor code) and in SMS (Url helper function)
- Complete the Journey Optimizer configuration for universal links (iOS) and app links (Android)
- Implement mobile app handling of tracked
mclicklinks in iOS and Android - Follow recommended practices and troubleshoot deep links that do not open the app or the expected screen
- Test deep links end-to-end by sending a proof and clicking on real devices
Glossary:
- Deep link: A link that takes recipients from an email or SMS message directly to a specific screen or content in a mobile app (product-specific)
- Universal links (iOS) / App links (Android): HTTPS-based deep links the configuration on this page applies to (product-specific)
- AASA / assetLinks.json: The association files hosted on your delegated subdomain for iOS (AASA) and Android (assetLinks.json) (product-specific)
/ee/v1/mclick/*: Tracked URLs that Adobe hosts and resolves for deep link clicks when link tracking is enabled (product-specific)
Guardrails:
- Deep links will not work unless you complete both the configuration and the mobile app implementation steps on this page.
- Deep linking is supported for both iOS and Android using tracked URLs (
/ee/v1/mclick/*) for compatibility and click tracking. - The configuration section applies when you use universal links (iOS) and app links (Android), which are HTTPS-based deep links.
- Tracked deep link clicks use URLs under
/ee/v1/mclick/*, which Adobe hosts and resolves, and apply when link tracking is enabled for the message. - For non-tracked links, the URL is not rewritten through Adobe systems; you must configure universal links or app links on your own domains and hosting.
- The app must perform a GET on the
mclickURL and read theLocationheader, then route based on the final URL; do not simply open themclickURL in a browser. - Hosting the AASA (iOS) and assetLinks.json (Android) files requires contacting Adobe Customer Care with the delegated subdomain and app bundle ID; Android also requires the SHA-256 certificate fingerprint.
Terminology:
- Canonical name: Deep link — Acronym: n/a — variants: deeplink, Deeplink (Insert link option)
- Synonyms: “universal links” (iOS) and “app links” (Android) = the HTTPS-based deep link setup
- Do not confuse: “
/ee/v1/mclick/*” (tracked deep link flow handled as an app deep link) ≠ “/ee/v1/click/” (opens in the device’s default web browser, standard click tracking) - Do not confuse: “tracked links” (rewritten through Adobe, use
mclick) ≠ “non-tracked links” (not rewritten; configured on your own domains)
FAQ:
- Q: What must be done before deep links work? — Complete both the configuration steps in Journey Optimizer and the mobile app implementation steps for iOS and Android.
- Q: How should the app handle the tracked link? — Perform a GET on the
mclickURL, read theLocationheader, and route based on the final URL; do not open themclickURL directly in a browser. - Q: What happens if the app is not installed? — If the same HTTPS URL can be served by your website, the link can open a web page as a fallback.
- Q: Are UTM parameters available in the app? — Yes; UTM parameters configured in Journey Optimizer are included in the final URL returned in the
Locationheader. - Q: How do I test end-to-end? — Send a proof (create a proof with a deep link) and click it on iOS and Android devices, for both installed and not-installed scenarios, validating on real devices.
- Q: Should I use a custom URL scheme like
appname://path? — You can, but the recommended approach is a universal link or app link (https://) matching the HTTPS-based setup on this page.