Mixpanel Connector
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:
- A Mixpanel account with a project created
- Your Mixpanel Project Token for client-side tracking
- A Service Account with appropriate permissions for server-side API access
- A Brevo account with API access
- 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).
# Service Account authenticationcurl 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:
// Client-side initializationmixpanel.init("YOUR_PROJECT_TOKEN");OAuth (for Partner Integrations)
For app integrations that access multiple projects:
curl https://mixpanel.com/api/2.0/engage \ -H "Authorization: Bearer YOUR_OAUTH_TOKEN"Configuration
Basic Setup
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: 17Event Mapping
Map Mixpanel events to Brevo event types:
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:
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: LTVAPI 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
import { TajoClient } from '@tajo/sdk';
const tajo = new TajoClient({ apiKey: process.env.TAJO_API_KEY, brevoApiKey: process.env.BREVO_API_KEY});
// Connect Mixpanel projectawait 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
// 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
// Export a Mixpanel cohort and sync to a Brevo listconst 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
// Set user properties via the Engage APIconst 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: { $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
- Use Service Accounts - Prefer Service Accounts over Project Secret for server-side authentication
- Include
$insert_id- Always set a unique insert ID for event deduplication - Batch profile updates - Send up to 2,000 profile updates per request for efficiency
- Use EU endpoints - For EU data residency, use
api-eu.mixpanel.comfor all API calls - Sync cohorts on schedule - Set up daily or weekly cohort sync rather than continuous polling
- Map reserved properties - Use Mixpanel’s reserved properties (
$email,$first_name) for profile data - 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_idprevents 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
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 | 9afa1de | png (1283), mdx (406), Markdown (164), gif (97), YAML (82), TypeScript (71) | 2237 |
Integration Shape
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.