One of the first questions mobile teams ask after implementing Mixpanel is:
“How do we know where our app installs are coming from?”
It’s a fair question.
You launch campaigns on:
- Google Ads
- Meta Ads
- TikTok
- Apple Search Ads
Users click an ad.
Install your app.
Create an account.
Maybe subscribe weeks later.
Now the product team wants to know:
- Which campaigns drive installs?
- Which channels drive paying users?
- Which ad networks generate the highest retention?
- Which campaigns create the most valuable customers?
This is where mobile attribution comes in.
Unlike web attribution, mobile attribution isn’t straightforward because users typically go through the App Store or Google Play Store before opening your application.
That extra step makes attribution significantly more complicated.
This is why most companies rely on attribution providers such as:
- Adjust
- AppsFlyer
- Branch
- Kochava
- Singular
These platforms specialize in connecting ad clicks, installs, re-engagements, and post-install activity.
The next challenge is getting that attribution data into Mixpanel.
There are three common approaches:
| Method | Complexity | Flexibility | My Recommendation |
| Webhooks | High | Very High | Best for mature data teams |
| SDK → SDK | Medium | High | Best for most mobile apps |
| Server → Mixpanel | Low | Limited | Fastest to implement |
Let’s walk through each one.
Before You Implement Attribution
Before talking about SDKs and integrations, let’s talk about the thing that usually causes the biggest problems.
Identity management.
Most attribution providers use their own device identifiers.
Mixpanel uses:
distinct_id
Your backend probably uses:
user_id
And your attribution provider may use:
adid
or another device identifier.
If you don’t connect those IDs correctly, you’ll eventually run into:
- Duplicate users
- Hidden profiles
- Attribution data disconnected from user activity
- Incorrect conversion reporting
The ideal relationship looks like:
Adjust Device ID (adid)
↓
Mixpanel distinct_id
↓
Authenticated User ID
The sooner you connect those identifiers, the easier reporting becomes later.
Option 1: Mobile Attribution Using Webhooks
This is usually the most flexible approach.
Instead of sending attribution data directly into Mixpanel, the attribution provider sends it to your infrastructure first.
The flow looks like this:
User Clicks Ad
↓
Installs App
↓
Adjust / AppsFlyer
↓
Webhook
↓
Your Backend
↓
Mixpanel
When a new install occurs, the attribution provider sends attribution data to your webhook endpoint.
The payload typically contains information such as:
- Device ID
- Campaign
- Network
- Ad Group
- Creative
- Install Timestamp
Example Workflow Using Adjust
Let’s use Adjust as an example.
Adjust sends an install callback containing an:
adid
which is Adjust’s device identifier.
At the same time, your mobile application has access to:
mixpanel.getDistinctId()
through the Mixpanel SDK.
When the application launches, send both values to your backend.
Example:
String mixpanelDistinctId = mixpanel.getDistinctId();
String adjustDeviceId = adjustAdid;
Now your database can store:
| Adjust Device ID | Mixpanel Distinct ID |
| abc123 | xyz456 |
Later, if the user authenticates:
String userId = “user_123”;
you can update the relationship:
| Adjust Device ID | Mixpanel Distinct ID | User ID |
| abc123 | xyz456 | user_123 |
At this point attribution, anonymous activity, and authenticated activity are all connected.
What I Usually Do
Instead of immediately sending attribution into Mixpanel, I prefer:
Webhook
↓
Data Warehouse
↓
Transformation Layer
↓
Mixpanel
Why?
Because attribution data changes.
Sometimes networks update attribution decisions.
Sometimes installs get reattributed.
Sometimes campaign names change.
When attribution lives in your warehouse first, you control how that data ultimately reaches Mixpanel.
Advantages
| Advantage | Why It Matters |
| Full Control | Transform data before sending |
| Highest Accuracy | Handle attribution updates correctly |
| Easier Auditing | Attribution data stays in your warehouse |
| Flexible Reporting | Build custom attribution models |
Disadvantages
| Disadvantage | Why It Matters |
| More Infrastructure | Requires backend processing |
| Additional Development | Someone has to maintain it |
My Recommendation
If your company already uses:
- BigQuery
- Snowflake
- Redshift
- Databricks
this is often the best long-term solution.
Option 2: SDK-to-SDK Attribution Tracking
This is usually my preferred approach for mobile applications.
Instead of relying on webhooks, you install both:
- Mixpanel SDK
- Attribution Provider SDK
inside your application.
The attribution provider returns campaign data directly to the device.
Your application then sends that data into Mixpanel.
The flow looks like:
App Launch
↓
Adjust SDK
↓
Attribution Data
↓
Mixpanel SDK
↓
Track Install Event
Android Example
Below is the full example workflow from the documentation.
When attribution data becomes available, the application stores it locally and sends the install event to Mixpanel.
private trackAttribution(AdjustAttribution attribution){
if(isAttributionAlreadyStored()){ //function to check if the data is already on the device
return;// data already stored, nothing to do
}
JSONObject props = new JSONObject();
insertJsonProperty(props, “[Adjust]Network”, attribution.network);
insertJsonProperty(props, “[Adjust]Campaign”, attribution.campaign);
insertJsonProperty(props, “[Adjust]Adgroup”, attribution.adgroup);
insertJsonProperty(props, “[Adjust]Creative”, attribution.creative);
storeAttribution(props); //store the data for later user
mixpanel.track(“install”, props);//send the install event since this is the first time it has been received
}
private void insertJsonProperty(JSONObject props, String name, String value) {
try {
if (value != null) {
props.put(name, value);
}
} catch(JSONException e) { }
}
Why This Code Matters
There are three important things happening here.
1. Preventing Duplicate Install Events
if(isAttributionAlreadyStored()){
return;
}
Without this check, the SDK may send multiple install events for the same user.
I’ve seen implementations where install counts were inflated simply because attribution was being reprocessed every time the app opened.
2. Capturing Attribution Properties
insertJsonProperty(props, “[Adjust]Network”, attribution.network);
insertJsonProperty(props, “[Adjust]Campaign”, attribution.campaign);
insertJsonProperty(props, “[Adjust]Adgroup”, attribution.adgroup);
insertJsonProperty(props, “[Adjust]Creative”, attribution.creative);
These properties become some of the most useful dimensions inside Mixpanel.
You’ll eventually use them to answer:
- Which campaigns generate subscriptions?
- Which ad groups produce retained users?
- Which creatives drive revenue?
3. Storing Attribution Locally
storeAttribution(props);
This line is easy to overlook.
Don’t.
A user might:
Install App Today
↓
Open App
↓
Close App
↓
Register Next Week
Without local storage, attribution can disappear before the user authenticates.
I always recommend storing attribution data before sending it anywhere else.
What Properties Should You Track?
At minimum:
{
“Network”: “Facebook”,
“Campaign”: “Summer Sale”,
“Ad Group”: “Prospecting”,
“Creative”: “Video Ad 1”
}
This is usually enough to build meaningful acquisition reports.
Updating the User Profile After Authentication
Once a user creates an account:
mixpanel.identify(userId);
Then update the profile:
JSONObject profileProps = new JSONObject();
profileProps.put(“Install Network”, “Facebook”);
profileProps.put(“Install Campaign”, “Summer Sale”);
mixpanel.getPeople().set(profileProps);
Now attribution becomes part of the user profile instead of existing only on the install event.
Advantages
| Advantage | Why It Matters |
| No Backend Required | Simpler implementation |
| Strong Identity Management | Everything happens through the Mixpanel SDK |
| Easy Debugging | Attribution lives in the application |
| Highly Configurable | Full control over events and properties |
Disadvantages
| Disadvantage | Why It Matters |
| More Development Work | Requires SDK implementation |
| App Releases Required | Changes usually require deployment |
My Recommendation
For most mobile teams, this is the approach I’d start with.
It gives you control without requiring additional infrastructure.
Option 3: Partner Server-to-Mixpanel Integrations
Most attribution providers also offer direct Mixpanel integrations.
The flow is simple:
App
↓
Attribution Partner
↓
Mixpanel
Once configured, the partner sends attribution events and profile properties directly into Mixpanel.
This is often the quickest approach.
Why Teams Like It
Minimal engineering effort.
In some cases, you can enable attribution tracking without shipping a new app version.
Why I’m Careful With It
This approach creates the most identity-related problems.
The attribution provider often sends data using its own identifier.
Meanwhile, your application sends data using Mixpanel’s distinct_id.
Now you have two separate identities.
Partner Identity
+
Mixpanel Identity
representing the same person.
Hidden Profile Issues
This is probably the biggest drawback.
Even when event merging works correctly, profile merging doesn’t.
The result:
Anonymous Profile
+
Authenticated Profile
One profile often becomes hidden.
I’ve seen teams discover this months later while debugging user reports.
Advantages
| Advantage | Why It Matters |
| Fast Setup | Minimal implementation effort |
| Low Maintenance | Partner manages data delivery |
| No Infrastructure Required | Easier for smaller teams |
Disadvantages
| Disadvantage | Why It Matters |
| Identity Issues | Most common problem |
| Hidden Profiles | Difficult to clean up later |
| Less Flexible | Limited control over data |
| Harder To Debug | Attribution logic lives elsewhere |
My Recommendation
Good for quick deployments.
Not my first choice if attribution is critical to the business.
What About Android Install Referrer?
Android provides:
getInstallReferrer()
which allows you to retrieve some attribution information directly from Google Play.
Example:
InstallReferrerClient referrerClient =
InstallReferrerClient.newBuilder(context).build();
referrerClient.startConnection(new InstallReferrerStateListener() {
@Override
public void onInstallReferrerSetupFinished(int responseCode) {
try {
ReferrerDetails response =
referrerClient.getInstallReferrer();
String referrerUrl =
response.getInstallReferrer();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onInstallReferrerServiceDisconnected() {}
});
This can work for basic attribution needs.
However, it provides significantly less data than dedicated attribution providers.
For serious mobile marketing measurement, I’d still recommend a dedicated attribution platform.
Which Approach Should You Choose?
If I were implementing mobile attribution today:
Startup or Small Team
Attribution SDK
↓
Mixpanel SDK
Simple.
Reliable.
Easy to maintain.
Data-Driven Organization
Partner Webhooks
↓
Warehouse
↓
Mixpanel
Most flexibility.
Best reporting quality.
Fastest Possible Setup
Partner Server
↓
Mixpanel
Fastest deployment.
Most limitations.
Final Thoughts
Mobile attribution isn’t really an SDK problem.
It’s an identity problem.
Most attribution issues aren’t caused by missing campaign data.
They’re caused by disconnected identifiers.
Before choosing an attribution strategy, make sure you understand how you’ll connect:
- Attribution Provider IDs
- Mixpanel distinct_ids
- Authenticated User IDs
Get that right, and any of the three approaches can work.
Get it wrong, and you’ll spend months wondering why attribution reports don’t match the rest of your analytics.
