Skip to main content
FloKit joins identifiers from your MMP, subscription platform, and product event stream to build a complete user timeline — from first ad touch to subscription revenue. A well-configured identity graph is the foundation of accurate payback analysis.

The identity graph

FloKit maintains a deterministic identity graph. When two identifiers are associated with the same user — for example, an anonymous_id linked to a user_id at login, or a user_id matched to an app_user_id in RevenueCat — FloKit merges their event histories into a single unified timeline. All payback calculations, cohort assignments, and LTV projections operate on the merged view.

Identifiers

IdentifierSourcePurpose
anonymous_idYour app / Events APIPre-login events; linked to user_id at account creation
user_idYour backendPrimary user identifier across your product
email_hashYour backend (SHA-256 of lowercase email)Cross-device matching; privacy-safe
device_idMMP (IDFA / GAID)Device-level attribution join
app_user_idRevenueCatRevenueCat’s subscriber identifier; should match user_id
mmp_customer_user_idAppsFlyer / AdjustMMP’s customer ID; should match user_id
subscription_customer_idStripeStripe customer object ID
campaign_idMMP / ad platformCampaign grouping
ad_set_idMMP / ad platformAd set / ad group grouping
creative_idMMP / ad platformCreative-level attribution
paywall_idYour app / Events APIWhich paywall was shown
offer_idRevenueCat / Adapty / Events APIWhich promotional offer was applied
transaction_idApp Store / Google Play / StripeRevenue transaction; deduplicates refunds

Linking anonymous to identified

Send user_id alongside anonymous_id in any event after the user logs in or creates an account. FloKit retroactively attributes all prior pre-login events to the identified user.
{
  "event": "user_created",
  "user_id": "usr_abc123",
  "anonymous_id": "anon_xyz789",
  "timestamp": "2024-03-15T14:10:00Z",
  "properties": {
    "platform": "ios",
    "country": "US"
  }
}
After FloKit processes this event, all previous events carrying anon_xyz789 — including install attribution — are merged into the usr_abc123 identity.

Identity validation

Go to FloKit → Data → Identity to inspect join rates across your user base. A healthy integration should show:
  • >90% of install-attributed users joining to a subscription record within 7 days
  • Less than 5% of subscription events with an unknown or unmapped user_id
  • >95% anonymous-to-identified link rate within the session

Common join gaps

RevenueCat app_user_id does not match MMP customer_user_id Set the RevenueCat app_user_id to your backend user_id during authentication. Both the MMP and RevenueCat should use the same stable identifier so FloKit can join the two systems.
// iOS — set during or immediately after authentication
Purchases.shared.logIn(yourBackendUserId) { customerInfo, created, error in
  // handle result
}
Anonymous pre-install events not linking Send the same anonymous_id in both your pre-install product events and your MMP install callback. If the MMP fires an install event with a different or missing anonymous_id, FloKit cannot link pre-install behavior to the attributed install. Stripe customer not joining Include your backend user_id in the Stripe customer metadata object at customer creation time. FloKit reads this field when syncing Stripe webhook data.
const customer = await stripe.customers.create({
  email: user.email,
  metadata: {
    user_id: user.id,  // your backend user_id
  },
});