Migrate from AppsFlyer OneLink

After this guide, you will have your OneLink links rebuilt on Strait with the same short paths, in-app destinations, fallbacks, previews and campaigns, an app that opens them with the Strait SDK, and a safe plan to stop using OneLink.

  • Task
  • Android
  • iPhone
  • React Native
  • Flutter
  • Capacitor
  • Unity
On this page 8
  1. 1. Export your links from AppsFlyer
  2. 2. Preview the import
  3. 3. Import
  4. 4. Swap the SDK in your app
  5. 5. Switch over, then retire OneLink
  6. Frequently asked questions
  7. Common errors
  8. Next steps
Time
About 15 minutes to import. The whole move is about a day of developer work plus one app release
You need
Your OneLink Custom Links export (CSV), your app's code, a Strait workspace
Works on
Android, iPhone, React Native, Flutter, Capacitor, Unity

Five steps. Each says what to do, what to copy and how you know it worked.

Do this: in AppsFlyer, open Experiences & Deep Linking → OneLink Custom Links, pick the template, and press Export. Don't edit the file. Its columns are the link name, media source, campaign name, short URL and long URL.

onelink-links.csv (shortened)
Link name,Media source,Campaign name,Short URL,Long URL
Summer sale,instagram,summer_26,https://yourapp.onelink.me/AbCd/summer,https://yourapp.onelink.me/AbCd?pid=instagram&c=summer_26&af_dp=yourapp%3A%2F%2Fproduct%2F42&af_web_dp=https%3A%2F%2Fshop.example.com%2Fp%2F42
Promo,email,,https://yourapp.onelink.me/AbCd/promo,https://yourapp.onelink.me/AbCd?pid=email&deep_link_value=product_42&af_web_dp=https%3A%2F%2Fshop.example.com%2F

AppsFlyer's export only includes links made in its dashboard. Links made with the OneLink API, a bulk upload or the SDK aren't in it; create those on Strait with the batch API in step 3.

You should see: one CSV with a row per OneLink link.

2. Preview the import

Do this: open Dashboard → Import → From AppsFlyer. Choose the file and press Preview.

Each row shows the new short path, the screen your app will open, fallbacks, preview and campaign. The settings come from the long URL's parameters:

OneLink Strait
The end of the short URL (yourapp.onelink.me/AbCd/summer → summer), else the link name The short path (slug). Letters, numbers, - and _, up to 64; other characters become -
af_dp (yourapp://product/42) The path your app gets, e.path: /product/42, on your website's address
deep_link_value, deep_link_sub1 … deep_link_sub10 Kept as parameters, e.params.deep_link_value, so app code that reads them keeps working
af_web_dp Its address carries the path; when its page differs, it's where computers go (desktopUrl). A link with only af_web_dp keeps it as the destination
af_ios_url, af_android_url iosFallbackUrl, androidFallbackUrl. Without them, people without the app go to the store, as in OneLink
af_og_title, af_og_description, af_og_image The chat preview: title, description, imageUrl
c, else the campaign name column campaign
pid, else the media source column utm_source on the destination (how Analytics names the channel)

A link with af_dp or deep_link_value but no af_web_dp needs your website's address: type it in Your website and preview again. Rows with a problem say why in plain words, and every parameter we don't use (such as is_retargeting or af_adset) is listed.

You should see: a table of your links. Any row with a problem says what's wrong.

3. Import

Do this: press Import N links.

Running it twice is safe: a short path that already exists is reported, never overwritten. Rows that failed can be downloaded as a CSV, fixed, and imported again with Bulk create (CSV).

For links that aren't in the export, or thousands of them, use the API: POST /v1/links/batch takes up to 500 links per call with your secret key (the server-only key from Dashboard → Settings).

Terminal
curl https://strait.link/v1/links/batch \
  -H "Authorization: Bearer $SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "links": [
      {
        "slug": "summer",
        "longUrl": "https://shop.example.com/product/42?utm_source=instagram",
        "desktopUrl": "https://shop.example.com/p/42",
        "campaign": "summer_26"
      },
      { "slug": "promo", "longUrl": "https://shop.example.com/?deep_link_value=product_42&utm_source=email" }
    ]
  }'

Each item gets its own answer: 201 made, 400 invalid, 402 plan limit reached, 409 short path taken. See the REST API.

You should see: a summary of what was made, and your links in Dashboard → Links at https://<handle>.strait.link/<path>.

4. Swap the SDK in your app

Do this: remove the AppsFlyer deep-linking code and add our SDK (React Native, Flutter, Capacitor, Android, iOS, Unity). Then swap the red lines for the green ones:

Diff
- appsFlyer.onDeepLink((res) => { if (res.deepLinkStatus === 'FOUND') route(res.data.deep_link_value); });
+ links.onLink((e) => { if (e.matched) route(e.path, e.params); });   // e.params.deep_link_value is still there
Diff
- appsFlyer.logEvent('af_purchase', { af_revenue: 49.99, af_currency: 'USD' });
+ links.trackEvent('purchase', { value: 49.99, currency: 'USD' });

Links tapped before an install arrive in the same callback with kind: 'deferred'. Using AppsFlyer for ad attribution? Keep its SDK for that.

Last, point app verification at your new address. Android: set the intent filter's android:host to hilltop.strait.link and add your SHA-256 fingerprints in Apps & stores. iPhone: set Associated Domains to applinks:hilltop.strait.link and add your Team ID and bundle ID in Apps & stores. In a debug build, the SDK's doctor() tells you if anything is missing.

You should see: tapping https://hilltop.strait.link/summer in Messages or Gmail opens your app on the product 42 screen.

Do this: go in this order.

  1. Ship the app update. Keep the AppsFlyer SDK in this release if old OneLink links should still open the app.
  2. Make new links on Strait. Point your backend, marketing tools and share buttons at POST /v1/links (or the Node SDK).
  3. Replace old links wherever you control the text: website, emails, app screens, QR codes you can reprint.
  4. Keep OneLink running while old onelink.me links still get taps. They only work while your AppsFlyer setup does.
  5. Remove the AppsFlyer deep-linking code in a later release, once taps on old links have stopped.

You should see: new taps in Dashboard → Analytics, and old OneLink links getting fewer taps each week.

Frequently asked questions

What doesn't move from AppsFlyer?

Attribution and analytics history stay in AppsFlyer, so export the reports you need first. Also not moved: the onelink.me domain (AppsFlyer owns it), links that aren't in the dashboard export, and parameters that only AppsFlyer reads (is_retargeting, af_adset, af_sub1 and the like; the preview lists them).

Not yet. Custom domains are coming soon. Until then, new links use <handle>.strait.link.

What does Strait cost?

Free up to 25,000 taps a month, no card. App opens are never billed. Paid plans are on Pricing.

Common errors

  • A row says it has an in-app destination but no af_web_dp. Type your website in Your website and preview again.
  • A short path is reported as taken. Another link in your workspace already uses it. Rename it in the file, or keep the existing link.
  • The app opens the website, not the app. The new build with hilltop.strait.link isn't installed, or fingerprints or Team ID are missing in Apps & stores. Run doctor() in a debug build.

Next steps