---
title: "Mixpanel Connector"
description: "Complete Mixpanel integration guide for syncing product analytics events, user profiles, and cohorts with Brevo through Tajo."
url: https://tajo.io/docs/connectors/custom/mixpanel/
markdown: https://tajo.io/docs/connectors/custom/mixpanel.md
lang: en-US
robots: noindex
---

# Mixpanel Connector

Connector status: Planned Not built yet. Tajo does not run this connector today.

| Source field | Destination field | Sample value |
| --- | --- | --- |
| `record.id` | `source_id` | `record_1042` |
| `record.updated_at` | `updated_at` | `2026-10-18T08:00:00Z` |
| `record.value` | `value` | `sample_value` |

Connect Mixpanel to Brevo through Tajo to bridge product analytics with marketing automation. Sync user profiles, behavioral events, and cohorts to create data-driven campaigns based on real product usage.

## Overview

| Property | Value |
| --- | --- |
| **Platform** | Mixpanel |
| **Category** | Analytics (Custom) |
| **Setup Complexity** | Medium |
| **Official Integration** | No |
| **Data Synced** | Events, Profiles, Cohorts, Groups |
| **Available Skills** | 7 |

## Features

- **Event ingestion** - Import track events via Mixpanel’s Ingestion API into Brevo workflows
- **User profile sync** - Map Mixpanel user profile properties to Brevo contact attributes
- **Cohort export** - Sync Mixpanel cohorts to Brevo contact lists for targeted campaigns
- **Group analytics** - Sync group-level data for B2B account-based marketing
- **Identity management** - Leverage Mixpanel’s identity merge for unified customer profiles
- **JQL queries** - Run custom JQL queries to extract specific data sets for Brevo
- **Lookup tables** - Sync enrichment data from Mixpanel lookup tables

## Prerequisites

Before you begin, ensure you have:

1. A Mixpanel account with a project created
2. Your Mixpanel Project Token for client-side tracking
3. A Service Account with appropriate permissions for server-side API access
4. A Brevo account with API access
5. A Tajo account with API credentials

## Authentication

### Service Accounts (Recommended)

Mixpanel recommends using Service Accounts for API authentication. Service accounts use HTTP Basic Auth with username (service account username) and password (service account secret).

```bash
# Service Account authentication
curl https://mixpanel.com/api/app/me \
  -u "SERVICE_ACCOUNT_USERNAME:SERVICE_ACCOUNT_SECRET"
```

### Project Token

The Project Token is used for client-side event tracking and is safe to include in client code:

```javascript
// Client-side initialization
mixpanel.init("YOUR_PROJECT_TOKEN");
```

### OAuth (for Partner Integrations)

For app integrations that access multiple projects:

```bash
curl https://mixpanel.com/api/2.0/engage \
  -H "Authorization: Bearer YOUR_OAUTH_TOKEN"
```

## Configuration

### Basic Setup

```yaml
connectors:
  mixpanel:
    enabled: true
    project_token: "your-project-token"
    service_account:
      username: "your-service-account-username"
      secret: "your-service-account-secret"
    project_id: "12345"
    data_residency: "US"  # or "EU"

    # Data sync options
    sync:
      events: true
      profiles: true
      cohorts: true
      groups: false

    # Brevo list assignment
    lists:
      all_users: 15
      engaged_users: 16
      at_risk: 17
```

### Event Mapping

Map Mixpanel events to Brevo event types:

```yaml
event_mapping:
  # Mixpanel event -> Brevo event
  "Purchase": "order_completed"
  "Sign Up": "customer_created"
  "Add to Cart": "cart_updated"
  "Page View": "page_viewed"
  "$experiment_started": "experiment_started"

  # Custom events
  "Feature Activated": "feature_used"
  "Subscription Renewed": "subscription_renewed"
```

### Profile Property Mapping

Map Mixpanel user properties to Brevo contact attributes:

```yaml
property_mapping:
  $email: email
  $first_name: FIRSTNAME
  $last_name: LASTNAME
  $phone: SMS
  $city: CITY
  $region: REGION
  $country_code: COUNTRY
  plan: PLAN_TYPE
  company: COMPANY
  signup_date: SIGNUP_DATE
  total_revenue: LTV
```

