Overview
Deep linking routes users to a specific screen in your app when they tap a link — whether from an email, SMS, website, push notification, or in-app message. If the app is not installed, the operating system can redirect users to the app store or a fallback web page. This guide covers:- Types of deep links and when to use each
- Platform setup for Android and iOS
- Handling deep links in your app with the OneSignal SDK
- Channel-specific behavior for push, email, and in-app messages
For general URL and link configuration (Launch URLs, UTM parameters, dynamic URLs, link tracking), see URLs, links, & deep links.
Prerequisites
Before setting up deep links, you need:- A OneSignal account with an app configured
- The OneSignal SDK installed in your mobile app
- A domain you control, hosted over HTTPS, for Universal Links or App Links
- Access to your app’s source code and build configuration (Xcode for iOS, Android Studio for Android)
Types of deep links
There are three common deep linking mechanisms. Each has different behavior depending on whether the app is installed.| Type | Platform | Format | App not installed |
|---|---|---|---|
| Universal Links | iOS 9+ | https://yourdomain.com/path | Opens the URL in Safari |
| App Links | Android 6.0+ | https://yourdomain.com/path | Opens the URL in the browser |
| Custom URI schemes | iOS & Android | myapp://path | Fails silently or shows an error |
https:// URLs, work across channels (push, email, SMS), and provide fallback behavior when the app is not installed. Custom URI schemes (myapp://) are simpler to set up but do not provide fallback behavior and may not work in all contexts (e.g., email clients).
Android setup (App Links)
Use Android Studio’s App Links Assistant to generate the required configuration.Configure intent filters
Add an intent filter to the Activity that should handle the deep link:Handle the incoming intent
Host the Digital Asset Links file
Generate theassetlinks.json file using Android Studio’s App Links Assistant and host it at:
iOS setup (Universal Links)
Apple Universal Links open your app when a user taps a matchinghttps:// URL. For simpler use cases where the app is guaranteed to be installed, you can use URL Schemes instead.
Enable Associated Domains
- In Xcode, select your target → Signing & Capabilities → add Associated Domains
- Add your domain:
applinks:yourdomain.com
Handle the Universal Link in your app
Host the Apple App Site Association file
Create anapple-app-site-association (AASA) file and host it at:
TEAMID with your Apple Team ID and com.example.app with your bundle identifier:
iOS Launch URL behavior
OneSignal’s iOS SDK usesopenURL to handle the Launch URL (url property). This causes the link to open in the browser first, then redirect back into the app — which can be a poor user experience.
To avoid this, use one of these approaches:
- Use
datainstead ofurlin the API payload and handle the deep link in your Push Notification Click Listener - Suppress Launch URLs by adding
OneSignal_suppress_launch_urlsto yourInfo.plistas a Boolean with valueYES, then handle all navigation in the click listener
Handle deep links with the OneSignal SDK
The most reliable way to handle deep links from OneSignal messages is to use the SDK’s click listeners rather than relying on OS-level link resolution. This gives you full control over navigation in your app.Push notification click listener
UseaddClickListener to intercept notification clicks and route the user based on the deep link URL or additional data:
addClickListener() Push.
In-app message click listener
Use the in-app message click listener to handle deep links from in-app message buttons and actions:addClickListener() In-App.
Push notifications
Include the deep link in one of two ways:| Method | API property | Behavior |
|---|---|---|
| Launch URL | url (or app_url for mobile-only) | OS opens the URL directly. On iOS, this opens the browser first unless suppressed. |
| Additional Data (recommended) | data | URL is passed to your click listener. You control navigation entirely. |
Platform behavior
- Android: Opens the matching Activity directly via App Links
- iOS: Opens Safari, then the app (unless you suppress Launch URLs and handle navigation in the click listener)
url, web_url, and app_url targeting.
Emails
By default, OneSignal rewrites email links for click tracking. This changes the URL, which breaks deep linking because the OS no longer recognizes the domain as matching your app’s Associated Domain.Enable deep links in email
To preserve deep links, disable click tracking using one of these methods:- Dashboard: Uncheck Track link clicks in the email editor
- API: Set
disable_email_click_tracking: true - Per-link: Use the Liquid filter
{{ 'https://yourdomain.com/path' | do_not_track_link }}to disable tracking on individual links while keeping it enabled for others

