▸Example Mixpanel call (the "before")
import Mixpanel
let mixpanel = Mixpanel.mainInstance()
// Identifies the user — distinct_id becomes joinable to email forever:
mixpanel.identify(distinctId: userId)
mixpanel.people.set(properties: [
"$email": email,
"$name": fullName,
"plan": "pro",
])
mixpanel.track(event: "Paywall Purchase", properties: ["value": price])
Most analytics SDKs accept dozens of custom parameters per event. Respectlytics's API stores exactly five fields per event: event_name, session_id (rotated every two hours), timestamp, platform, and country. Extra fields are rejected with a 400. The discipline is structural — engineers can't accidentally add PII over time because the API refuses it.
☑Remove Mixpanel cleanly
-
1
Remove
pod 'Mixpanel'fromPodfile -
2
Remove
implementation 'com.mixpanel.android:mixpanel-android:...'frombuild.gradle.kts -
3
Remove
mixpanel-react-nativefrompackage.jsonormixpanel_flutter:frompubspec.yaml -
4
Delete any
Mixpanel.mainInstance().people.set(...)oridentify()calls — those are the people-profile entry points -
5
Replace
mixpanel.track(...)call sites withRespectlytics.track("event_name") -
6
Delete the Mixpanel project (or revoke the project token) in the Mixpanel admin once you've confirmed no more events arrive
-
7
If you used Mixpanel-driven cohort exports for marketing, plan the cutover to whatever replaces those flows
⇋Mixpanel vs Respectlytics — 5-field event schema
| Mixpanel | Respectlytics | |
|---|---|---|
| Stored fields per event | — see tool note above (typically dozens of params) | Exactly 5 |
| API enforcement of schema | Lenient (extras stored) | Strict (extras rejected with 400) |
| Per-user state computable | Yes (people profiles, user properties) | No (use account system) |
| Custom event properties accepted | 25–250 depending on tool | 0 |
❓Frequently asked questions
How do we segment events without custom properties?
By using distinct event names. Instead of track('purchase', { product: 'gold_pack' }), fire track('purchase_gold_pack'). The aggregation buckets event names automatically; no manual configuration. Keep your taxonomy short (under ~50 distinct names per matrix axis) to stay navigable.
We need per-event price for revenue reporting — how does that work?
It doesn't — and that's the point. Authoritative revenue lives in your billing system (Stripe, RevenueCat, App Store Connect) with refund-aware totals and currency-conversion handling. Mirroring revenue into product analytics produces two truths that drift over time.
What if we genuinely need a sixth field for legitimate reasons?
Three options: (a) encode the variant into the event name (e.g., paywall_purchase_pro vs paywall_purchase_basic); (b) keep per-user state in your account system and don't mirror it; (c) use a different tool for the specific use case. Most product teams find (a) or (b) sufficient.
How does the API actually enforce this?
JSON validation at the API gateway. A POST /api/v1/events/ with any field outside the 5 allowed keys returns HTTP 400 Bad Request with a body listing the rejected field names. Your integration test catches the regression on the first commit that adds an extra field.