# Mixpanel (Legacy) Destination

## Destination Info

* Accepts [Page](/docs/segment/connections/spec/page), [Alias](/docs/segment/connections/spec/alias), [Group](/docs/segment/connections/spec/group), [Identify](/docs/segment/connections/spec/identify), [Track](/docs/segment/connections/spec/track) calls.
* In Cloud-mode, refer to it as **Mixpanel** in the [Integrations object.](/docs/segment/guides/filtering-data/#filtering-with-the-integrations-object)
* In Device-mode, refer to it as **Mixpanel** in the [Integrations object.](/docs/segment/guides/filtering-data/#filtering-with-the-integrations-object)

### Components

* Browser
* [iOS](https://github.com/segment-integrations/analytics-ios-integration-mixpanel)
* [Android](https://github.com/segment-integrations/analytics-android-integration-mixpanel)
* Server

[Mixpanel](https://mixpanel.com/?utm_source=segmentio\&utm_medium=docs\&utm_campaign=partners) is an event tracking and segmentation platform for your web and mobile apps. By analyzing the actions your users perform, you can gain a better understanding to drive retention, engagement, and conversion. The client-side Mixpanel Destination code is open-source.

Segment's Mixpanel destination code is open source and available on GitHub. You can view these repositories:

* [Analytics.js in Device-mode](https://github.com/segmentio/analytics.js-integrations/tree/master/integrations/mixpanel)
* [Android](https://github.com/segment-integrations/analytics-android-integration-mixpanel)
* [iOS](https://github.com/segment-integrations/analytics-ios-integration-mixpanel)
* [Swift](https://github.com/segment-integrations/analytics-swift-mixpanel)
* [Kotlin](https://github.com/segment-integrations/analytics-kotlin-mixpanel)

## Getting started

1. From the Segment app Destinations page click on **Add Destination**.
2. Search for Mixpanel in the Destinations Catalog and confirm the Source to connect to.
3. Copy your Mixpanel "API Secret" and "Token", and paste them into the Connection Settings in Segment.
4. Enable the destination to start sending your data to Mixpanel.

## Page

If you're not familiar with the Segment Spec, take a look to understand what the [Page method](/docs/segment/connections/spec/page/) does. An example call would look like:

```javascript
analytics.page()
```

By default, the Page call is transformed to Mixpanel events. This sends all Page and Screen calls with a single name, for example `Loaded a Page` or `Loaded a Screen` respectively, with the calls' properties in the body. This gives the best experience of Page/Screen analytics with Mixpanel's reporting.

You can disable this default by changing the "Track All Pages to Mixpanel with a Consolidated Event Name" in the Mixpanel destination settings.

If you want to track the Page or Screen calls to Mixpanel with the name or category in the event name, Segment offers these options to send page/screen calls:

1. Track All Pages to Mixpanel with a Consolidated Event Name
2. Track all Pages to Mixpanel
3. Track Categorized Pages to Mixpanel
4. Track Named Pages to Mixpanel

> \[!NOTE]
>
> Beginning with "Consolidate Page" calls, the following options are each *mutually exclusive*. [See the code for details](https://github.com/segmentio/analytics.js-integrations/blob/master/integrations/mixpanel/lib/index.js#L96-L139).

### Setting prioritization

When you use the Mixpanel destination in Cloud-mode, Segment sends events for each option you select. This may result in Mixpanel receiving duplicate events for a single page call.

When you use the Mixpanel destination in Device-mode, Segment prioritizes the options to prevent duplicate calls as follows:

* If you select "Track all Pages to Mixpanel", all Page calls regardless of how you have customized it will send a `Loaded A Page`. Even if you have the other options enabled, Segment sends this call to prevent double counting your pageviews.
* If you select "Track Categorized Pages to Mixpanel", Segment sends a `Viewed [category] Page` event.
* If you select "Track Named Pages to Mixpanel", Segment sends a `Viewed [name] Page` event.

> \[!NOTE]
>
> If both Option 2 and 3 are enabled, Segment gives precedence to `category`. If you pass both `category` and `name`, (for example, `analytics.page('category', 'name');`), Segment sends a `Viewed category name Page` to Mixpanel.

In short, Segment sends one event to Mixpanel per Page call.

## Identify

If you're not familiar with the Segment Spec, take a look to understand what the [Identify method](/docs/segment/connections/spec/identify/) does. An example call would look like:

```js
analytics.identify('userId123', {
  firstName: 'James',
  lastName: 'Gibbon'
})
```

The first thing you'll want to do is to identify your users so Mixpanel knows who they are. You'll use the Identify method to accomplish this which takes the unique `userId` of a user and any `traits` you know about them.

> \[!NOTE]
>
> **Important:** Mixpanel used to require that you call `alias` in all libraries to connect anonymous visitors to identified users. However, with the release of Mixpanel's new [Identity Merge feature](https://help.mixpanel.com/hc/en-us/articles/9648680824852#introduction) this is no longer necessary. To enable ID Merge, go to your Mixpanel Settings Dashboard, navigate to **Project Settings > Identity Merge** and enable the setting from that screen. If you are *not* using this setting, use the instructions below.

As soon as you have a `userId` for a visitor that was previously anonymous you'll need to [`alias`](/docs/segment/connections/spec/alias/) their old anonymous `id` to the new `userId`. In Mixpanel only **one** anonymous user history can be merged to **one** identified user. For that reason you should only call `alias` once, right after a user registered, but before the first Identify.

### People

Segment doesn't send data to Mixpanel People by default. To enable Mixpanel People, change the "Use Mixpanel People" setting in the Mixpanel Destination settings in Segment.

To add people properties in Mixpanel before you know the user's unique database `userId`, you can identify `traits` without the `userId`.

> \[!NOTE]
>
> This only works in Analytics.js and the Segment mobile SDKs.

The Identify call would look like this in Analytics.js if you only want to set people properties without a `userId`:

```js
analytics.identify({
  email: 'hello@example.com',
  name: 'Ian Taylor'
})
```

## Group

Group calls are sent to Mixpanel if, **and only if**,

1. The Group Identifier Traits setting has one or more traits saved in the destination settings for Mixpanel.

   ![The Mixpanel Traits and Properties list showing the "Group Identifier Traits" field where one or more traits (like company\_id) can be defined for grouping users.](https://docs-resources.prod.twilio.com/b12a35e6e6e5fbc726551ae94c033e3469ad508eff69ea99540ecdd0423931fc.png)
2. You have created a group key of the same name in your Mixpanel [project settings](https://help.mixpanel.com/hc/en-us/articles/360025333632-Group-Analytics#implementation).
3. A Group trait with the same name as one of the configured Group Identifier Traits is sent with the group call.

```js
analytics.group("0e8c78ea9d97a7b8185e8632", {
  name: "Initech",
  company_id: "0e8c78ea9d97a7b8185e8632", // Group identifier trait.
  industry: "Technology",
  employees: 329,
  plan: "enterprise",
  "total billed": 830
});
```

Mixpanel supports multiple definitions of groups. For more information see [Mixpanel's Group Analytics documentation](https://help.mixpanel.com/hc/en-us/articles/360025333632-Group-Analytics).

If the group call **does not** have a group trait that matches the Group Identifier Traits setting, then the event will be ignored.

If you'd like to connect a track call to a group call in Mixpanel, send the group's ID as a property on the track call named `$group_id`.

### Group using device-mode

When you use Analytics.js, you must set a `userId` value, or Mixpanel will ignore Group calls.
When using Analytics.js, a `userId` must be set or group calls to Mixpanel will be ignored. When you call the Identify method from the client in either a browser using Analytics.js or one a mobile SDKs, several things occur:

Segment recognizes and translates the [special traits](/docs/segment/connections/spec/identify/#traits) so that they fit the expectations of Mixpanel's API. The table below shows the mappings. Pass the key on the left and Segment transforms it to the key on the right before sending to Mixpanel.

| `created`   | `$created`    |
| ----------- | ------------- |
| `email`     | `$email`      |
| `firstName` | `$first_name` |
| `lastName`  | `$last_name`  |
| `name`      | `$name`       |
| `username`  | `$username`   |
| `phone`     | `$phone`      |

### Group using cloud-mode

When you call the Identify method from any of Segment's server libraries, Segment creates or updates the user in Mixpanel People with the traits you provide. Calling Identify doesn't create any users in the standard Mixpanel reporting interface since that only supports Track events.

You won't see server-side `traits` appear as super-properties on any events you track. This is because Mixpanel [has no REST API](https://github.com/mixpanel/mixpanel-node/issues/48) for setting [super properties](https://mixpanel.com/docs/managing-users/managing-user_advanced/specific-properties) for a `distinct_id`, so [Identify](/docs/segment/connections/spec/identify/) calls only affect Mixpanel People.

For Mixpanel People, it's important to Identify a user before you call Track. A Track without an Identify won't create a user in Mixpanel People.

If you use cloud-mode, you must explicitly include the grouping value as an event property for any event you want to analyze using Mixpanel's Group Analytics.

### Register super properties

By default, each trait (that is, properties in an Identify call) is registered as a super property. This doesn't require passing a `userId` in the Identify call. You can pass a `traits` object by itself and it will still register the traits as super properties.

Disable **Set All Traits as Super Properties or People Properties By Default** to disable the default behavior and register super properties explicitly. For more information, see [Explicitly set People Properties and Super Properties](#explicitly-set-people-properties-and-super-properties).

> \[!NOTE]
>
> Super properties require a device mode connection.

#### Set People properties

If you've enabled Mixpanel People in your Segment settings, Segment calls Mixpanel's `people.set` with the same `traits` object. There's no need for an additional API call to populate Mixpanel People.

Disable **Set All Traits as Super Properties or People Properties By Default** to disable the default behavior and register super properties explicitly. Segment automatically includes any trait on an identify that matches one of Mixpanel's special properties, which you can see in the table above. For more information, see [Explicitly set People Properties and Super Properties](#explicitly-set-people-properties-and-super-properties).

If you call Identify without a `userId`, it may not set the People Properties inside Mixpanel, but it will cache those traits for later use with Segment's `analytics.js`. It is best practice to always call Identify with a `userId`.

### Arrays

For array type traits passed to Identify calls, Segment uses Mixpanel's `people.union` to union (append ignoring duplicates) them to their existing values. If the trait doesn't exist a new array will be created for you. To clear the contents of an array trait, you can pass an empty array `[]`.

## Track

If you're not familiar with the Segment Spec, take a look to understand what the [Track method](/docs/segment/connections/spec/track/) does. An example call would look like:

```javascript
analytics.track('Button Clicked')
```

Because Mixpanel is an event tracking analytics tool, you'll want to [Track](/docs/segment/connections/spec/track/) your user's actions. The more useful events you [Track](/docs/segment/connections/spec/track/), the better Mixpanel becomes.

You should use the [Track](/docs/segment/connections/spec/track/) method to accomplish this. The Segment [Track](/docs/segment/connections/spec/track/) method maps events and event properties directly to Mixpanel events and event properties.

### Track charge

If Mixpanel People is enabled in your Segment settings and you include an event property called `revenue`, Segment tracks a charge to the current user.

### Reserved properties

There are two strings to avoid when naming event properties that will be sent to Mixpanel: `length` and `bucket`. `length` is interpreted as the JavaScript `.length` method, which causes the `mixpanel.track` call to fail silently. `bucket` is a reserved property that was used in the early days of Mixpanel. If you include a property called `bucket` in your events, it will not show up in the UI. However, it will not cause the `mixpanel.track` call to fail.

## Alias

If you're not familiar with the Segment Spec, take a look to understand what the [Alias method](/docs/segment/connections/spec/alias/) does. An example call would look like:

```javascript
analytics.alias('newUserId')
```

> \[!NOTE]
>
> **Important:** Mixpanel used to require that you call `alias` in all libraries to connect anonymous visitors to identified users. However, with the release of Mixpanel's new [Identity Merge feature](https://help.mixpanel.com/hc/en-us/articles/360039133851#enable-id-merge) this is no longer necessary. To enable ID Merge, go to your Mixpanel Settings Dashboard, navigate to **Project Settings > Identity Merge** and enable the setting from that screen. If you are *not* using this setting, use the instructions below.

As soon as you have a `userId` for a visitor that was previously anonymous you'll need to [`alias`](/docs/segment/connections/spec/alias/) their old anonymous `id` to the new `userId`. In Mixpanel only **one** anonymous user history can be merged to **one** identified user. For that reason you should only call `alias` once, right after a user registered, but before the first Identify. To merge identities in Mixpanel, send an identify call with both the previous anonymous ID, and the new user ID, as follows:

```javascript
analytics.alias('anonId','newUserId');
```

You can Track the action that caused the user to be identified or created. For more information, see [Best Practices for Identifying Users](/docs/segment/connections/spec/best-practices-identify/).

Read more about how Mixpanel recommends using `alias` [in their docs](https://mixpanel.com/docs/integration-libraries/using-mixpanel-alias).

> \[!TIP]
>
> Segment recommends that you alias on the client whenever possible, due to technical limitations with aliasing server-side.

### Alias using device-mode

In client-side JavaScript you only need to pass the new identified `userId`. Segment aliases the old anonymous `id` to your new `userId`.

Here's a JavaScript example where the new `userId` is `12345`:

```javascript
analytics.alias('12345');
analytics.identify('12345');
analytics.track('User Signed Up');
```

### Alias using cloud-mode

If an Identify or Track call arrives to Mixpanel with a new `distinct_id` too quickly after an `alias` call, there is a race condition between the event and the alias call. As long as your Identify and Track calls arrive \~1 second after the `alias`, this shouldn't be an issue; when the alias queue is backed up, Mixpanel queues events as well, mitigating the race condition.

However, in cases when events are processed too quickly, before their corresponding alias, your calls can result in split/duplicate profiles.

Mixpanel's client-side JavaScript library fixes this issue by continuing to send Track calls to the original mixpanel `distinct_id` while the records update.

> \[!TIP]
>
> Segment recommends that you alias for Mixpanel on the client side through Analytics.js to avoid creating split profiles and broken funnels.

However, in certain circumstances, despite the risk of duplicate profiles, you may still wish to send the calls server-side. In those cases, there are two options for calling [`alias`](/docs/segment/connections/spec/alias/) from your servers:

#### In conjunction with client-side tracking

If you track anonymous users on the client side either from a browser or one of a mobile SDK, pass the Mixpanel `distinct_id` from the browser to your servers in order to [`alias`](/docs/segment/connections/spec/alias/) it to the new `userId`.

First, use [`analytics.ready`](/docs/segment/connections/sources/catalog/libraries/website/javascript#ready) to grab the Mixpanel `distinct_id`:

```js
analytics.ready(function(){
    var anonId = mixpanel.get_distinct_id();
});
```

Next, pass the `anonId` to your server and [`alias`](/docs/segment/connections/spec/alias/), [Identify](/docs/segment/connections/spec/identify/), and [Track](/docs/segment/connections/spec/track/) your new user.

Here's a Node example where the new `userId` is `12345`:

```js
analytics.alias({ previousId: anonId, userId: '12345' });
analytics.flush(); // flush the alias

analytics.identify({userId: '12345'});
analytics.track({
  userId: '12345',
  event: 'Connected Facebook'
});
```

Segment recommends that you flush the [`alias`](/docs/segment/connections/spec/alias) to give Mixpanel more time to process it on their side before you [Identify](/docs/segment/connections/spec/identify) and [Track](/docs/segment/connections/spec/track).

#### Tracking exclusively server-side

If you're tracking anonymous users with a server-side library, you can [`alias`](/docs/segment/connections/spec/alias/) the anonymous `id` to the new `userId`.

Here's a Python example of the [`alias`](/docs/segment/connections/spec/alias/), [Identify](/docs/segment/connections/spec/identify/), [Track](/docs/segment/connections/spec/track/) sequence where the anonymous `id` was `92fh49fqh9849hf` and the new `userId` is `12345`:

```python
analytics.alias('92fh49fqh9849hf', '12345')
analytics.flush() # flush the alias

analytics.identify('12345')
analytics.track('12345', 'Registered')
```

Segment recommends that you flush the [`alias`](/docs/segment/connections/spec/alias) to give Mixpanel more time to process it on their side before you [Identify](/docs/segment/connections/spec/identify) and [Track](/docs/segment/connections/spec/track).

## Best practices

### Collecting contextual properties

If you send events server side, depending on your library (JS, mobile, or server), Segment maps as many [Mixpanel supported contextual properties](https://mixpanel.com/help/questions/articles/what-properties-do-mixpanels-libraries-store-by-default) as possible.

You can see which [context properties are being automatically collected by any Segment library](/docs/segment/connections/spec/common/). If you use a library that doesn't support a certain contextual property, you can still send them manually with your events, as long as it's sent in accordance with the [spec](/docs/segment/connections/spec/common/).

For example, if you want to send `utm` parameters with your server side library, you can attach a `context.campaign` object like this:

```javascript
// node library

analytics.track({
  userId: '019mr8mf4r',
  event: 'Purchased an Item',
  properties: {
    revenue: 39.95,
    shippingMethod: '2-day'
  },
  context: {
    campaign: {
      name: "TPS Innovation Newsletter",
      source: "Newsletter",
      medium: "email",
      term: "tps reports",
      content: "image link"
    }
  }
});
```

Segment doesn't map `$library_version` since that is reserved for Mixpanel's library version, not Segment's. Segment doesn't map to `$brand`.

## Features

### People

Segment doesn't send data to Mixpanel People by default. To enable Mixpanel People, change the "Use Mixpanel People" setting in the Mixpanel Destination settings in Segment.

If you want to add people properties in Mixpanel before you know the user's unique database `userId` you can identify `traits` without the `userId`.

Your Identify call would look like this in Analytics.js if you only want to set people properties without a `userId`:

```js
analytics.identify({
  email: 'example@example.com',
  name: 'Ian Taylor'
})
```

### UTM campaign parameters

When used in Device Mode through a web source, Segment's client-side Javascript library, Analytics.js, loads `mixpanel.js` (Mixpanel's direct SDK) in the background. As a result, you'll get the exact same functionality from Mixpanel around UTM Campaign Parameters as you would when using Mixpanel directly.

[Read more in Mixpanel's UTM docs](https://mixpanel.com/help/questions/articles/can-i-track-google-analytics-style-utm-tags-with-mixpanel)

In order to pass UTM parameters server-side, you can either pass properties or traits of `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, and `utm_term` in your track and identify calls, or pass them in your `context` object, for example:

```javascript
// node library

analytics.track({
  userId: '019mr8mf4r',
  event: 'Item Purchased',
  properties: {
    revenue: 39.95,
    shippingMethod: '2-day'
  },
  context: {
    campaign: {
      name: "TPS Innovation Newsletter",
      source: "Newsletter",
      medium: "email",
      term: "tps reports",
      content: "image link"
    }
  }
});
```

### Explicitly set People Properties and Super Properties

Previously, Segment set all traits and properties as both Super Properties and People Properties (If you had Mixpanel People enabled). Now Mixpanel allows you to segment your reports by both People Properties and Super Properties. To give you better precision and control over what property or trait gets set as a Super Property or People Property, you can disable **Set All Traits as Super Properties or People Properties By Default** and pass in the properties or traits that you want to send to Mixpanel as People or Super Properties as shown below. Segment passes through all of Mixpanel's special traits as People Properties so you only need to add the ones that aren't on [this list](#group-using-device-mode).

![MIxpanel Traits and Properties list with Properties to increment in People option highlighted.](https://docs-resources.prod.twilio.com/ecb3f32ddc96c4da49d230c20365d8129716a407f2a7a72f64a2b2da31c4340d.png)

### Incrementing events

You don't need to add extra code to increment event counts for Mixpanel people, as long as they are "known users". Supply the events that should be incremented.

![The Mixpanel Traits and Properties list with Properties to increment in People option highlighted.](https://docs-resources.prod.twilio.com/4488b896b709feb3f85f38c0a830b03e2f0f9cf5ef4c465c44815937ced7e38f.png)

You can find this in the **Advanced Options** of your Mixpanel settings on your Segment Destinations page.

For each event name listed, Segment calls Mixpanel `increment`, and set a user trait of `Last + {{ event.name }}`.

For example, if you add **Logged In** to the list of increment events, Segment increments a user trait called **Logged In** and set a trait called **Last Logged In** with the current date and time.

If you'd like to add an increment for viewing a specific page or screen, ensure you have the setting "Track Named Pages" selected and use the dynamically generated event name under "Events to Increment in People." For example, `.page('Signup')` would translate to "*Viewed* Signup *Page*" and `.screen('Listing')` would translate to "*Viewed* Listing *Screen*".

Remember, Segment sends one event per Page call.

> \[!NOTE]
>
> Increment works for "known users", so if your track call is being made server-side, you need to pass a `userId`. If your track call is being made client-side, you need to identify the user first.

### Incrementing properties

To increment at the property level, tell Segment which properties you want to increment using the **Properties to increment** setting and Segment calls Mixpanel's `increment` for you when you attach a number to the property. For example, you need to increment the following property:

```javascript
analytics.track('Event Name', {
feedback_day_number: 1
}
);
```

Enter the `propertyname: _feedback_day_number_` in the destination settings. The property value now increases from 1.

### Reset Mixpanel cookies

When a user logs out, Segment recommends that you call `analytics.reset();` to clear the Segment cookie. This function isn't mapped to Mixpanel's reset method. If you have issues with `distinct_id` for example, if it's not matched with the right user, you should add this to your logout flow:

```javascript
analytics.ready(function(){
  window.mixpanel.cookie.clear();
});
```

### Ignore IP from server to disable geo-location in Mixpanel People

To avoid having any IP address sent to Mixpanel and by doing so, turn off geo-location for server-side users, pass the `context.ip` as 0.

Here's a python example:

```python
analytics.track(user_id=user.id,
  event='Ignore My IP', context={
  'ip': 0
})
```

Provide `context.ip` to all your [Identify](/docs/segment/connections/spec/identify/), [Track](/docs/segment/connections/spec/track/), and [`alias`](/docs/segment/connections/spec/alias/) calls to make sure Mixpanel doesn't geo-locate your users.

### Sending data to Mixpanel's European Union endpoint

To implement Mixpanel in the European Union, enable the setting "Enable European Union Endpoint" on the Settings tab of the Mixpanel destination. When this setting is enabled, Segment updates the endpoint for any data sent from server-side libraries, browsers using Analytics.js, or the iOS SDK.

If you send data with the Android SDK, specify the different endpoints with meta-data tags. On your app's `AndroidManifest.xml` file, add the following tags under your `<application>` tags to override the track, engage, and group endpoints:

```xml
<meta-data android:name="com.mixpanel.android.MPConfig.EventsEndpoint"
           android:value="https://api-eu.mixpanel.com/track?ip=" />
<meta-data android:name="com.mixpanel.android.MPConfig.PeopleEndpoint"
           android:value="https://api-eu.mixpanel.com/engage=" />
<meta-data android:name="com.mixpanel.android.MPConfig.GroupsEndpoint"
           android:value="https://api-eu.mixpanel.com/groups" />
```

See the [Mixpanel documentation on their European Union endpoint](https://developer.mixpanel.com/docs/implement-mixpanel#section-implementing-mixpanel-in-the-european-union-eu) for additional information.

## Troubleshooting

### When will I eee data from my mobile app?

If you already have an app deployed with the Segment library, and you just enabled Mixpanel mobile, it can take up to an hour for all your mobile users to refresh their Segment settings cache, and learn about the new service that you want to send to.

After the settings cache refreshes, the library starts to send data to Mixpanel.

Also worth noting, Mixpanel's SDK only submits requests to the Mixpanel servers when the app is backgrounded. That means you may see events in your Segment debugger while testing, but those requests won't actually be forwarded to Mixpanel until the app gets sent to the background.

If you're testing in Xcode remember you must first background the app, then the events will show up in Mixpanel. If you terminate the session without backgrounding those events will be lost.

### I'm seeing events come into Mixpanel, but not people.

1. You'll need to make sure you're using [Identify](/docs/segment/connections/spec/identify/). A Mixpanel track doesn't create users in Mixpanel People.
2. Make sure to turn on the "People" setting so that all of your [Identify](/docs/segment/connections/spec/identify/) calls will be sent to Mixpanel's People feature.
3. Make sure you disable the default filter in the Mixpanel People Explore tab.

## Appendices

### Distinct ID

In Device-mode, when a `distinct_id` is present in the browser, it is automatically sent to Mixpanel. In Cloud-mode, the `distinct_id` is set to Segment's `userId` if one is present. If there is no `userId` on the payload, `anonymousId` is set instead.

### Insert ID

`$insert_id` is only available for cloud events. For the Mixpanel (Legacy) destination, Segment generates `$insert_id` from the messageId, event name, and Mixpanel namespace constant using the [uuidv5](https://developer.hashicorp.com/terraform/language/functions/uuidv5) function:

```javascript
const insertId = uuidv5(`${messageId}:${projectId}:${eventName}`, MIXPANEL_NAMESPACE)
```

### IP

If an `ip` property is passed to Mixpanel, the value will be interpreted as the IP address of the request and therefore automatically parsed into Mixpanel geolocation properties (City, Country, Region). After that IP address has been parsed, they will throw out the IP address and only hold onto those resulting geolocation properties. As such, if you want to display an IP address as a property within the Mixpanel UI or within raw data, you will simply want to slightly modify the naming convention for that property.

Instead of `ip`, you can use a property name of `user IP` or `IP Address` (whatever is most clear for your implementation). This way, Mixpanel won't automatically interpret the IP address as an IP address, and instead store that value as a property on the event. You can read more in Mixpanel's [Import Events](https://mixpanel.com/help/reference/http#tracking-events) documentation.

### Bypass "Last Seen" in server-side calls

You can bypass the automatic re-setting of the "Last Seen" date property by passing **active** with a value of `false` in the `context` object, as follows:

```python
analytics.identify(
  user_id='12345',
  traits={
    'name': 'Frank'
  },
  context={
    'active': false
  }
)
```

### Push notifications

Push notifications are only available for projects bundling the Segment-Mixpanel SDK.

> \[!NOTE]
>
> Set up your push notification handlers by calling into native Mixpanel methods. You can read more about how to approach this in the [iOS](/docs/segment/connections/sources/catalog/libraries/mobile/ios/#what-if-your-sdk-doesnt-support-feature-x) and [Android](/docs/segment/connections/sources/catalog/libraries/mobile/android/#how-can-i-use-a-destination-specific-feature) documentation.

### In-app notifications

In-app notifications are only available for projects either bundling the Segment-Mixpanel SDK or using the client-side Web integration. Configure in-app notification handlers by calling into native Mixpanel methods.

> \[!NOTE]
>
> Read more about how to approach this in the [iOS](/docs/segment/connections/sources/catalog/libraries/mobile/ios/#what-if-your-sdk-doesnt-support-feature-x) and [Android](/docs/segment/connections/sources/catalog/libraries/mobile/android/#how-can-i-use-a-destination-specific-feature) documentation.

### A/B testing

> \[!NOTE]
>
> Configure push notification handlers by calling into native Mixpanel methods. You can read more about how to approach this in the [iOS](/docs/segment/connections/sources/catalog/libraries/mobile/ios/#what-if-your-sdk-doesnt-support-feature-x) and [Android](/docs/segment/connections/sources/catalog/libraries/mobile/android/#how-can-i-use-a-destination-specific-feature) documentation.

#### Device connection mode (Bundled Mobile SDK)

Segment supports Mixpanel push notifications automatically using the [didRegisterForRemoteNotificationsWithDeviceToken method](/docs/segment/connections/sources/catalog/libraries/mobile/ios/#how-do-i-use-push-notifications).

For *in-app* notifications and surveys, follow the Mixpanel documentation for [Swift](https://developer.mixpanel.com/docs/swift#in-app-messages). Use the native functionality to control when to show an in-app message by following the instructions in Segment's [iOS](/docs/segment/connections/sources/catalog/libraries/mobile/ios/#what-if-your-sdk-doesnt-support-feature-x) documentation by and calling the native Mixpanel methods.

#### Cloud connection mode (Unbundled/Server-side)

If you use Mixpanel server side and you have access to your users' device tokens, you can import into Mixpanel by sending the token using `context.device.token` as described in the [spec](/docs/segment/connections/spec/common/#context) with an Identify call. Segment sends the token as Mixpanel's special trait `$ios_devices`. This only works on iOS. In order to use push on Android, you must bundle the Mixpanel SDK.

For example, using the [node library](/docs/segment/connections/sources/catalog/libraries/server/node/):

```javascript
analytics.identify({
  userId: '019mr8mf4r',
  traits: {
    name: 'Michael Bolton',
    email: 'mbolton@example.com',
    plan: 'Enterprise',
    friends: 42
  },
  context: {
    device: {
      token: 'ff15bc0c20c4aa6cd50854ff165fd265c838e5405bfeb9571066395b8c9da449'
    }
  }
});
```

### Tracking Mixpanel push notification open rate

To enable push tracking, click the checkbox within Mixpanel as explained in [Mixpanel's documentation](https://mixpanel.com/help/questions/articles/how-do-i-track-push-notification-open-rate). This feature allows push notification opens to be tracked as properties of an app open event, however this will miss pushes which are received when the app is already open.

To add push open tracking, Mixpanel requires that on initialization Mixpanel is launched with options. Segment makes this available through the factory `(instancetype)createWithLaunchOptions:(NSString *)token launchOptions:(NSDictionary *)launchOptions;`

*Note*: Push open tracking in Android is not currently supported by the Mixpanel Android library.

## Using Mixpanel with Engage

Mixpanel is a product analytics platform that is compatible as a Engage destination.

You can send computed traits and audiences created in Engage to Mixpanel and use them to create dashboards, run cohort analyses, or to power messages.

You can set a "lookback window" for both computed traits and audiences, which limits the period of time in which data is considered when calculating the trait or audience. For example, you might set a lookback window of 7 days on an audience or trait like `new_users_7_days`, but you would not add a lookback window to a trait that isn't time-bounded, for example `lifetime_value` .

When you specify a lookback window, Engage updates the audience or trait hourly. If you do not specify a lookback window, Engage continuously updates both computed traits and audiences in real time.

### Using Engage's Computed Traits with Mixpanel

You can send Computed Traits created in Engage to Mixpanel as Identify calls to create user properties in Mixpanel.

![Segment Traits page showing Computed Traits num\_of\_courses\_clicked and total\_courses\_clicked with value 11.](https://docs-resources.prod.twilio.com/10fe52f1dede2bfb37267d610d1d1dd77d25a98857c872909dd63a4c59f08df9.png)

You can check a specific user profile in Mixpanel for Computed Traits by going to **Users → Explore** and search for a specific user to view their profile.

![Mixpanel user profile showing properties and activity feed with email and order details.](https://docs-resources.prod.twilio.com/4289b87db94420597bb72945cfe1cc1503074c056b4cda579a1a8272b1473ef5.png)

Computed traits without a lookback window search across all historical events, and update in real time.

Computed traits with a lookback window only search across events that occurred within the specified time frame. Computed traits *with* a lookback window are updated hourly.

![Configure and Preview Your Trait page with the lookback window set to 7 days.](https://docs-resources.prod.twilio.com/6ae3d13f803ba4684413ef9a6872f1fd19d288744ebedf1c810afc9ee6fef911.png)

If you choose to include anonymous users when you create the computed trait, you must use the [`alias` call](#alias) to merge user profiles when they become a known user.

![A screenshot of the A screenshot of the "Configure and Preview Your Trait" page in Segment, with the "Include anonymous users" box checked.](https://docs-resources.prod.twilio.com/114f2c93ec4c63463b781d210d2c7fe03df6c63bb77de1ac7aba65e0a08ffea3.png)

### Using Engage Audiences with Mixpanel

You can send Engage Audiences to Mixpanel as Identify or Track calls. You can choose the type of call to send when you add Mixpanel as a destination for an audience.

![Mixpanel settings page with API Secret and Use Mixpanel People options.](https://docs-resources.prod.twilio.com/bc59f3949e6b6a00ed183742923e1085b5a782a449ad53f8a5122346de7456cf.png)

When you send custom traits as Identify calls, the name of the audience is added to the user's profile as a user trait, with a boolean value to indicate if the user is in the audience. For example, when a user first completes an order in the last 30 days, Segment sends an Identify call with the property `order_completed_last_30days: true`. When this user no longer satisfies these criteria (for example when their last purchase was more than 30 days ago) Engage sets that value to `false`.

![Configure and Preview Your Trait page with the Include anonymous users setting highlighted.](https://docs-resources.prod.twilio.com/a264b7d3efc280523474ace2c6119cb921e33aad9a81be2fa63c769813533632.png)

You can check a specific user profile in Mixpanel for Computed Traits by going to **Users → Explore** and searching for a specific user to view their profile.

![A screenshot of a user in Mixpanel, with a box around a custom trait.](https://docs-resources.prod.twilio.com/803be6bb557a933b467b3f09b0f61b4ab3102e4d7922d1f1f345f2c5e81074f7.png)

When you first create an audience, Engage sends an Identify call for every user in the audience. Later syncs only send updates for users who were added or removed from the audience since the last sync.

When you use Track calls, Segment sends an `Audience Entered` event when the user enters the audience, with the audience name as a property of the event. When the user exits the audience, Engage sends an `Audience Exited` event with the same property.

![Events tab for example Segment user, Sherry Bobbins, showing 'Audience Entered' data at 1:12 pm.](https://docs-resources.prod.twilio.com/27c915b005c87a2ba55e8a9d0dc3ded640b3234781e7936d1ea27bdde5adaf9d.png)

You can check a specific user profile in Mixpanel for audience events by going to **Users → Explore** and searching for a specific user to view their profile. Look for `Audience Entered` and `Audience Exited` events in the Activity Feed.

![A screenshot of a user profile in Mixpanel, with the Properties tab selected.](https://docs-resources.prod.twilio.com/41d82a24a513295dea99c066483f75bbae86364c9635984da3f7bfb38f77d840.png)

Audiences without a lookback window searches across all historical events and update in real time.

Audiences with a lookback window only search across events that occurred within the specified time frame. Audiences *with* a lookback window are updated hourly.

![A screenshot of the Configure and Preview Your Audience page in Segment.](https://docs-resources.prod.twilio.com/6df60afff8f56d5d62f28b12488383ed99489c7f42cd3e9a65083fcb71b07821.png)

If you choose to include anonymous users when you create an audience, you must use the [alias call](#alias) to merge user profiles when they become a known user.

![A screenshot of the Configure and Preview Your Audience page in Segment, with an line under the Include anonymous users setting.](https://docs-resources.prod.twilio.com/cf3ecea068fbf1d35909cc8173a36efd2451dec6c1eb47bb74dd21348cda5c84.png)

## Setting Up Engage and Mixpanel

To send computed traits or audiences to Mixpanel, connect the destination to your Space. Once it's set up, you can select Mixpanel as a destination for Engage data when you create computed traits or audiences.

1. In your Segment workspace, click Engage in the left navigation bar, and select your Space.
2. Click **Engage Settings** and select the **Destinations** tab.
3. Click **Add Destination**.
4. Search for Mixpanel and click add destination.
5. Enter your API Secret and Token for the integration.
6. Enable the "Use Mixpanel People" toggle. This allows Engage to send Identify calls to Mixpanel.

> \[!NOTE]
>
> Mixpanel now accepts Identify calls by default. Previously, this was an additional paid feature.

![A screenshot of the settings page for the Mixpanel destination.](https://docs-resources.prod.twilio.com/4048ef268ee8175437bdd74681aba673ce1a4c088655a3149e243e8bd1d7282d.png)

## Mixpanel Engage Details

* **Supports Engage**: Yes
* **Engage Destination type**: Event Method (data is delivered to this Destination one-by-one on a realtime basis)
* **Traits and Audiences created by**: Traits and audiences are added as user properties using Identify calls. You can send Audiences as `Audience Entered` or `Audience Exited track` calls with the audience name as an event property.
* **Must create audience\_name field before Engage can update those values?**: No. If sent as an Identify call, Engage auto-creates the computed trait or audience name as a user property.
* **Audience appears as**:
  * Computed traits appear as a lower case user property with spaces converted to underscores.
  * For audiences sent as an Identify call, Engage creates a lower case boolean (true/false) user property. Spaces are converted to underscores.
  * For audiences sent as a Track call, Engage sends `Audience Entered` and `Audience Exited` events with the audience name as an event property.
* **Destination rate limit**: [None](https://help.mixpanel.com/hc/en-us/articles/115004602563-Rate-Limits-for-API-Endpoints#track-and-engage-endpoints)
* **Lookback window allowed**: Yes, unlimited.
* **Identifiers required** : `userId` or `anonymousId`
* **Identifiers accepted** : `userId` or `anonymousId`
* **Client or Server-Side Connection**: Server-side

## Mixpanel Engage FAQs

**What happens if I delete an audience or trait in Segment?**

If you delete an audience or trait in Segment, it isn't deleted from Mixpanel. To remove an audience-created property in Mixpanel, you must use either [the Mixpanel Engage API using the $unset method or hide user properties from the Lexicon](https://help.mixpanel.com/hc/en-us/articles/115004567926-Hide-or-Delete-Events-Properties-Users).

**If a user has multiple external ids in Segment, what happens when they enter an audience or have a computed trait?**

Segment sends an Identify or a Track call for each external on the user's account. For example, if a user has three email addresses, and you are sending Identify calls for your audience, Engage sends three Identify calls to Mixpanel and adds the latest email address to the user profile as the email "address of record" on the Mixpanel user profile.

**What happens if I receive a `Timestamp must be within the last 5 years` error, and my timestamp displays `1970-01-01`?**

The Segment PHP Library (2.1.0) version requires a UNIX timestamp. If you send anything other than a UNIX timestamp, Segment converts this to the `1970-01-01` timestamp. If you're experiencing failed events due to this error and you have a connected PHP source, update your PHP Library version to 2.1.0.

## Settings

Segment lets you change these destination settings from the Segment app without having to touch any code.

| Field                                                                  | Description                                                                                                                                                                                                                                                                                                              | Required | Type    |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ------- |
| API Secret                                                             | You can find your API Secret under \*\*Settings > Project Settings\*\* in the upper right of the \[Mixpanel interface]\(https://mixpanel.com).                                                                                                                                                                           | No       | string  |
| Track All Pages to Mixpanel with a Consolidated Event Name             | This will track \*\*Loaded a Page\*\* events to Mixpanel for all \[\`page\` method]\(/docs/segment/connections/sources/catalog/libraries/website/javascript/#page) calls and \*\*Loaded a Screen\*\* events for all \[\`screen\` method]\(/docs/segment/connections/sources/catalog/libraries/mobile/ios/#screen) calls. | No       | boolean |
| Cross Subdomain Cookie                                                 | This will allow the Mixpanel cookie to persist between different pages of your application.                                                                                                                                                                                                                              | No       | boolean |
| Enable European Union Endpoint                                         | Enable this setting to send your events to Mixpanel's \[EU endpoint]\(https://developer.mixpanel.com/docs/privacy-security#storing-your-data-in-the-european-union). In Mixpanel, be sure to enable Data Residency under Project Settings > Set up Mixpanel > Data Residency.                                            | No       | boolean |
| Events to increment in People                                          | If you want to see and segment by event counts and last event date in Mixpanel people, you will need to:&#xA;1\. Enable the "Use Mixpanel People" setting.&#xA;2\. List the events you want to see in People here.                                                                                                       | No       | array   |
| Group Identifier Traits                                                | What trait Segment should use as your Mixpanel "group key" in group calls. If, for example, you set this to be \`company\`, then "company" will be sent as \`group\_key\` and the value of \`traits\["company"]\` will be sent as the \`group\_id\`.                                                                     | No       | array   |
| Group Traits to Set Once                                               | Group traits to be set only once using Mixpanel's \`$set\_once\` operator.                                                                                                                                                                                                                                               | No       | array   |
| Legacy Super  Properties                                               | We used to add $ to mixpanel traits as super properties. Enable this if you would like to use the legacy behavior.                                                                                                                                                                                                       | No       | boolean |
| Use Mixpanel People                                                    | This will send all of your \[identify]\(/docs/segment/connections/spec/identify/) calls to Mixpanel's People feature.                                                                                                                                                                                                    | No       | boolean |
| Traits to set as People Properties                                     | If you only want to set specific traits as People Properties in Mixpanel People, you will need to:&#xA;- Enable the "Use Mixpanel People" setting.&#xA;- List the traits you want to see in People here.                                                                                                                 | No       | array   |
| Persistence Type                                                       | This will allow the Mixpanel cookie to persist between different pages of your application.                                                                                                                                                                                                                              | No       | select  |
| Properties to increment in People                                      | If you want to see and segment by event counts and last event date in Mixpanel people, enable people, and then list the events you want to see in People here.                                                                                                                                                           | No       | array   |
| Secure Cookie                                                          | This will mark the Mixpanel cookie as secure, meaning it will only be transmitted over https                                                                                                                                                                                                                             | No       | boolean |
| Automatically set all Traits as Super Properties and People Properties | While this is checked, our integration automatically sets all traits on identify calls as super properties and people properties if Mixpanel People is checked as well.                                                                                                                                                  | No       | boolean |
| Source Name                                                            | This value, if it's not blank, will be sent as \`segment\_source\_name\` to Mixpanel for every \`event\`/\`page\`/\`screen\` call.                                                                                                                                                                                       | No       | string  |
| Properties to send as Super Properties                                 | If you want to see and segment by Super Properties in Mixpanel, then list the properties you want to see as Super Properties here.                                                                                                                                                                                       | No       | array   |
| Token                                                                  | You can find your token under \*\*Account\*\* in the upper-right of the \[Mixpanel interface]\(https://mixpanel.com).                                                                                                                                                                                                    | Yes      | string  |
| Track All Pages to Mixpanel                                            | This will track \*\*Loaded a Page\*\* events to Mixpanel for all \[\`page\` method]\(/docs/segment/connections/sources/catalog/libraries/website/javascript/#page) calls. We keep this disabled by default.                                                                                                              | No       | boolean |
| Track Categorized Pages to Mixpanel                                    | This will track events to Mixpanel for \[\`page\` method]\(/docs/segment/connections/sources/catalog/libraries/website/javascript/#page) calls that have a \`category\` associated with them. For example \`page('Docs', 'Index')\` would translate to \*\*Viewed Docs Index Page\*\*.                                   | No       | boolean |
| Track Named Pages to Mixpanel                                          | This will track events to Mixpanel for \[\`page\` method]\(/docs/segment/connections/sources/catalog/libraries/website/javascript/#page) calls that have a \`name\` associated with them. For example \`page('Signup')\` would translate to \*\*Viewed Signup Page\*\*.                                                  | No       | boolean |