Email deep link behavior
| Scenario | Result |
|---|---|
| iOS + Safari + Universal Link + Tracking disabled | Opens app directly |
| iOS + Safari + Universal Link + Tracking enabled | Opens Safari, prompts to open app |
| iOS + non-Safari mail client + Universal Link | Opens App Store if app not installed |
| Android + App Link + Tracking disabled | Opens app directly |
| Android + App Link + Tracking enabled | Opens browser first, then app |
In-app messages
Deep links in in-app messages use the click listener pattern. You set a custom action identifier in the message editor, then handle it in your app code.Drag-and-drop editor
- Add a button or clickable element
- Set the click action to Custom Action ID
- Enter your deep link URI as the Action Name (e.g.,
https://yourdomain.com/promoormyapp://promo)
HTML editor
Use theopenUrl method in the In-App JS Library to trigger deep links from custom HTML.
Handle the click
Use the in-app message click listener to intercept the action and navigate the user in your app.Testing deep links
Android
Useadb to test App Links without sending a notification:
assetlinks.json is reachable:
iOS
Use Apple’s Associated Domains validation tool to verify your AASA file. You can also test Universal Links by:- Pasting the link in the Notes app
- Long-pressing the link to confirm the “Open in [App]” option appears
- Tapping the link to verify it opens your app
Universal Links do not work when typed directly into Safari’s address bar — they must be tapped from another app (Notes, Mail, Messages, etc.).
OneSignal test messages
- Send a test push from the OneSignal dashboard with a deep link URL as the Launch URL or in Additional Data
- Verify the notification opens the correct screen in your app
- Check your click listener logs to confirm the URL or data was received
Troubleshooting
iOS deep link opens Safari instead of the app
This is the most common issue. Possible causes:- AASA file not hosted correctly — Verify it’s at
https://yourdomain.com/.well-known/apple-app-site-associationwithContent-Type: application/jsonand no redirects - Associated Domains not configured — Check Xcode → Signing & Capabilities → Associated Domains includes
applinks:yourdomain.com - Launch URL behavior — OneSignal’s iOS SDK uses
openURLfor theurlproperty, which triggers browser-first behavior. Usedata+ click listener or suppress Launch URLs instead - Testing in Safari — Universal Links don’t activate from the Safari address bar. Test from Notes, Mail, or another app.
Android deep link opens the browser
autoVerifymissing — Ensure your intent filter includesandroid:autoVerify="true"assetlinks.jsonnot found — Verify the file is athttps://yourdomain.com/.well-known/assetlinks.jsonand returns HTTP 200- SHA256 fingerprint mismatch — The fingerprint in
assetlinks.jsonmust match your app’s signing certificate. Debug and release builds use different certificates.
Deep link works in push but not email
Email click tracking rewrites URLs, breaking domain verification. Disable click tracking for emails that contain deep links.Deep link received but app doesn’t navigate
- Verify your click listener is registered early in the app lifecycle (e.g., in
Application.onCreate()orAppDelegate.didFinishLaunchingWithOptions) - Check that the URL or action ID matches what your routing logic expects
- On iOS, confirm you’re not relying on
urlwithout suppressing Launch URLs — the browser may consume the link before your listener fires
FAQ
What happens if the app is not installed?
With Universal Links (iOS), the URL opens in Safari as a regular web page. With App Links (Android), the URL opens in the default browser. In both cases, you can configure your web page to redirect to the appropriate app store. Custom URI schemes (myapp://) fail silently or show an error if the app is not installed.
Should I use Launch URL or Additional Data for deep linking?
Additional Data (data) is recommended for mobile deep links because it gives you full control over navigation via the click listener. Launch URL (url) is simpler but has limitations on iOS (browser redirect) and does not allow custom routing logic.
Can I personalize deep links with user data?
Yes. Use Dynamic URLs with Liquid syntax to inject user properties, tags, or custom data into your deep link URLs. For example:https://yourdomain.com/profile/{{subscription.external_id}}.
Can I use deep links with custom URI schemes?
Yes. Set your custom scheme (e.g.,myapp://screen) as the Launch URL or Additional Data value. Custom schemes work well for push and in-app messages but may not work in email clients. They also provide no fallback if the app is not installed.
Do deep links work with OneSignal Journeys?
Yes. When configuring a message step in a Journey, set the Launch URL or Additional Data to your deep link. The behavior is the same as a standalone push or in-app message.URLs, links, & deep links
Launch URLs, UTM parameters, dynamic URLs, and link tracking configuration.
Mobile SDK reference
Full API reference for click listeners and notification event handling.
In-App Click Actions
Configure click actions for in-app message buttons and elements.
Mobile push setup
Platform-specific push notification setup for Android and iOS.