Skip to main content
RapidDev - Software Development Agency
flutterflow-integrationsFlutterFlow API Call

Mixpanel

Connect FlutterFlow to Mixpanel by creating a FlutterFlow API Call that POSTs events to Mixpanel's /track endpoint. Store your public project token in App Constants, build the base64-encoded event body inside an API Group, and fire it from On Page Load or On Tap triggers. The service account secret stays in a Cloud Function — never in your Dart app.

What you'll learn

  • How to create a Mixpanel API Group in FlutterFlow with the correct base64-encoded body shape
  • Why the project token is safe in App Constants but the service account secret must stay in a Cloud Function
  • How to fire Mixpanel events from On Page Load and On Tap triggers using the authenticated user's distinct_id
  • How to verify events in Mixpanel's Live View and debug silent 200-OK failures
  • How to avoid CORS failures on FlutterFlow web builds using FF's built-in proxy
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate16 min read45 minutesAnalyticsLast updated July 2026RapidDev Engineering Team
TL;DR

Connect FlutterFlow to Mixpanel by creating a FlutterFlow API Call that POSTs events to Mixpanel's /track endpoint. Store your public project token in App Constants, build the base64-encoded event body inside an API Group, and fire it from On Page Load or On Tap triggers. The service account secret stays in a Cloud Function — never in your Dart app.

Quick facts about this guide
FactValue
ToolMixpanel
CategoryAnalytics
MethodFlutterFlow API Call
DifficultyIntermediate
Time required45 minutes
Last updatedJuly 2026

Why Add Mixpanel to Your FlutterFlow App?

FlutterFlow includes built-in Firebase Analytics for basic event logging, but Mixpanel gives you a different layer of insight: user-level funnels, cohort analysis, retention curves, and A/B experiment results — all built around a specific user identity rather than aggregate session counts. If you want to understand why users drop off between your onboarding screen and your first paid action, Mixpanel is the tool that surfaces that.

The integration mechanics differ from a web app. Mixpanel's browser JavaScript SDK cannot run inside a compiled Flutter app — your FlutterFlow project compiles to Dart code running natively on iOS, Android, or in a browser via Flutter Web. The reliable path is a FlutterFlow API Group that POSTs events directly to Mixpanel's HTTP ingestion endpoint (`https://api.mixpanel.com/track`). This approach works on all platforms, requires no pub.dev packages, and is free on both FlutterFlow and Mixpanel's free tier.

Mixpanel splits its auth into two parts: the **project token** (a public identifier safe to ship in your app — think of it like a publishable API key) and the **service account** user-and-secret pair (used only for server-side queries like exporting cohorts or running funnel queries). The project token belongs in FlutterFlow's App Constants; the service account secret belongs in a Firebase Cloud Function. Never combine them in the same place, and never put the service account secret in an API Call header — it would ship inside your compiled APK or web bundle.

Integration method

FlutterFlow API Call

FlutterFlow sends events to Mixpanel by POSTing to the /track ingestion endpoint using a FlutterFlow API Group. The project token is public and safe to store in App Constants; the call fires from Action Flows on any user interaction or page load. For richer session tracking, the mixpanel_flutter pub.dev SDK can be wrapped in a Custom Action.

Prerequisites

  • A FlutterFlow project on any paid plan (Starter or above) with a published app or active Test Mode
  • A Mixpanel account with a project created — free tier is sufficient to start
  • Your Mixpanel project token (found in Project Settings → Project Token — it is public, not a secret)
  • Basic familiarity with FlutterFlow's Action Flow Editor and App State variables
  • If using the Custom Action path: FlutterFlow Basic plan or above for Custom Code access

Step-by-step guide

1

Create a Mixpanel project and copy the project token

Open mixpanel.com and sign in or create a free account. Click 'Create Project' in the top-left dropdown, give it a name that matches your FlutterFlow app (e.g. 'MyApp Production'), and select your data region (US or EU). Once the project is created, click the settings gear in the bottom-left corner → 'Project Settings'. Near the top of the General tab you will see 'Project Token' — a short alphanumeric string like `abc123def456`. Copy this token. This is a **public** identifier, not a secret: it cannot be used to read your data, only to write events into your project. It is safe to store in your FlutterFlow app. While you are here, also note the 'API Secret' field below it — that is the service account credential used for server-side queries (exporting cohorts, running saved reports via the Query API). You will NOT put that value in FlutterFlow. Keep the Mixpanel browser tab open for verification in Step 5.

