AirBridge → Mixpanel Instrumentation Mapping
The implementation contract for Mixxi attribution across iOS and Android. This version consolidates v1.0–v1.2 and aligns the app with enums v1.4.0 ahead of Episode 0 / Discovery on 31 July 2026.
The critical correction
Earlier circulation placed the raw channel in acquisition_source. That is no longer valid. The raw value belongs in acquisition_channel; acquisition_source may contain only a committed enum value.
Raw, lossless
acquisition_channelRaw source such as instagram or whatsapp. First-touch and $set_once.
Canonical bucket
acquisition_sourceEnum rollup from v1.4.0. First-touch and $set_once; never a raw channel string.
Affiliate join key
marketing_affiliate_idThe affiliate code from campaign, for affiliate links only.
Derive the acquisition source
Evaluate rules top-down; the first match wins.
Result
No attribution / null.
ad_platform, not channel. Instagram and Facebook paid traffic both roll up to paid_meta; the raw channel remains available in acquisition_channel and mx_channel.The chain and timing rules
- Consent gate first: DPDP deny-by-default.
- Initialize Mixpanel before attribution work so
distinct_idexists. - Initialize AirBridge and handle immediate and deferred deep links.
- Write first-touch profile keys with
$set_once. - Register
mx_*super props and track funnel events. - MMRP joins the deterministic AirBridge postback to Mixpanel.
click → AirBridge → consent → Mixpanel init → AirBridge init → deep-link params → $set_once profile props → register mx_* → signup_complete
Latest-touch event context
On every attributed open, register the available context as Mixpanel super properties:
mx_channel · mx_phase · mx_episode · mx_recipe · mx_asset · mx_placement · mx_funding · mx_ad_platform · mx_persona · mx_layer · mx_team · mx_cta · mx_aff
Profile keys
First touch · immutable
acquisition_channel, acquisition_source, and affiliate credit stay fixed once stamped.
Super properties
Latest attributed touch · overwrite
Overwrite on each new tagged open. Do not clear on organic opens. Omit absent params; never write empty strings.
What ships when
Write the raw channel to
acquisition_channel. Leave acquisition_source unset. Never write a raw channel into acquisition_source.Write
acquisition_source from the JSON-encoded v1.4.0 rollup. The app must read the ruleset from JSON rather than hardcoding it.Join, parity, and privacy
Deterministic join
MMRP joins via airbridge_id and, for affiliate credit, marketing_affiliate_id. No fingerprinting.
Event parity
Use signup_complete, never account_created. iOS and Android names and lowercase enum values must be byte-identical.
DPDP
No phone numbers or raw PII in Mixpanel. Never forward gaid, device_uuid, or client_id into Mixpanel properties.
One decisive fresh-device test
- Use a clean device and test each platform/environment. Create an affiliate link with
RISING-E0-TESTONLY; separately test a marketing link:instagram / phase1_tease__ep01_discovery / trend__testasset_01 / funding=organic. - Tap → install → consent → sign up → open an episode.
- In the correct Mixpanel Live View, confirm
signup_complete, a second event with fullmx_*, rawacquisition_channel, enum-onlyacquisition_source, andairbridge_id. - For the affiliate case, confirm exact
marketing_affiliate_idand the AirBridge postback join. - Tap a second tagged link. Its event context must change while first-touch profile keys remain unchanged.
Do not hardcode against these
- Confirm the v1.4.0 JSON contains the rollup ruleset as data, not just enum members. The app team must be on v1.4.0, not v1.0.0.
- Affiliate postback field (
partnervssub_id) remains console-defined and owned by Punit;campaignis the stable in-app source. go.mixxi.aiis cosmetic for deferred attribution; direct Universal/App Links are a separate freeze-gated change.- Do not build
vote_castclient-side. Preferred path: Unravel backend emits it from validated Kafka votes.