Rovenue SDKBeta
Guides

Attribution hand-off

Forward AppsFlyer or Adjust attribution to Rovenue with setAttribution so the very first onboarding can be targeted by campaign.

Rovenue reads Apple Search Ads, the Google Play referrer and Meta's install referrer on its own. If you also use AppsFlyer or Adjust, hand their attribution to Rovenue with setAttribution(provider, data) from the MMP's callback. Pass the callback object as it arrives; Rovenue normalises it.

The record is write-once on the server: a call after the install is already attributed changes nothing, so it is safe to call from every callback.

Configure Rovenue before your MMP callbacks can fire: initialise Rovenue first, then AppsFlyer or Adjust. setAttribution before configure throws or does nothing (depending on the platform), and that hand-off is lost.

setAttribution

// AppsFlyer
func onConversionDataSuccess(_ data: [AnyHashable: Any]) {
    guard let dict = data as? [String: Any] else { return }
    Task { try? await Rovenue.shared.setAttribution(provider: .appsflyer, data: dict) }
}

// Adjust v5 (AdjustDelegate): the adid comes from Adjust.adid
func adjustAttributionChanged(_ attribution: ADJAttribution?) {
    guard let base = attribution?.dictionary() as? [String: Any] else { return }
    Adjust.adid { adid in
        var dict = base
        if let adid { dict["adid"] = adid }
        Task { try? await Rovenue.shared.setAttribution(provider: .adjust, data: dict) }
    }
}

setAttribution(provider:data:) is async throws and throws only .invalidArgument (the data cannot be serialised to JSON). Network and server failures are logged, not thrown.

// AppsFlyer
override fun onConversionDataSuccess(data: MutableMap<String, Any>) {
    Rovenue.shared.setAttribution(AttributionProvider.APPSFLYER, data)
}

// Adjust (v5, inside the attribution callback): the adid comes from getAdid
Adjust.getAdid { adid ->
    Rovenue.shared.setAttribution(
        AttributionProvider.ADJUST,
        mapOf(
            "network" to attribution.network,
            "campaign" to attribution.campaign,
            "adgroup" to attribution.adgroup,
            "creative" to attribution.creative,
            "adid" to adid,
        ),
    )
}

Kotlin's setAttribution is fire-and-forget and never throws: the provider is a typed enum and the data a Map, so there is no invalid-argument path. Failures are logged.

import appsFlyer from 'react-native-appsflyer';
import { Adjust } from 'react-native-adjust';
import { Rovenue } from '@rovenue/react-native-sdk';

// AppsFlyer
appsFlyer.onInstallConversionData((res) => {
  Rovenue.setAttribution('appsflyer', res.data);
});

// Adjust (attribution callback)
Adjust.addAttributionChangedListener((attribution) => {
  Adjust.getAdid((adid) => {
    Rovenue.setAttribution('adjust', { ...attribution, adid });
  });
});

Returns a promise (void); it rejects only with InvalidArgument (unknown provider, or data that cannot be serialised).

import 'package:adjust_sdk/adjust.dart';
import 'package:adjust_sdk/adjust_config.dart';
import 'package:rovenue_flutter/rovenue_flutter.dart';

// AppsFlyer
appsflyerSdk.onInstallConversionData((res) {
  Rovenue.instance.setAttribution(
    AttributionProvider.appsflyer,
    Map<String, Object?>.from(res['payload'] as Map),
  );
});

// Adjust (Adjust SDK v5): the attribution callback is set on the config
final config = AdjustConfig('{YourAppToken}', AdjustEnvironment.production);
config.attributionCallback = (attribution) async {
  final adid = await Adjust.getAdid();
  Rovenue.instance.setAttribution(AttributionProvider.adjust, {
    'network': attribution.network,
    'campaign': attribution.campaign,
    'adgroup': attribution.adgroup,
    'creative': attribution.creative,
    'adid': adid,
  });
};
Adjust.initSdk(config);

Returns Future<void>; it throws a RovenueException only with RovenueErrorKind.invalidArgument.

Swift, React Native and Flutter reject only on an invalid argument; Kotlin has no such path and never throws. Network and server failures are logged on all four.

The MMP listener snippets are illustrative; check the callback names against your MMP SDK version. Adjust's attribution object carries network, campaign, adgroup and creative, which is what Rovenue reads. Add Adjust's adid to the data as well (Adjust SDK v5 returns it from Adjust.getAdid, not on the attribution object): Rovenue mirrors it onto the subscriber as $adjustId, so the server-to-server backup can match the install.

Configure options

OptionPlatformsMeaning
awaitMmpAttributionSwift, Kotlin, React Native, FlutterHold the first placement request after install until setAttribution is called. Default false.
facebookAppIdAndroid onlyFacebook App ID used to read Meta's install referrer. If omitted, the manifest com.facebook.sdk.ApplicationId meta-data is used.

With awaitMmpAttribution on, the first placement after install waits at most 3 seconds for the hand-off, then resolves with whatever is known. Later launches never wait, and an install that upgrades from SDK 0.19 or earlier is not treated as a first launch.

Set the MMP's customer user id to the Rovenue id so the server-to-server backup can match the install to the same subscriber. See AppsFlyer and Adjust server-to-server.

See Acquisition targeting for the Campaigns page that consumes this data.

On this page