AppsFlyer

Record app installs, sessions, and in-app events for attribution and ROI measurement.

The AppsFlyer Native Plugin records app installs, updates, and sessions automatically so you can attribute installs, measure campaign performance, and evaluate user quality. Send custom in-app events through the Median JavaScript Bridge.

The plugin integrates the AppsFlyer SDK in your app and exposes a small JavaScript API for setting a customer user ID, logging custom events, and receiving conversion and deep link data. You configure your app in the AppsFlyer dashboard and in Median App Studio, then use the bridge for custom logic.

🚧

iOS 14.5+ App Tracking Transparency Requirement

Requesting user consent through the App Tracking Transparency (ATT) framework is required for iOS 14.5+. See Apple App Tracking Transparency in the Median docs and AppsFlyer – Enabling ATT support for implementation details.

Why use AppsFlyer?

  • Attribution and ROI: Attribute installs to campaigns and measure return on ad spend.
  • Automatic event tracking: Installs, updates, and sessions are recorded without extra code.
  • Custom in-app events: Log business events (e.g. signup, purchase) via the JavaScript Bridge.
  • Conversion and deep link data: Receive install attribution and deep link payloads in your web app via callbacks.

Key Terms

Dev Key: A unique key per app in the AppsFlyer dashboard. You use the Android and Apple dev keys in Median App Studio to link your Median app to AppsFlyer.

Conversion data: Data returned by AppsFlyer for an install (e.g. first launch, install time, attribution status). The SDK invokes your callback when the app is launched or brought to the foreground (e.g. after a deep link).

af_status: A string in the conversion data object indicating whether the install is Organic or Non-organic. Use it to branch logic (e.g. show different onboarding for paid vs organic users).

Organic vs non-organic: Organic = install not attributed to a campaign; non-organic = attributed to a marketing source.


Prerequisites

  • A Median.co app with JavaScript Bridge enabled
  • An AppsFlyer account and app(s) created for iOS and Android
  • Apple App ID (from App Store Connect – App Information) or your app’s App Store URL
  • Android package name (from Median App Identifiers) or your app’s Play Store URL
  • For iOS 14.5+: ATT implemented and, if desired, ATT prompt delay configured in the plugin
👍

Developer Demo

Display our demo page in your app to test during development https://median.dev/appsflyer/


When to use this plugin

AppsFlyer is essential for apps that need to:

Use CaseExample
Campaign attributionAttribute installs and re-engagement to paid campaigns (e.g. Facebook, Google)
Install and session trackingMeasure installs, updates, and sessions automatically without extra code
Custom in-app eventsLog signups, purchases, or feature usage for analytics and optimization
Conversion dataKnow whether an install is organic or non-organic and use it in your app logic
Deep link handlingReact to deferred or direct deep links (e.g. open a specific screen from a push or ad)
ROI measurementEvaluate user quality and campaign performance in the AppsFlyer dashboard

What you'll do

  1. Create apps in AppsFlyer: Complete AppsFlyer configuration and obtain dev keys for Android and Apple.
  2. Enable the plugin: Go to Plugin setup and enter Android Dev Key, Apple Dev Key, and Apple App ID (and optional ATT delay).
  3. Use the bridge: Implement median.appsflyer.setCustomerUserId, median.appsflyer.logEvent, and the global conversion / deep link callbacks in JavaScript bridge functions.
  4. Test on devices: Follow Testing Checklist; the SDK is not fully validated in the simulator.

Implementation Guide

AppsFlyer configuration

Before enabling the plugin in Median, create and configure your app in the AppsFlyer dashboard using your Apple App ID and Android package name (see Prerequisites). Add one app for iOS and one for Android; once each is created, you’ll receive a dev key for that platform.

KeyExample valueSource
Apple App ID123456789App Store Connect – App Information
Android package nameco.median.android.dnxqylMedian App Studio – App Identifiers

Once the app is created and added to your dashboard, you will receive a dev key for that platform.

AppsFlyer Dev Key

AppsFlyer - Dev Key

You may need to configure additional options in AppsFlyer (e.g. re-engagement attribution, uninstall measurement). See AppsFlyer App Settings and the AppsFlyer Help Center.


App Studio configuration

Enable the Plugin

  1. Open Native Plugins: In Median App Studio, open your app and go to Native Plugins.
  2. Open AppsFlyer: Select AppsFlyer and go to Settings.
  3. Enter credentials: Set Android Dev Key, Apple Dev Key, and Apple App ID from your AppsFlyer setup. Optionally set the ATT prompt delay (iOS).

Configuration options

SettingDescriptionDefaultRecommended
Android Dev KeyAppsFlyer dev key for your Android appFrom AppsFlyer dashboard
Apple Dev KeyAppsFlyer dev key for your iOS appFrom AppsFlyer dashboard
Apple App IDApple App ID (numeric) for your iOS appFrom App Store Connect
ATT prompt delay (optional)Delay in seconds before showing the ATT prompt on iOSPer your product/legal requirements

Median AppsFlyer Plugin Configuration

Median AppsFlyer Plugin Configuration

📘

Note

The configuration above is a sample for the developer demo. AppsFlyer is highly customizable. For production, we recommend consulting AppsFlyer or your marketing team to tailor settings (attribution, uninstall measurement, etc.) to your needs. See the AppsFlyer Help Center.

