Airbridge Migration
Migrate from Airbridge to WarpLink: link and parameter mapping, exporting data, SDK swap, and deep linking, install attribution, and analytics.
This guide is for teams currently using Airbridge for tracking links, deep linking, or install attribution who are moving to WarpLink. It covers Airbridge-specific concept mapping, exporting your existing tracking links and data, and swapping the Airbridge SDK for the WarpLink SDK on each platform.
For the provider-agnostic playbook (planning, domains, cutover, and decommissioning), see the general migration guide. This page covers only what is specific to leaving Airbridge.
Airbridge's help center still has docs pages for an older "DeepLink Plan" product. That naming is deprecated. Airbridge's current deep linking feature is called "Deep Link." If your team's integration follows an old "DeepLink Plan" guide, check which SDK generation you are actually running before assuming the API surface below matches your code.
Concept Mapping
| Airbridge | WarpLink |
|---|---|
| Tracking Link | Link |
| Link Management (dashboard) | WarpLink dashboard |
abr.ge domain | aplnk.to domain |
| Custom domain (CNAME) | Custom domain |
| Short Link ID | Slug |
| Deep Link field / Campaign field | Link fields (see parameter mapping below) |
| Raw Data Export | Built-in click analytics |
| SKAdNetwork support, ML-based fraud detection, 330+ ad network integrations | Not replaced by WarpLink; see Attribution and Reporting |
1. Export Your Links
Tracking links via API. Airbridge's REST API includes a List Tracking Links endpoint and a Get a Tracking Link endpoint, authenticated with an API token you generate from Dashboard > Settings > Tokens.
Dashboard export. The Link Management view lets you download your full list of tracking links as a CSV file or a Google Sheet, capped at 10,000 tracking links per download.
Raw click and event data. Airbridge's Raw Data Export feature lets you pick an event and property template, a default preset or a fraud-check preset, and export it as CSV, or push it continuously to your own S3, Google Cloud Storage, BigQuery, or Snowflake destination. Raw data export is available on a higher Airbridge tier, not the entry-level tier most small teams start on.
2. Recreate Your Links
Recreate each Airbridge tracking link as a link in WarpLink via the dashboard or the REST API.
Parameter Mapping
| Airbridge Field | WarpLink Field |
|---|---|
| Deep Link (URL-scheme destination; Airbridge requires a path segment between the scheme and the query string) | ios_url / android_url |
| Google Play destination / iOS App Store destination (fallback when the app is not installed) | android_fallback_url / ios_fallback_url |
| Web URL (Desktop fallback, or fallback when no store destination is set) | destination_url |
Campaign (tracking parameter, becomes campaign=value on the generated link) | utm_campaign |
Channel (groups tracking links; lowercase letters, numbers, and . - _ only) | tags |
| Image / Title / Description (social preview) | og_image_url / og_title / og_description |
| Short Link ID (only available once a custom domain is added) | slug |
| Custom Parameter (key/value catch-all) | Encoded as query parameters on destination_url, echoed back as custom_params on resolve |
Airbridge auto-appends UTM parameters to the Web URL destination when none are supplied on the link; WarpLink does not do this automatically, so carry over any UTM values you want preserved. Also reformat any deep link scheme that omits a path segment (yourscheme://?type=blog) to include one (yourscheme://blog?type=blog) before recreating it: Airbridge's own docs note that some ad platforms, Instagram specifically, do not process a schemeless-path deep link, and the requirement carries over regardless of provider.
Create via API
curl -X POST https://api.warplink.app/v1/links \
-H "Authorization: Bearer wl_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"destination_url": "https://yourapp.com/product/123",
"ios_url": "myapp://product/123",
"android_url": "myapp://product/123",
"ios_fallback_url": "https://apps.apple.com/app/id123456789",
"android_fallback_url": "https://play.google.com/store/apps/details?id=com.example.myapp",
"utm_campaign": "spring_sale"
}'
3. Swap the SDK
Remove Airbridge:
- Remove the
airbridge-ios-sdkCocoaPods pod, or the SPM package fromhttps://github.com/ab180/airbridge-ios-sdk-deployment(productAirbridge) - Remove
AirbridgeOptionBuilder(name:token:)and theAirbridge.initializeSDK(option:)call - Remove the deep link forwarding calls that exist solely to reach Airbridge:
Airbridge.trackDeeplink(url:)/Airbridge.handleDeeplink(url:onSuccess:)inapplication(_:open:options:), andAirbridge.trackDeeplink(userActivity:)/Airbridge.handleDeeplink(userActivity:onSuccess:)inapplication(_:continue:restorationHandler:) - Remove the
Airbridge.handleDeferredDeeplink(onSuccess:)call
Add WarpLink:
// Package.swift
dependencies: [
.package(url: "https://github.com/WarpLinkApp/warplink-ios-sdk", from: "1.1.0")
]Remove Airbridge:
// Remove from build.gradle
// implementation "io.airbridge:sdk-android:$LATEST_VERSION"
// implementation "io.airbridge:sdk-android-restricted:$LATEST_VERSION"Also remove the AirbridgeOptionBuilder(name, token).build() / Airbridge.initializeSDK(context, option) call from your Application class, the Airbridge.handleDeeplink(intent, onSuccess, onFailure) and Airbridge.handleDeferredDeeplink { uri -> ... } calls from your Activity, and the App Links intent filter targeting your abr.ge (or custom domain) host.
Add WarpLink:
dependencies {
implementation("app.warplink:sdk:1.1.0")
}Remove Airbridge:
npm uninstall airbridge-react-native-sdk
cd ios && pod installAdd WarpLink:
npm install @warplink/react-nativeThe iOS SDK is distributed through Swift Package Manager and needs dynamic linkage, so add this to ios/Podfile inside your app target before installing pods:
# ios/Podfile, inside your app target
use_frameworks! :linkage => :dynamiccd ios && pod install4. Update SDK Initialization
Mobile apps authenticate with an SDK key, created in the dashboard under API Keys > SDK key. An API key looks identical but cannot record installs, so pasting one here leaves deep links working while attribution silently fails.
Before (Airbridge):
import Airbridge
let option = AirbridgeOptionBuilder(name: "YOUR_APP_NAME", token: "YOUR_APP_SDK_TOKEN").build()
Airbridge.initializeSDK(option: option)After (WarpLink):
import WarpLink
WarpLink.configure(
apiKey: "wl_live_yoursdkkeyhere000000000000000000",
options: WarpLinkOptions(onLink: { result in
if case .success(let link) = result, let link {
navigate(to: link) // taps AND deferred installs (check link.isDeferred)
}
})
)Before (Airbridge):
import co.ab180.airbridge.Airbridge
import co.ab180.airbridge.AirbridgeOptionBuilder
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
val option = AirbridgeOptionBuilder("YOUR_APP_NAME", "YOUR_APP_SDK_TOKEN").build()
Airbridge.initializeSDK(this, option)
}
}After (WarpLink):
import app.warplink.WarpLink
import app.warplink.WarpLinkOptions
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
WarpLink.configure(
context = this,
apiKey = "wl_live_yoursdkkeyhere000000000000000000",
options = WarpLinkOptions(onLink = { result ->
result.onSuccess { link -> navigateTo(link) }
})
)
}
}Before (Airbridge):
import { Airbridge } from 'airbridge-react-native-sdk';
Airbridge.setOnDeeplinkReceived((url) => {
// handle url
});After (WarpLink):
import { WarpLink } from '@warplink/react-native';
WarpLink.configure({
apiKey: 'wl_live_yoursdkkeyhere000000000000000000',
onLink: ({ deepLink }) => deepLink && navigateTo(deepLink.destination),
});5. Update Domain Configuration
In Signing & Capabilities > Associated Domains:
- applinks:YOUR_APP_NAME.abr.ge
+ applinks:aplnk.toIn AndroidManifest.xml, update the intent filter host. Airbridge's own docs warn to keep separate <intent-filter> tags per host rather than combining multiple <data> entries in one filter:
<data
android:scheme="https"
- android:host="YOUR_APP_NAME.abr.ge" />
+ android:host="aplnk.to" />abr.ge is Airbridge-owned, so a link built on it cannot move with you: any abr.ge link must be reissued on a new domain. A custom domain is different. Airbridge requires you to own the domain yourself and set it up as a CNAME record at your own DNS provider, pointed at a Name/Value pair Airbridge supplies, so once your links exist on WarpLink you can repoint that same CNAME to WarpLink without needing Airbridge's permission or losing the domain. Airbridge does not document what happens to a cancelled account's CNAME target, so treat this as an active, deliberate DNS cutover rather than something to rely on continuing to resolve on its own. Airbridge accounts are limited to 2 custom domains, and reassigning the account's Display Domain retroactively rewrites the domain on every existing Airbridge tracking link, not just new ones, so account for that if your team is still actively managing domains on Airbridge during the transition.
Moving to a custom domain? Declare it to the SDK too: linkDomains at configure(), or the WarpLinkDomains plist key / app.warplink.DOMAINS manifest entry. See Use it in your app.
6. Migrate Deep Link Handling
The onLink callback set in step 4 already receives resolved links for cold start, warm start, and deferred installs.
Delete the Airbridge.trackDeeplink(url:) / Airbridge.handleDeeplink(url:onSuccess:) pair from application(_:open:options:), and the Airbridge.trackDeeplink(userActivity:) / Airbridge.handleDeeplink(userActivity:onSuccess:) pair from application(_:continue:restorationHandler:). Forward the same URL or activity to WarpLink instead:
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
WarpLink.open(url) // was Airbridge.trackDeeplink(url:) + handleDeeplink(url:onSuccess:)
return true
}
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
WarpLink.continue(userActivity) // was Airbridge.trackDeeplink(userActivity:) + handleDeeplink(userActivity:onSuccess:)
return true
}Resolved links arrive in your onLink callback. Or set your delegate class to the drop-in WarpLinkAppDelegate / WarpLinkSceneDelegate and skip writing these methods yourself.
Delete the Airbridge.handleDeeplink(intent, onSuccess, onFailure) call from your Activity's onResume() or onCreate(). Cold start is automatic once onLink is set at configure(). For warm start, forward new intents and keep android:launchMode="singleTask" on the Activity:
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
WarpLink.onNewIntent(intent) // was Airbridge.handleDeeplink(intent, ...)
}Resolved links arrive in your onLink callback.
Delete the Airbridge.setOnDeeplinkReceived((url) => { ... }) callback. WarpLink.configure()'s onLink callback covers cold start, warm start, and deferred installs in one callback, the same way that single Airbridge callback did.
On iOS you are removing the Airbridge calls from a delegate method that already exists and already forwards to your linking library. Swap them for the WarpLink call and leave the rest of the method alone. Do not let handleIncomingURL decide the return value: it returns nothing, and replacing the forwarded result breaks React Navigation, Expo Linking, and OAuth callbacks.
// ios/YourApp/AppDelegate.swift
import React
import warplink_react_native
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
if userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL {
WarpLinkModule.handleIncomingURL(url) // was AirbridgeReactNative.trackDeeplink(userActivity:)
}
return RCTLinkingManager.application(
application, continue: userActivity, restorationHandler: restorationHandler)
}Android needs no host code, given android:launchMode="singleTask". See the React Native SDK guide for the Objective-C form and Expo prebuild, and the iOS SceneDelegate hook if your app has a SceneDelegate (Info.plist declares UIApplicationSceneManifest): iOS stops calling the AppDelegate method above once a scene exists.
7. Migrate Deferred Deep Links
WarpLink runs the deferred deep link check automatically from configure(). The match arrives in the same onLink callback, flagged with isDeferred. There is no separate deferred call to port.
On iOS, Airbridge delivers a deferred match through Airbridge.handleDeferredDeeplink(onSuccess:), a distinct call from the direct-tap handling in step 6. On Android, it is the separate Airbridge.handleDeferredDeeplink { uri -> ... } call. In React Native, Airbridge does not distinguish the two at all: the same Airbridge.setOnDeeplinkReceived((url) => { ... }) callback you deleted in step 6 already carried deferred matches too. Delete whichever of these calls remain in your code; WarpLink's onLink replaces all of them.
Handle the deferred case inside your onLink callback:
options: WarpLinkOptions(onLink: { result in
guard case .success(let deepLink) = result, let deepLink else { return }
if deepLink.isDeferred {
print("Match confidence: \(deepLink.matchConfidence ?? 0)")
}
navigate(to: deepLink)
})Handle the deferred case inside your onLink callback:
options = WarpLinkOptions(onLink = { result ->
result.onSuccess { deepLink ->
if (deepLink.isDeferred) {
Log.d("MyApp", "Match confidence: ${deepLink.matchConfidence}")
}
navigateTo(deepLink)
}
})Handle the deferred case inside your onLink callback:
WarpLink.configure({
apiKey: 'wl_live_yoursdkkeyhere000000000000000000',
onLink: ({ deepLink }) => {
if (!deepLink) return;
if (deepLink.isDeferred) console.log('Match confidence:', deepLink.matchConfidence);
navigateTo(deepLink.destination);
},
});To run the check manually instead, set the deferred opt-out flag and call checkDeferredDeepLink() yourself (see the deferred deep link guides for iOS, Android, and React Native).
8. Attribution and Reporting
WarpLink attributes installs to the link that drove them through a match cascade: a referrer signal (Play Install Referrer) on Android, a device ID (IDFV) on iOS, and an enriched fingerprint as a probabilistic fallback on both platforms, with a confidence score on every result. See the iOS attribution guide (or the Android and React Native equivalents) for match types, confidence bands, and privacy details.
WarpLink does not replace Airbridge as a mobile measurement partner for paid ad campaigns. Airbridge receives SKAdNetwork attribution results from publishers and exposes a conversion-value configuration API for ad networks, and on its higher tiers adds ML-based fraud detection (click injection, click flooding, SDK spoofing), 330+ ad network integrations, multi-touch attribution reports, and custom event tracking. If Airbridge also serves as your measurement partner for paid campaigns or fraud filtering, keep that integration in place alongside WarpLink.
If you run Airbridge and WarpLink side by side during the transition, avoid registering both SDKs for the same URL scheme or Associated Domains entry. Running two attribution SDKs against the same domain risks double-counting installs or conflicting deep link handling; stagger the cutover by app version rather than leaving both SDKs live indefinitely.
Airbridge does not publish guidance for running its SDK alongside another provider during a migration off Airbridge. A couple of gotchas worth testing for during a dual-SDK window: any deep link scheme that reaches Airbridge without a path segment can already fail silently on platforms like Instagram, so check that behavior before assuming a broken link is a migration bug rather than a pre-existing one; and if your account still has two custom domains registered on Airbridge, changing the assigned Display Domain mid-migration rewrites every existing tracking link to the new domain, which can look like a WarpLink cutover problem when it is actually an Airbridge-side change.
Testing Checklist
After migration, verify on each platform:
- SDK initializes: enable debug logging and check console output
- Deep links open the app: tap a WarpLink URL on a physical device
- Deep link data resolves: destination and custom parameters are correct
- Deferred deep links work: click link, install, verify match. An uninstall is enough to retest on either platform, because the completion marker goes with the app. That second install is reported as a reinstall and still counts as an install
- AASA/assetlinks verified:
curl https://aplnk.to/.well-known/apple-app-site-association - Error handling: test invalid URLs, expired links, no connectivity
- SKAdNetwork ownership is unambiguous if Airbridge is still installed during testing
- All Airbridge code removed: no remaining imports or dependencies
- Clean build: no compilation errors
Next Steps
- General migration guide: the provider-agnostic playbook for planning, domains, cutover, and decommissioning.
- Quickstart: create your first link and get an SDK key.
- iOS SDK, Android SDK, and React Native SDK: full setup and API reference.