Skip to content

P1-01 Unified Contact Graph + Attribution

Single identity record per human across ALL touchpoints.


DimensionScoreRationale
Pain5/5Identity fragmentation is universal — every multi-tool team suffers
Revenue4/5Foundation enables all revenue-generating modules
Build2/5Merge logic, multi-tenancy, and SDK require significant engineering
Moat5/5Once enriched with cross-module data, switching cost is enormous
Total16/20

Foundation

“Mailchimp says 4,200 contacts. App DB says 3,800. Referral tool says 2,100. How many actual people do we have?”

“We spent all of Tuesday reconciling Intercom contacts with our Stripe customers. Again.”

  • Teams lose 15–20% of leads to identity fragmentation across tools.
  • Manual reconciliation burns 3–5 hours per week for growth teams.
  • Attribution breaks when the same person appears as three different records in three different tools.
  • No single source of truth means no reliable segmentation, no accurate LTV, no trustworthy reporting.

  • Single identity per human — email, phone, anonymous browser session, and app user ID all resolve to one record.
  • Every interaction attributed to source — UTM parameters, referral codes, direct visits, QR codes.
  • Deterministic merge on email/phone — when a known identifier matches, records merge automatically.
  • Anonymous-to-known resolution — browser sessions retroactively attach to a contact when they identify themselves.
  • Multi-tenant isolation — every query scoped by tenant_id, zero data leakage.

ToolPricingLimitation
Segment$120–$1,200/moCDP only — no growth modules, no merge logic
RudderstackOpen-sourceComplex self-hosting, no integrated growth features
HubSpot CRMFree tierLimited identity resolution, no event-level attribution
Mixpanel / Amplitude$25–$2,000/moAnalytics identity, not a contact record

Maximum defensibility (5/5).

No point solution can replicate the value of an integrated data layer where every growth interaction — referral, survey response, waitlist signup, email click — enriches the same contact record.

Once a tenant has 50K+ contacts enriched with cross-module data (referral history, NPS scores, email engagement, waitlist position), the switching cost is enormous. This data does not exist in any single competitor.


The Contact Graph sits at the center of every data flow. Every module reads from it and writes back to it. This is what makes GrowthOS a system rather than a bundle.


  • contacts tableemail, phone, app_user_id, anonymous_id, profile_json, source, utm_params, merged_into
  • Deterministic merge rules — automatic deduplication on email and phone match
  • JS SDKinit(), identify(), track() methods
  • REST APIPOST /contacts, PATCH /contacts/:id, GET /contacts/:id, POST /events
  • Contact list UI — searchable, filterable contact browser in the dashboard
  • Multi-tenant isolation — all data scoped via tenant_id

  • Probabilistic merge (fuzzy matching on name/address) — too error-prone for MVP
  • Native iOS/Android SDKs — JS SDK covers web and React Native
  • CSV import/export — manual data operations deferred to Phase 2

BUILD — this is core IP.

No adequate open-source solution exists with multi-tenancy + merge logic + attribution at this level of integration. The Contact Graph is the single most important architectural decision in GrowthOS.

Estimated effort: 6–8 weeks MVP.