After the plugin is configured, use the JavaScript Bridge functions below to set a customer user ID, log custom events, and handle conversion or deep link data via callbacks.


JavaScript Bridge Functions

Associate a User

Associates your own customer user ID with AppsFlyer so you can cross-reference it with AppsFlyer’s device IDs and your backend.

↔️Median JavaScript Bridge

try {
  const { success } = await median.appsflyer.setCustomerUserId("user123");
  console.log(success ? "User ID set successfully" : "Failed to set user ID");
} catch (err) {
  console.error(err.code, err.message);
}

Parameters

ParameterTypeRequiredDescription
idstringYesYour unique customer or user

Log a Custom In-App Event

Logs a custom in-app event with an optional object of values. Use it for signups, purchases, or any business event you want to measure in AppsFlyer.

↔️Median JavaScript Bridge

try {
  const { success } = await median.appsflyer.logEvent("purchase", { value: 99.99, currency: "USD" });
  console.log(success ? "Event logged successfully" : "Failed to log event");
} catch (err) {
  console.error(err.code, err.message);
}

Parameters

ParameterTypeRequiredDescription
eventNamestringYesEvent name (e.g. 'purchase', 'signup')
eventValuesobjectNoKey-value pairs to attach to the event (e.g. { amount: 9.99, currency: 'USD' })

Conversion data and deep link callbacks

The plugin does not expose a single “get conversion data” function. Instead, the app invokes global callback functions you define when conversion or deep link data is available (on app launch or when brought to the foreground, e.g. via a deep link). Data is cached after the first call and will be the same on later invocations.

Legacy conversion (install) data

Define this function so the app can pass conversion data for the install:

↔️Median JavaScript Bridge

function median_appsflyer_cd_success(conversionDataMap) {
  // conversionDataMap.af_status is "Organic" or "Non-organic"
  console.log('Install attribution:', conversionDataMap);
}

New conversion data

function median_appsflyer_cd(data) {
  console.log('Conversion data:', data);
}

UDL (Unified Deep Linking) / deep link result

For deep link payloads (e.g. deeplinkValue, campaign, mediaSource):

function median_appsflyer_deeplink_result(data) {
  console.log('Deep link data:', data);
  if (data.deeplinkValue) {
    // Navigate or handle deep link
  }
}

Sample response – conversion data

{
  "is_first_launch": false,
  "in-stall_time": "2026-02-11 10:32:16.951",
  "af_message": "organic install",
  "af_status": "Organic"
}

Sample response – deep link

{
  "afSub1": "",
  "afSub2": "",
  "afSub3": "",
  "afSub4": "",
  "afSub5": "",
  "campaign": "",
  "campaignId": "",
  "clickEvent": {},
  "clickHTTPReferrer": "",
  "deeplinkValue": "",
  "isDeferred": true,
  "matchType": "",
  "mediaSource": ""
}

Testing Checklist

Use this checklist to confirm AppsFlyer is working in your app:

  • Plugin is enabled and configured in Native Plugins > AppsFlyer > Settings
  • median.appsflyer.setCustomerUserId(id) runs without errors
  • median.appsflyer.logEvent(name, values) runs without errors
  • Conversion callback (median_appsflyer_cd_success or median_appsflyer_cd) is called on launch or when returning to the app
  • Behavior verified on a real Android device (not only simulator)
  • Behavior verified on a real iOS device (not only simulator)
  • On iOS 14.5+, ATT prompt appears when configured and consent affects behavior as expected
  • Android Dev Key, Apple Dev Key, and Apple App ID match the AppsFlyer dashboard
  • Global callback function names match exactly (median_appsflyer_cd_success, median_appsflyer_cd, median_appsflyer_deeplink_result)
  • No JavaScript errors in the console from the plugin or callbacks
  • Callbacks do not block the UI; navigation or UI updates remain responsive

Troubleshooting

Ensure the JavaScript Bridge is enabled in your Median app and that you are calling median.appsflyer after the app and bridge are ready (e.g. after deviceready or when your main app script runs). Confirm the AppsFlyer plugin is enabled under Native Plugins in App Studio.

Conversion data is provided when the app is launched or brought to the foreground. Ensure you define the global function names exactly: median_appsflyer_cd_success (legacy), median_appsflyer_cd (new), or median_appsflyer_deeplink_result (UDL). The SDK may take a moment to return data; avoid removing or redefining these callbacks during the first launch.

Confirm App Tracking Transparency is implemented in your app and that you have configured the ATT prompt (and optional delay) as required. The simulator may not show the system ATT dialog; test on a real device.

Verify Android Dev Key, Apple Dev Key, and Apple App ID in Native Plugins > AppsFlyer > Settings match the app in your AppsFlyer dashboard. Ensure you are testing on a real device; the SDK does not fully work in the simulator. Allow some time for data to appear in the dashboard.

Conversion data is cached after the first callback. For a fresh install, the first launch may have limited data until attribution is resolved. Check AppsFlyer’s documentation on timing and testing.

Confirm your deep link URL scheme and link format are configured correctly in AppsFlyer and that the app is opened via that link (not only from the home screen). Use AppsFlyer’s deep link validator and test on a real device.ent!

📘

Still having trouble?

For SDK-level errors or attribution behavior, refer to AppsFlyer SDK documentation.