## API Endpoints

| Method | Endpoint | Description |
| --- | --- | --- |
| `POST` | `/import` | Import events (Ingestion API) |
| `POST` | `/track` | Track events (client-side) |
| `POST` | `/engage#$set` | Set user profile properties |
| `POST` | `/engage#$set_once` | Set properties only if not already set |
| `POST` | `/engage#$delete` | Delete a user profile |
| `POST` | `/engage#$union` | Union to list properties |
| `POST` | `/groups` | Set group profile properties |
| `GET` | `/export` | Export raw event data |
| `POST` | `/cohorts/list` | List saved cohorts |
| `POST` | `/engage/query` | Query user profiles |
| `POST` | `/jql` | Run custom JQL queries |
| `GET` | `/segmentation` | Query segmentation reports |
| `GET` | `/retention` | Query retention reports |
| `GET` | `/funnels` | Query funnel reports |

## Code Examples

### Initialize Mixpanel Connector

```javascript
import { TajoClient } from '@tajo/sdk';

const tajo = new TajoClient({
  apiKey: process.env.TAJO_API_KEY,
  brevoApiKey: process.env.BREVO_API_KEY
});

// Connect Mixpanel project
await tajo.connectors.connect('mixpanel', {
  projectToken: process.env.MIXPANEL_TOKEN,
  serviceAccountUser: process.env.MIXPANEL_SA_USER,
  serviceAccountSecret: process.env.MIXPANEL_SA_SECRET,
  projectId: process.env.MIXPANEL_PROJECT_ID
});
```

### Import Events via Ingestion API

```javascript
// Import events to Mixpanel (automatically forwarded to Brevo)
const response = await fetch('https://api.mixpanel.com/import', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + btoa(
      `${process.env.MIXPANEL_SA_USER}:${process.env.MIXPANEL_SA_SECRET}`
    )
  },
  body: JSON.stringify([
    {
      event: "Purchase",
      properties: {
        distinct_id: "user_123",
        $insert_id: "evt_abc123",
        time: Math.floor(Date.now() / 1000),
        revenue: 89.99,
        product_id: "SKU-001",
        product_name: "Widget Pro"
      }
    }
  ])
});

// Expected response: { "code": 200, "status": "OK", "num_records_imported": 1 }
```

### Sync Cohort to Brevo

```javascript
// Export a Mixpanel cohort and sync to a Brevo list
const cohort = await tajo.connectors.syncCohort('mixpanel', {
  cohortId: 12345,
  targetList: 16,
  syncMode: 'mirror'
});

console.log(cohort);
// {
//   cohortName: "Engaged Users (Last 7 Days)",
//   membersCount: 3200,
//   syncedToBrevo: 3200,
//   listId: 16
// }
```

### Set User Profile Properties

```javascript
// Set user properties via the Engage API
const response = await fetch('https://api.mixpanel.com/engage#$set', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify([{
    $token: process.env.MIXPANEL_TOKEN,
    $distinct_id: "user_123",
    $set: {
      $email: "jane@example.com",
      $first_name: "Jane",
      $last_name: "Kim",
      plan: "premium",
      total_orders: 12,
      lifetime_value: 1250.00
    }
  }])
});
```

## Rate Limits

| API | Limit | Details |
| --- | --- | --- |
| **Ingestion API** | 2 GB/min | Per project |
| **Track API** | No hard limit | Best-effort delivery |
| **Engage API** | 2,000 updates/batch | Max 2 GB/min per project |
| **Query API** | 60 requests/hour | Per project (Service Account) |
| **Export API** | 60 requests/hour | Max 100 days per query |
| **JQL API** | 60 requests/hour | Per project |
| **Cohort Export** | 60 requests/hour | Per project |

Event Deduplication

Mixpanel deduplicates events using the `$insert_id` property. Always include a unique `$insert_id` to prevent duplicate events when retrying failed imports.

## Troubleshooting

