Adjust
Integrate Purchases SDK with Adjust for precise revenue tracking
With our Adjust integration you can:
- Accurately track subscriptions generated from Adjust campaigns, allowing you to know precisely how much revenue your campaigns generate.
- Send trial conversions and renewals directly from RevenueCat to Adjust, allowing for tracking without an app open.
- Continue to follow your cohorts for months to know the long tail revenue generated by your campaigns.
Integration at a glance
| Revenue support | Supports Negative Revenue | Sends Sandbox Events | Includes Customer Attributes | Sends Transfer Events | Optional Event Types |
|---|---|---|---|---|---|
| ✅ | ❌ | ✅ | ❌ | ❌ | See Event types |
For a cross-provider view of identifiers, revenue support, sandbox behavior, and attribution responsibilities, see the attribution provider comparison.
Before you begin
Review Getting Started with Attribution Integrations for how attribution integrations fit together, then use the setup checklist as a reference for required lifecycle events, reporting choices, duplicate-event risks, and testing checks.
The following considerations are specific to Adjust:
- Adjust uses event tokens, not readable event names. Configure the required tokens for each platform you want RevenueCat to send events from.
- If your app shows a paywall very early, a customer can purchase before
$adjustIdhas synced to RevenueCat. Keep the callback or delegate path in your implementation socollectDeviceIdentifiers()andsetAdjustID()run again when Adjust attribution data becomes available. - Turn off Adjust SDK purchase or revenue tracking for the same events RevenueCat sends, unless you intentionally manage deduplication in Adjust.
- Adjust doesn't accept revenue values below
0.001, including negative values. Free trial events and refunds are sent without revenue. - If you enabled S2S authentication in Adjust, add the matching OAuth token to the RevenueCat Adjust settings.
- iOS
- Android
- None
- Adjust SDK v5 removed
adidfromADJAttributionon iOS. Fetch the ADID from the Adjust SDK, then pass it tosetAdjustID(). RevenueCat stores the value as$adjustId.
- Adjust SDK v5 removed
adidfromAdjustAttributionon Android. Fetch the ADID from the Adjust SDK, then pass it tosetAdjustID(). RevenueCat stores the value as$adjustId.
1. Install Adjust SDK
Before RevenueCat can integrate with Adjust, your app should be running the latest Adjust SDK. Refer to the Adjust developer documentation for the latest installation instructions.
2. Send attribution data to RevenueCat
Adjust matches RevenueCat events to campaigns using device-specific attribution data. RevenueCat will only send events into Adjust when the required Customer Attributes below are set for the device. Recommended attributes improve attribution matching quality.
| Key | Description | Required |
|---|---|---|
$adjustId | Adjust ID. The unique Adjust identifier for the user | ✅ |
$idfa | iOS advertising identifier UUID | ⚠️ (recommended) |
$gpsAdId | Google advertising identifier | ⚠️ (recommended) |
$idfv | iOS vendor identifier UUID | ⚠️ (recommended) |
$ip | The IP address of the device | ⚠️ (recommended) |
These properties can be set manually, like any other Customer Attributes, or through the helper methods collectDeviceIdentifiers() and setAdjustID(). Set them after the RevenueCat SDK is configured and before the first purchase occurs whenever possible.
The examples below show the recommended app-side flow:
- Configure the RevenueCat SDK.
- Collect device identifiers.
- Pass the Adjust ID to
setAdjustID()if it's available. - Keep the callback path in place so your app can collect identifiers again when a previously unavailable value becomes available, such as after ATT permission is granted or the Adjust SDK returns the ADID.
- iOS
- Android
- None
- If you request App Tracking Transparency permission to access the IDFA,
call
collectDeviceIdentifiers()again after the customer accepts permission to update the$idfaattribute in RevenueCat. - The AdSupport framework is required to access the IDFA parameter. In
Xcode, add
AdSupport.frameworkto your app target under Frameworks, Libraries, and Embedded Content, leave it set to Do Not Embed, then importAdSupportin your Swift file.
- RevenueCat's current Android SDKs don't collect Android ID. Google's
Advertising ID (
$gpsAdId) acts as the primary Android device identifier in RevenueCat and when connecting with third-party integrations.
- Swift
- Java
import AdjustSdk // Provides Adjust, ADJConfig, and AdjustDelegate
import RevenueCat
import AdSupport // Required for IDFA collection
import UIKit
class AppDelegate: UIResponder, UIApplicationDelegate {
private let adjustDelegate = AdjustAttributionDelegate()
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
Purchases.configure(withAPIKey: "public_sdk_key")
let config = ADJConfig(
appToken: "adjust_app_token",
environment: ADJEnvironmentProduction
)!
config.delegate = adjustDelegate
Adjust.initSdk(config)
// Automatically collect the $idfa, $idfv, and $ip values
Purchases.shared.attribution.collectDeviceIdentifiers()
// Set the Adjust ID on app launch if it exists
setAdjustIdIfAvailable()
return true
}
}
private func setAdjustIdIfAvailable() {
Adjust.adid { adjustId in
if let adjustId = adjustId {
Purchases.shared.attribution.setAdjustID(adjustId)
}
}
}
// IMPORTANT: Set the Adjust ID when it becomes available, if it
// didn't exist on app launch
private final class AdjustAttributionDelegate: NSObject, AdjustDelegate {
func adjustAttributionChanged(_ attribution: ADJAttribution?) {
Purchases.shared.attribution.collectDeviceIdentifiers()
setAdjustIdIfAvailable()
}
}
Purchases.configure(this, "my_api_key");
// Automatically collect the $gpsAdId and $ip values
Purchases.getSharedInstance().collectDeviceIdentifiers();
// Set the Adjust ID on app launch if it exists
setAdjustIdIfAvailable();
// IMPORTANT: Set the Adjust ID when it becomes available, if it
// didn't exist on app launch
config.setOnAttributionChangedListener(new OnAttributionChangedListener() {
@Override
public void onAttributionChanged(AdjustAttribution attribution) {
Purchases.getSharedInstance().collectDeviceIdentifiers();
setAdjustIdIfAvailable();
}
});
private void setAdjustIdIfAvailable() {
Adjust.getAdid(new OnAdidReadListener() {
@Override
public void onAdidRead(String adjustId) {
if (adjustId != null) {
Purchases.getSharedInstance().setAdjustID(adjustId);
}
}
});
}
RevenueCat only creates an Adjust delivery attempt when $adjustId is present on the event. If RevenueCat already processed a purchase without the identifier, setting it later doesn't repair that past event.
(Optional) Send campaign data to RevenueCat
RevenueCat isn't an attribution network and can't determine which ad drove an install or conversion. If Adjust or another source gives your app final campaign values, you can attach them to the customer using reserved Customer Attributes.
Don't set your own fallback campaign values, such as Organic, Unknown, or No User Consent, while waiting for Adjust attribution. Reserved attribution attributes can only be set once per customer. If Adjust later returns final campaign values, RevenueCat can't replace a placeholder value you already set.
If you set these campaign attributes from an Adjust callback or delegate, keep the $adjustId setup above in place. Campaign attributes are additive, not a replacement for the required Adjust ID.
| Key | Description |
|---|---|
$mediaSource | The attribution source or network |
$campaign | The campaign name or identifier |
$adGroup | The ad group name or identifier |
$ad | The ad name or identifier |
$keyword | The keyword associated with the attribution |
$creative | The creative name or identifier |
3. Send RevenueCat events into Adjust
After you've set up the RevenueCat SDK to send attribution data from Adjust to RevenueCat, you can enable the integration and configure the event tokens from the RevenueCat dashboard.
-
Go to your dashboard and select your project.
-
In the lower-left corner, select Integrations.
-
Select Adjust.
-
Configure each platform you want RevenueCat to send events from:
- Open the platform's configuration section.
- Skip the OAuth token override field for now. This optional field is explained in (Optional) Configure S2S Adjust authentication.
- Add the Adjust app token.
- Create or find the corresponding events in Adjust for the core subscription lifecycle events described in the setup checklist, then copy each Adjust-generated event token into the matching RevenueCat event token field.
- Configure any optional event tokens from Event types that you want RevenueCat to send.
-
Select whether you want sales reported as gross revenue (before app store commission), or after store commission and/or estimated taxes. This setting applies to the Adjust integration as a whole. It changes the revenue value RevenueCat sends to Adjust, so use the same reporting mode when comparing Adjust-side ROAS to RevenueCat revenue metrics. Learn more about taxes and commissions.
If you set $adjustId and other attributes after configuring Purchases and before a purchase occurs, RevenueCat syncs them with the purchase event. You usually don't need to call syncAttributesAndOfferingsIfNeeded() for Adjust. Reserve explicit syncs for cases where newly set attributes must affect Targeting or where you need to avoid a race with server-side purchase tracking. Avoid frequent calls because this SDK method is limited to 5 calls per minute per running app instance.
Event types
RevenueCat sends Adjust events using the event tokens you configure for each platform. Adjust event tokens are provider-issued identifiers, not readable event names. Use the token for the matching Adjust event, and don’t reuse a token across different RevenueCat lifecycle events unless you intentionally want Adjust to report them as the same event.
RevenueCat sends the core subscription lifecycle events described in the setup checklist. Adjust also supports these optional events:
| Optional event | Sent when |
|---|---|
| Non-subscription purchase | A user makes a one-time (non-subscription) purchase |
| Expiration | A subscription expires and access is lost |
| Product change | A user changes the product of their subscription |
(Optional) Configure S2S Adjust authentication
If you've enabled S2S authentication on Adjust, add the matching OAuth token to RevenueCat:
- To use the same token for every platform, in the Adjust integration settings, add the token to Global OAuth token.
- To use a platform-specific token, in the matching platform configuration section, add the token to OAuth token override.
If both fields are set for a platform, RevenueCat uses the platform OAuth token override instead of the Global OAuth token.
If you enable S2S authentication in Adjust and don't configure an OAuth token in RevenueCat, Adjust will respond to events with the following error:
{"error":"Event request failed (missing authentication token)"}
4. Test the Adjust integration
Before rolling out the integration, test with a new customer after the SDK, customer attributes, and dashboard settings are configured.
- Make a sandbox purchase with a new customer.
- In the RevenueCat Customer Profile, confirm the required attributes from Send attribution data to RevenueCat are present.
- In Customer History, open the sandbox purchase event and confirm the Adjust delivery row exists. If RevenueCat doesn't show an Adjust delivery row, see no provider delivery row troubleshooting.
- In the RevenueCat Adjust integration settings, review failed events and compare any error codes with Adjust's server-to-server API reference. For general rejection guidance, see provider rejection troubleshooting.
Verify sandbox events in Adjust Testing Console
RevenueCat sends sandbox subscription events to Adjust in sandbox mode. In Adjust Testing Console, use the SANDBOX MODE filter to view sandbox events before moving to production, especially if you're submitting an app with Adjust attribution for the first time. See Adjust Testing Console docs.

You should start seeing events from RevenueCat appear in Adjust!
Historical or backfilled events
Adjust can warn or reject events that arrive out of timestamp order, such as a historical import sent after a newer live event for the same customer. Test migrations with a small sample before sending a large backfill.
See historical or backfilled event troubleshooting for the shared pattern.
Sample event
Below is a representative sample event sent to Adjust. The type of event (for example, initial purchase or renewal) is defined by the configured event_token. Optional device and revenue fields depend on the customer attributes and event data available when RevenueCat processes the event.
- Code
{
"app_token": "abcdefg",
"event_token": "abcdefg",
"s2s": 1,
"created_at_unix": 1640995185,
"adid": "00000000000000000000000000000000",
"environment": "production",
"currency": "USD",
"revenue": 34.511,
"idfa": "00000000-0000-0000-0000-000000000000",
"idfv": "00000000-0000-0000-0000-000000000000",
"ip_address": "00.0.000.000",
"sender": "revenuecat"
}