Pro tip: If you are building a multi-environment setup (development vs production), create two Mixpanel projects and store the appropriate token per environment in FlutterFlow's App Constants.

Expected result: You have a Mixpanel project token copied to your clipboard and the Mixpanel Live View tab open and waiting.

2

Store the project token in FlutterFlow App Constants

In FlutterFlow, click the settings gear in the bottom-left navigation panel and select 'App Constants' (also accessible via Settings → App Values in some FlutterFlow versions). Click '+ Add Constant', name it `mixpanelToken` (camelCase, no spaces), set the type to String, and paste your project token as the value. Click Save. App Constants are compiled into the app bundle at build time — they are appropriate for publishable keys like this project token. Do not add the Mixpanel API Secret here. Constants are visible in the compiled binary, which is intentional for ingestion tokens (Mixpanel's ingestion API is designed to accept calls with only the public token), but it would be a serious credential leak for a service account secret. After saving, you can reference this constant anywhere in FlutterFlow as `FFAppConstants.mixpanelToken` in Dart, or via the variable picker in the Action Flow Editor under App Constants → mixpanelToken.

Pro tip: App Constants are different from App State: Constants are set at build time and never change at runtime. App State variables can change as users interact with your app. Use Constants for API credentials.

Expected result: A constant named 'mixpanelToken' appears in the App Constants list with your token value saved.

3

Create the Mixpanel API Group and /track POST call

Click 'API Calls' in the left navigation panel of FlutterFlow. Click '+ Add' → 'Create API Group'. Name the group 'Mixpanel' and set the base URL to `https://api.mixpanel.com`. Click 'Add Call' to add the first endpoint. Name this call 'Track Event'. Set the method to POST and the endpoint path to `/track`. The Mixpanel /track endpoint accepts a `data` parameter carrying a base64-encoded JSON payload — this is Mixpanel's legacy ingestion format. Under the 'Body' tab, select 'Form URL Encoded' (not JSON) and add a single key-value pair: key = `data`, value = a variable you will define next. Switch to the Variables tab and add the following variables: `eventName` (String), `distinctId` (String), and `tokenValue` (String — you will pass the App Constant here at call time). These three variables will be combined in a custom function to build the base64 payload. For now, add a fourth variable named `encodedPayload` (String) to hold the pre-encoded value. In the Body section, set the `data` form field to reference the `encodedPayload` variable using the `{{encodedPayload}}` syntax. Under the Response & Test tab, paste a sample Mixpanel success response (`1`) and click 'Get Response Fields' — Mixpanel /track returns just `1` (success) or `0` (failure), so the response binding will be minimal. Save the API group.

mixpanel_api_call_config.json
1{
2 "group_name": "Mixpanel",
3 "base_url": "https://api.mixpanel.com",
4 "call_name": "Track Event",
5 "method": "POST",
6 "endpoint": "/track",
7 "body_type": "form_url_encoded",
8 "body_params": {
9 "data": "{{encodedPayload}}"
10 },
11 "variables": [
12 { "name": "encodedPayload", "type": "String" },
13 { "name": "eventName", "type": "String" },
14 { "name": "distinctId", "type": "String" }
15 ]
16}

Pro tip: Mixpanel's /track endpoint returns HTTP 200 with body '1' on success and '0' on failure — a 200 status alone does not confirm the event was ingested. Always check Live View to confirm.

Expected result: The Mixpanel API Group appears in your API Calls list with a Track Event POST call configured.

4

Build the base64-encoded event payload in a Custom Function

Mixpanel's /track endpoint requires the event data to be a base64-encoded JSON string passed as the `data` form parameter. FlutterFlow cannot do base64 encoding inline in an Action Flow, so you need a small Custom Function. Click 'Custom Code' in the left nav → '+ Add' → 'Function'. Name it `buildMixpanelPayload`. Set the return type to String. Add three arguments: `eventName` (String), `distinctId` (String), and `token` (String). Paste the Dart code below into the function body. This function constructs the Mixpanel event JSON object, converts it to a string, and base64-encodes it — exactly what the /track endpoint expects. Click Save and Compile. After compiling successfully, this function will be available in your Action Flows under the 'Custom Functions' section of the variable picker. To wire everything together: select any widget (e.g., a button), open its Actions panel, click '+ Add Action' → 'Custom Action' (or 'Custom Function'). First, call `buildMixpanelPayload` with your event name, the current user's UID from App State (`currentUserUid`), and `FFAppConstants.mixpanelToken`. Store the return value in a local page variable named `encodedPayload`. Then add a second action: 'Backend/API Call' → Mixpanel → Track Event, passing the `encodedPayload` variable into the `encodedPayload` API variable.

custom_function.dart
1// FlutterFlow Custom Function: buildMixpanelPayload
2// Return type: String
3// Arguments: eventName (String), distinctId (String), token (String)
4
5import 'dart:convert';
6
7String buildMixpanelPayload(
8 String eventName,
9 String distinctId,
10 String token,
11) {
12 final Map<String, dynamic> event = {
13 'event': eventName,
14 'properties': {
15 'token': token,
16 'distinct_id': distinctId,
17 'time': DateTime.now().millisecondsSinceEpoch ~/ 1000,
18 'mp_lib': 'flutterflow',
19 },
20 };
21 final String jsonString = jsonEncode(event);
22 return base64Encode(utf8.encode(jsonString));
23}

Pro tip: The `time` property is optional but recommended — it timestamps the event on the client side so Mixpanel displays the correct time even if there is network latency.

Expected result: The `buildMixpanelPayload` function compiles successfully and appears under Custom Code → Functions.

5

Bind the event call to On Page Load and On Tap triggers

Now connect the Mixpanel call to real user actions. For a page-view event: click on the page background in FlutterFlow (not any widget) → open the Actions panel on the right → scroll to 'On Page Load' → click '+ Add Action'. Add the two-step sequence: (1) call `buildMixpanelPayload` with event name 'page_viewed', distinctId from `currentUserUid` App State variable, and token from `FFAppConstants.mixpanelToken` — store result in a local variable; (2) call the Mixpanel Track Event API with that stored value. For button taps: select the button widget → Actions panel → On Tap → same two-step sequence, but pass the relevant event name like 'button_tapped' or your custom event name. For the `distinct_id`, use the FlutterFlow authenticated user ID. If you are using FlutterFlow's built-in authentication (Firebase Auth or Supabase), the current user UID is available in App State as `currentUserUid`. If your app has guest users, generate a UUID on first launch using the `uuid` package in a Custom Action, store it in App State, and use that as the distinct_id — this ensures you can link anonymous sessions to identified users after login using Mixpanel's `$identify` call. Go to Mixpanel's Live View (your project → 'Live View' in the left sidebar) and run your FlutterFlow app in Test Mode. Tap the button or navigate to the page. Within a few seconds, the event should appear in Live View with the event name, timestamp, and properties. If it appears, your integration is working.

Pro tip: Use Mixpanel's Live View — not the main Events report — for real-time testing. The Events report has a data lag of several minutes to hours.

Expected result: Events appear in Mixpanel's Live View within seconds of triggering them in the FlutterFlow Test Mode app.

6

Handle CORS on web builds and proxy server-side queries

If you publish your FlutterFlow app to the web (not just native iOS/Android), browsers enforce CORS and Mixpanel's /track endpoint does not include the `Access-Control-Allow-Origin` header for arbitrary origins. You will see a `XMLHttpRequest error` in the browser console when the API Call fires on a web build. Two options: (1) Enable FlutterFlow's built-in API proxy — in the API Calls panel, open the Mixpanel group, toggle on 'Use FlutterFlow Proxy'. This routes your call through FlutterFlow's servers, adding the necessary headers. This is the easiest fix. (2) Route through a Firebase Cloud Function that makes the Mixpanel call server-side and returns the result to your FlutterFlow API Call. For server-side Mixpanel queries (exporting cohorts, running the Query API for funnel results) you need your Mixpanel service account credentials (user and secret). These MUST live in a Firebase Cloud Function — never in FlutterFlow. In the Cloud Function, use HTTP Basic Auth with the service account user as the username and the secret as the password when calling `https://mixpanel.com/api/2.0/...` endpoints. Your FlutterFlow app calls your Cloud Function URL, not Mixpanel directly. RapidDev's team sets up FlutterFlow + Mixpanel integrations like this every week — if you want a custom funnel dashboard built without writing Cloud Functions yourself, a free scoping call is at rapidevelopers.com/contact.

index.js
1// Firebase Cloud Function proxy for Mixpanel Query API
2// File: functions/index.js
3const functions = require('firebase-functions');
4const axios = require('axios');
5
6exports.mixpanelQuery = functions.https.onCall(async (data, context) => {
7 // Verify the caller is authenticated
8 if (!context.auth) {
9 throw new functions.https.HttpsError('unauthenticated', 'Must be signed in.');
10 }
11
12 const { endpoint, params } = data;
13 const serviceUser = process.env.MIXPANEL_SERVICE_USER;
14 const serviceSecret = process.env.MIXPANEL_SERVICE_SECRET;
15
16 const credentials = Buffer.from(`${serviceUser}:${serviceSecret}`).toString('base64');
17
18 try {
19 const response = await axios.get(
20 `https://mixpanel.com/api/2.0/${endpoint}`,
21 {
22 headers: { Authorization: `Basic ${credentials}` },
23 params,
24 }
25 );
26 return response.data;
27 } catch (error) {
28 throw new functions.https.HttpsError('internal', error.message);
29 }
30});

Pro tip: Store MIXPANEL_SERVICE_USER and MIXPANEL_SERVICE_SECRET as Firebase environment variables using the Firebase CLI, not hardcoded in the function source.

Expected result: Web builds send events without CORS errors; server-side query calls work through the Cloud Function with the service account credentials secured.

Common use cases

SaaS app that tracks feature adoption per user

A FlutterFlow SaaS app fires a Mixpanel 'Feature Used' event every time a user activates a core feature. The event includes the feature name, plan tier, and user ID as properties. Mixpanel's funnel view shows which features correlate with paid conversions.

FlutterFlow Prompt

Track when a user taps the 'Export Report' button — send a Mixpanel event called 'export_report_tapped' with properties: user_id, plan, report_type, and timestamp.

Copy this prompt to try it in FlutterFlow

Mobile e-commerce app with purchase funnel tracking

A shopping app built in FlutterFlow sends Mixpanel events at each step of the checkout flow: 'Product Viewed', 'Cart Updated', 'Checkout Started', and 'Order Placed'. The event properties include product ID, price, and category. Mixpanel's funnel analysis pinpoints exactly where users abandon.

FlutterFlow Prompt

Fire a 'checkout_started' event in Mixpanel when the user taps the Checkout button, passing their user ID, cart total, and number of items as event properties.

Copy this prompt to try it in FlutterFlow

Fitness app measuring session completion rates

A workout app fires 'Workout Started' and 'Workout Completed' events with the workout ID and duration. Mixpanel's retention chart shows how many users complete at least three workouts in their first week — the team's primary activation metric.

FlutterFlow Prompt

When a user finishes a workout, send a Mixpanel event 'workout_completed' with properties: workout_id, duration_seconds, difficulty_level, and the FlutterFlow authenticated user ID as distinct_id.

Copy this prompt to try it in FlutterFlow

Troubleshooting

API Call returns HTTP 200 but Mixpanel Live View shows no events

Cause: Mixpanel's /track endpoint returns 200 with body '1' on success and '0' on failure. A '0' response typically means the `data` parameter is missing, the base64 encoding is malformed, or the JSON payload shape is wrong (missing `event` or `properties.token` fields).

Solution: In FlutterFlow's API Call Response & Test tab, check the actual response body — not just the status code. If you see '0', log the `encodedPayload` variable before sending and decode it manually at base64decode.org to inspect the JSON. Confirm the payload includes the `event` key and the `properties` object with a `token` field matching your project token.

XMLHttpRequest error on web build — events work in Test Mode but fail after publishing

Cause: Flutter Web runs in a browser, which enforces CORS. Mixpanel's /track endpoint does not include Access-Control-Allow-Origin headers for all origins, so the browser blocks the preflight request.

Solution: Enable FlutterFlow's built-in proxy for the Mixpanel API Group (API Calls → Mixpanel group → toggle 'Use FlutterFlow Proxy'). Alternatively, route the call through a Firebase Cloud Function that calls Mixpanel server-side and returns the result, then point your FlutterFlow API Call at the function URL instead.

Users are showing up as multiple identities in Mixpanel (identity fragmentation)

Cause: The `distinct_id` passed in events is inconsistent — for example, using a random value before login and a different UID after login without calling Mixpanel's $identify/$alias to merge the profiles.

Solution: Always use the FlutterFlow authenticated user UID (`currentUserUid`) as the `distinct_id` for logged-in users. For guest sessions, generate a UUID on first app launch using a Custom Action with the `uuid` pub.dev package, persist it in App State (with local persistence enabled), and send it as distinct_id. After login, fire a separate Mixpanel $identify event to link the pre-auth and post-auth identities.

401 Unauthorized when calling Mixpanel's Query API (/api/2.0/ endpoints)

Cause: The Mixpanel Query API requires HTTP Basic Auth with a service account user and secret — not the project token. If you attempt to call the Query API directly from a FlutterFlow API Call using the project token, you will receive 401.

Solution: Never call the Mixpanel Query API from FlutterFlow directly. Build a Firebase Cloud Function that constructs the Basic Auth header using the service account credentials stored as environment variables. Your FlutterFlow API Call targets the function URL, passing only the query parameters. The function authenticates with Mixpanel and returns the results.

Best practices

  • Store only the Mixpanel project token in App Constants — it is a public ingestion identifier. The service account secret belongs exclusively in a Firebase Cloud Function.
  • Use the authenticated user UID as `distinct_id` for all logged-in events. Never use a random value per event session, as this creates thousands of phantom user profiles.
  • Fire events from the Action Flow Editor using On Page Load and On Tap triggers rather than calling the API from a custom timer — keep event calls tied to real user interactions.
  • Always verify new events in Mixpanel's Live View immediately after adding them in FlutterFlow. A 200 HTTP status does not confirm successful ingestion — only Live View confirms the event landed with correct properties.
  • Keep event names consistent and lowercase with underscores (e.g., `button_tapped`, `page_viewed`, `purchase_completed`). Inconsistent naming creates duplicate events that clutter your Mixpanel event taxonomy and break funnels.
  • For web builds, enable FlutterFlow's API proxy on the Mixpanel group to prevent CORS failures. Test both the native and web build paths before going to production.
  • Batch multiple event properties into the `properties` object rather than sending separate API calls per property — Mixpanel charges by event volume on paid plans, and a single rich event is better than several thin ones.
  • If you later want richer autocapture or offline event queueing, wrap the `mixpanel_flutter` pub.dev package in a FlutterFlow Custom Action — this gives automatic session tracking that the bare API Call approach cannot match.

Alternatives

Frequently asked questions

Can I use the Mixpanel JavaScript SDK in a FlutterFlow app?

No. Mixpanel's JavaScript SDK is designed for web browsers and cannot run inside a compiled Flutter/Dart application. The correct approach for FlutterFlow is either the HTTP API Call described in this guide (POST to /track) or the `mixpanel_flutter` pub.dev SDK wrapped in a FlutterFlow Custom Action. The pub.dev SDK gives you automatic session tracking and offline event queuing that the bare API Call approach lacks.

Is the Mixpanel project token safe to store in my FlutterFlow app?

Yes. The project token is a public ingestion identifier — it can only be used to send events into your Mixpanel project, not to read or export your data. Mixpanel intentionally makes this token public (it appears in their JS SDK snippet visible to anyone who views page source). Store it in App Constants. The service account user and secret are a different story: those credentials can query and export your data and must never appear in client-side Dart code.

Why do events appear in Test Mode but not after I publish my web app?

This is a CORS issue specific to Flutter Web builds. FlutterFlow's Test Mode routes API Calls through FlutterFlow's own servers, so CORS does not apply. Once published to the web, your browser blocks the cross-origin POST to api.mixpanel.com. Fix this by enabling FlutterFlow's built-in proxy on the Mixpanel API Group (toggle 'Use FlutterFlow Proxy' in the group settings). Native iOS and Android builds are never affected by CORS.

How do I track screen views automatically in FlutterFlow + Mixpanel?

Add an On Page Load action to each page in your FlutterFlow project that fires the Mixpanel Track Event API Call with the event name 'screen_viewed' and a property 'screen_name' matching the page name. There is no automatic screen-view tracking via the API Call approach — you must add the action to each page. The `mixpanel_flutter` Custom Action approach can automate this with the SDK's route observer pattern, but it requires more setup.

Does Mixpanel have a free tier, and will this integration cost money?

Mixpanel offers a free plan that includes a generous monthly tracked user allowance — check mixpanel.com/pricing for current limits, as they update periodically. The /track ingestion endpoint itself is designed for high volume and does not impose a strict rate limit on the free tier. Costs typically begin when you exceed the monthly tracked user count or need advanced features like data pipelines, cohort exports, or A/B testing. The FlutterFlow API Call integration described here works on Mixpanel's free plan.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire FlutterFlow integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.