| Issue | Cause | Solution |
| --- | --- | --- |
| Events not appearing | Wrong project token | Verify token matches the target project |
| Profile properties missing | Using wrong API | Use `/engage#$set` for profile properties, not `/track` |
| Cohort export fails | Insufficient permissions | Ensure Service Account has Admin or Analyst role |
| Duplicate events | Missing `$insert_id` | Include unique `$insert_id` on every event |
| 402 Payment Required | Over data limits | Check Mixpanel plan limits and upgrade if needed |
| EU data not routing | Wrong data residency | Use `api-eu.mixpanel.com` for EU projects |
| Identity merge issues | Incorrect distinct\_id | Follow Mixpanel’s identity management best practices |

## Best Practices

1. **Use Service Accounts** - Prefer Service Accounts over Project Secret for server-side authentication
2. **Include `$insert_id`** - Always set a unique insert ID for event deduplication
3. **Batch profile updates** - Send up to 2,000 profile updates per request for efficiency
4. **Use EU endpoints** - For EU data residency, use `api-eu.mixpanel.com` for all API calls
5. **Sync cohorts on schedule** - Set up daily or weekly cohort sync rather than continuous polling
6. **Map reserved properties** - Use Mixpanel’s reserved properties (`$email`, `$first_name`) for profile data
7. **Monitor ingestion** - Use Mixpanel’s Events page to verify events are being received correctly

## Security

- **HTTPS only** - All API communication requires TLS encryption
- **Service Account isolation** - Scoped access per project with role-based permissions
- **Event deduplication** - Built-in dedup via `$insert_id` prevents data integrity issues
- **SOC 2 Type II** - Mixpanel is SOC 2 Type II certified
- **GDPR/CCPA** - Supports user data deletion via the GDPR API
- **EU data residency** - EU data center available for European compliance

## Related Resources

- [Segment Connector](https://tajo.io/docs/connectors/custom/segment)
- [Amplitude Connector](https://tajo.io/docs/connectors/custom/amplitude)
- [Customer Sync Skill](https://tajo.io/docs/skills/data-sync/customer-sync)
- [Brevo Events API](https://tajo.io/docs/events-engagement/create-event)

## Open-Source Implementation Map

This section is derived from official or public repository material discovered for the Mixpanel connector. Use it as the engineering companion to the setup guide above: it shows where the API surface lives, what implementation assets exist, and how Tajo should translate them into reliable Brevo sync behavior.

### Repository Snapshot

| Repository | Commit | Languages / formats | Files |
| --- | --- | --- | --- |
| [mixpanel/docs](https://github.com/mixpanel/docs) | 9afa1de | png (1283), mdx (406), Markdown (164), gif (97), YAML (82), TypeScript (71) | 2237 |

### Integration Shape

```mermaid
graph LR
  Source["Mixpanel API / repository"] --> Auth["Auth and scopes"]
  Source --> Objects["Objects, events, and schemas"]
  Auth --> Tajo["Tajo connector runtime"]
  Objects --> Tajo
  Tajo --> Brevo["Brevo contacts, attributes, lists, campaigns"]
  Tajo --> Ops["Backfill, cursor, retries, logs"]
```

### What To Reuse

- Mixpanel’s Official Documentation
- docs.mixpanel.com
- If you see something off with Mixpanel’s docs (typo, broken link, outdated content/screenshot) you can contribute that fix yourself!
- Contributing Fixes
- You’ll need a GitHub account. It’s free and takes 1 minute to create. Not sure what to make your handle? We recommend ‘yourfullname-mixpanel’.

### Tajo Revamp Checklist

- Keep authentication setup aligned with the vendor docs and the public repository’s current API shape.
- Map primary resources into explicit Tajo sync objects with stable external IDs.
- Prefer cursor-based or updated-at incremental sync where the API exposes it; otherwise document the fallback.
- Treat webhook handlers as idempotent and replay-safe, especially for order, contact, ticket, and campaign events.
- Capture pagination, rate limits, retry headers, and partial-failure behavior in connector smoke tests.
- Keep examples small and runnable against sandbox or test-mode accounts.

### Sources

- [mixpanel/docs](https://github.com/mixpanel/docs)
- [Vendor documentation](https://developer.mixpanel.com/reference/overview)
