Adjust
This guide describes how to add and configure Adjust integration.
Adjust is the industry leader in mobile measurement and fraud prevention.
How does Integration Work?
This integration works in two ways.
1. Receive Attribution Data from Adjust
Once you successfully configured Adjust integration, Apphud will receive attribution data from it. You can view this data on the user's page:
2. Send Subscription Events to Adjust
Apphud can also send all subscription events to Adjust. So you could view these events in Adjust dashboard and Adjust could pass this data to their partners. This will help to measure the efficiency of your ad campaigns.
How to Add Integration?
Step 1 - Install the SDKs
- Install Apphud SDK.
- Integrate Adjust SDK.
- Pass attribution data to Apphud (required). See below.
- Collect Device Identifiers (required). See below.
- Request IDFA consent (required, iOS 14.5+). See below.
Step 2 - Preparations in Adjust
Authentication
Open Adjust and sign in. Copy App token.
Select your app and click here:
Copy App token:
If Adjust also issues an S2S token for your account, copy it so it can be pasted later on into the corresponding field in Apphud.
Define events in Adjust
As a preparation, you need to configure the desired events and their tokens in Adjust first. Adjust requires a unique Event token per event. For example, "trial_started", "trial_converted", "subscription_renewed" etc. You can view the list of all available events here.
You can create event tokens only for events that you need, there is no need to add all events.
In Adjust open app's "All Settings", go to the "Events" section and create necessary events. For each event, Adjust will generate a unique Event token.
As a result, you will have something like this:
Step 3 - Authentication
At Apphud go to Connections → Integrations section. Find Adjust on All or Attribution tabs.
Click Add connection and choose an appropriate source.
Paste the previously copied tokens:
- Adjust App token
- Adjust S2S token (optional)
Step 4 - Additional Settings
Environment and Revenue
Configure generic Environment and Revenue settings as described on Integrations overview → Configuration tab.
Set up filters (optional)
Navigate to Filters tab. Set up filters if needed as described on Integrations overview → Filters tab.
Step 5 - Set up events list
Open the Events tab of the configuration. For each Apphud event you want to forward, paste the corresponding Adjust Event token from Step 2 into the Partner event name field and toggle Enabled on.
Step 6 - Test connection (optional)
Save the connection.
After the configuration is saved, You may send test event to Adjust to check if integration is set up correctly before enabling it to react to all events. Check general guide here.
To test Adjust integration from scratch for iOS source you should do the following:
- Reset IDFA (Settings > Privacy > Advertising > Reset Advertising Identifier).
- Uninstall the app.
- Make sure you initialized Adjust SDK with the
ADJEnvironmentSandboxenvironment. Don't forget to change back toADJEnvironmentProductionbefore release! - Make sure
adjustAttributionChanged(_ attribution: ADJAttribution?)delegate method is called. - If the Adjust Attribution Data block exists in your user's page in Apphud, then integration is successful.
- When viewing events in Adjust Dashboard, make sure you enabled Sandbox Mode in the filter pane.
Step 7 - Enable and save
Once you confirmed the connection works — Enable integration and Save.
Pass Attribution Data to Apphud (required)
Send attribution data to Apphud (or at least Adjust ID):
// only for Apphud SDK v.3.5.7+
// set delegate
adjustConfig?.delegate = self
...
func adjustAttributionChanged(_ attribution: ADJAttribution?) {
Task {
if var data = attribution?.dictionary() {
let adid: String? = await Adjust.adid()
Apphud.setAttribution(data: ApphudAttributionData(rawData: data), from: .adjust, identifer:adid) { (result) in }
}
}
}
func adjustSessionTrackingSucceeded(_ sessionSuccessResponseData: ADJSessionSuccess?) {
Task {
if var data = await Adjust.attribution()?.dictionary() {
let adid: String? = await Adjust.adid()
Apphud.setAttribution(data: data, from: .adjust, identifer:adid) { (result) in }
}
}
}// set delegate
adjustConfig?.delegate = self
...
func adjustAttributionChanged(_ attribution: ADJAttribution?) {
if let data = attribution?.dictionary() {
Apphud.addAttribution(data: data, from: .adjust) { (result) in }
} else if let adid = Adjust.adid() {
Apphud.addAttribution(data: ["adid" : adid], from: .adjust) { (result) in }
}
}
func adjustSessionTrackingSucceeded(_ sessionSuccessResponseData: ADJSessionSuccess?) {
if let data = Adjust.attribution()?.dictionary() {
Apphud.addAttribution(data: data, from: .adjust) { (result) in }
} else if let adid = Adjust.adid() {
Apphud.addAttribution(data: ["adid" : adid], from: .adjust) { (result) in }
}
}// set delegate to ADJConfig
config.delegate = self;
...
- (void)adjustAttributionChanged:(ADJAttribution *)attribution {
[self sendAdjustAttribution:attribution];
}
- (void)adjustSessionTrackingSucceeded:(ADJSessionSuccess *)sessionSuccessResponseData {
[self sendAdjustAttribution:Adjust.attribution];
}
- (void)sendAdjustAttribution:(ADJAttribution*)attribution {
if (attribution != nil && attribution.adid != nil) {
[Apphud addAttributionWithData:attribution.dictionary from:ApphudAttributionProviderAdjust identifer:nil callback:^(BOOL result) {
}];
} else if (Adjust.adid != nil) {
[Apphud addAttributionWithData:@{@"adid" : Adjust.adid} from:ApphudAttributionProviderAdjust identifer:nil callback:^(BOOL result) {
}];
}
}void _initAdjust() {
final config = AdjustConfig('YourAppToken', AdjustEnvironment.production);
config.attributionCallback = (adjustData) async {
final apphudData = <String, dynamic>{};
if (adjustData.trackerToken != null) {
apphudData['trackerToken'] = adjustData.trackerToken!;
}
if (adjustData.trackerName != null) {
apphudData['trackerName'] = adjustData.trackerName!;
}
if (adjustData.network != null) {
apphudData['network'] = adjustData.network!;
}
if (adjustData.adgroup != null) {
apphudData['adgroup'] = adjustData.adgroup!;
}
if (adjustData.creative != null) {
apphudData['creative'] = adjustData.creative!;
}
if (adjustData.clickLabel != null) {
apphudData['clickLabel'] = adjustData.clickLabel!;
}
if (adjustData.adid != null) {
apphudData['adid'] = adjustData.adid!;
}
if (adjustData.fbInstallReferrer != null) {
apphudData['fbInstallReferrer'] = adjustData.fbInstallReferrer!;
}
await Apphud.addAttribution(
data: apphudData,
provider: ApphudAttributionProvider.adjust,
);
};
Adjust.start(config);
}fun setupAdjust(context: Context) {
val env = AdjustConfig.ENVIRONMENT_PRODUCTION
val config = AdjustConfig(context, "YOUR_ADJUST_TOKEN", env)
config.setOnAttributionChangedListener {
Adjust.getAdid { adid ->
Apphud.addAttribution(ApphudAttributionProvider.adjust, it.convertToMap(adid), adid)
}
}
config.setOnSessionTrackingSucceededListener {
Apphud.addAttribution(ApphudAttributionProvider.adjust, null, it.adid)
}
Adjust.initSdk(config)
}
fun AdjustAttribution.convertToMap(adid: String) = mapOf<String, Any>(
"trackerToken" to trackerToken,
"trackerName" to trackerName,
"network" to network,
"campaign" to campaign,
"adgroup" to adgroup,
"creative" to creative,
"clickLabel" to clickLabel,
"adid" to adid
)Adjust.GetAttribution( attribution =>
{
Adjust.GetAdid( adid =>
{
var dict = new Dictionary<string, object>
{
{ "trackerToken", attribution.trackerToken },
{ "trackerName", attribution.trackerName },
{ "network", attribution.network },
{ "campaign", attribution.campaign },
{ "adgroup", attribution.adgroup },
{ "creative", attribution.creative },
{ "clickLabel", attribution.clickLabel },
};
ApphudSDK.AddAttribution(ApphudAttributionProvider.adjust, dict, adid);
});
});// Step 1: Create AdjustConfig instance
const adjustConfig = new AdjustConfig(
'{YourAppToken}', // Replace with your actual app token
AdjustConfig.EnvironmentProduction // Change to AdjustConfig.EnvironmentSandbox for testing
);
// Step 2: Assign the attribution callback on the AdjustConfig instance
adjustConfig.setAttributionCallback(function (attribution) {
console.log("Adjust Attribution Data:", attribution);
// Fetch ADID separately
Adjust.getAdid(function (adid) {
if (!adid) {
console.log("No ADID found, skipping Apphud attribution submission.");
return; // Do not call ApphudSdk.addAttribution if ADID is missing
}
console.log("ADID for attribution:", adid);
// Map Adjust attribution object to a simple hash and include ADID
const attributionData = {
trackerName: attribution.trackerName,
network: attribution.network,
campaign: attribution.campaign,
adgroup: attribution.adgroup,
creative: attribution.creative,
clickLabel: attribution.clickLabel,
adid: adid
};
// Send Adjust attribution data to Apphud
ApphudSdk.addAttribution({
data: attributionData,
identifier: adid,
attributionProviderId: ApphudAttributionProvider.Adjust
});
});
});
// Step 3: Initialize the Adjust SDK with the configured AdjustConfig instance
Adjust.initSdk(adjustConfig);
❗️ Important NoteIn order to receive Adjust attribution data from Facebook (Meta), you should accept Facebook's "Advanced Mobile Measurement Agreement" using this link.
Collect Device Identifiers (required)
iOS: Call setDeviceIdentifiers(idfa: String?, idfv: String?) method immediately after the SDK initialization. If the advertising identifier (IDFA) is not available, pass only the IDFV.
When IDFA becomes available, you can call setDeviceIdentifiers(idfa: String?, idfv: String?) again.
Android: Call Apphud.collectDeviceIdentifiers() method after the SDK initialization.
When targeting Android 13 and above, you must also declare AD_ID permission in the manifest file.
For more details, refer to Device Identifiers guide.
Request IDFA Consent (required)
Starting iOS 14.5 access to IDFA requires user consent. You should request IDFA manually using AppTrackingTransparency framework and pass it to Apphud. Read more here.
Events Cheat Sheet
This is a list of all possible events and their parameters that can be sent to Adjust.
NoteYou can read more about subscription events here and parameters here.
Trial
Trial period started parameters
partner_params.product_id: String
Successful conversion from trial period to regular subscription parameters
partner_params.product_id: Stringrevenue: Floatcurrency: String
Failed conversion from trial period to regular subscription parameters
partner_params.product_id: Stringpartner_params.reason: String
Cancellations
Trial Canceled parameters
partner_params.product_id: String
Subscription Canceled parameters
partner_params.product_id: String
Autorenew disabled parameters (Deprecated)
partner_params.product_id: String
Autorenew enabled parameters
partner_params.product_id: String
Introductory Offer
Introductory offer started parameters
partner_params.product_id: Stringpartner_params.offer_type: Stringrevenue: Floatcurrency: String
Introductory offer renewed parameters
partner_params.product_id: Stringpartner_params.offer_type: Stringrevenue: Floatcurrency: String
Successful conversion from introductory offer to regular subscription parameters
partner_params.product_id: Stringpartner_params.offer_type: Stringrevenue: Floatcurrency: String
Failed conversion from introductory offer to regular subscription or failed renewal parameters
partner_params.product_id: Stringpartner_params.reason: Stringpartner_params.offer_type: String
Refund during introductory offer parameters
partner_params.product_id: Stringpartner_params.offer_type: Stringpartner_params.reason: String
Regular
Subscription started parameters
partner_params.product_id: Stringrevenue: Floatcurrency: String
Subscription renewed parameters
partner_params.product_id: Stringrevenue: Floatcurrency: String
Subscription expired parameters
partner_params.product_id: Stringpartner_params.reason: String
Subscription refunded parameters
partner_params.product_id: Stringpartner_params.reason: String
Note - Refund Events and Revenue in AdjustWe don't send revenue properties with refund events because Adjust does not support negative revenues.
According to Adjust S2S API documentation, the revenue parameter only accepts positive numbers (minimum 0.001).
Promo Offer
Promotional offer started parameters
partner_params.product_id: Stringpartner_params.offer_id: Stringpartner_params.offer_type: Stringrevenue: Floatcurrency: String
Promotional offer renewed parameters
partner_params.product_id: Stringpartner_params.offer_id: Stringpartner_params.offer_type: Stringrevenue: Floatcurrency: String
Successful conversion from promotional offer to regular subscription parameters
partner_params.product_id: Stringpartner_params.offer_id: Stringpartner_params.offer_type: Stringrevenue: Floatcurrency: String
Failed conversion from promotional offer to regular subscription or failed renewal parameters
partner_params.product_id: Stringpartner_params.offer_id: Stringpartner_params.offer_type: Stringpartner_params.reason: String
Refund during promotional offer parameters
partner_params.product_id: Stringpartner_params.offer_id: Stringpartner_params.offer_type: Stringpartner_params.reason: String
Other Events
Non-renewing purchase parameters
partner_params.product_id: Stringrevenue: Floatcurrency: String
Non-renewing purchase refunded parameters
partner_params.product_id: Stringpartner_params.reason: String
Billing issue parameters
partner_params.product_id: String
Billing issue resolved parameters
partner_params.product_id: String
NoteFor each event, Apphud includes the
environmentparameter depending on the environment of the subscription.
Updated 17 days ago
