Why unified profiles are hard
Every enterprise ends up with the same shape: Sales Cloud owns the account, Marketing Cloud owns the subscriber, Service Cloud owns the contact, the mobile app owns the device ID, the data warehouse owns the transaction. None of them share a primary key.
Data Cloud solves this with a three-stage pipeline: ingest → harmonize → resolve.
Data model: DLO → DMO → CIO
- DLO (Data Lake Object) — raw source data, one per stream.
- DMO (Data Model Object) — canonical schema mapped from many DLOs.
- CIO (Calculated Insight) — SQL-defined aggregates like LTV or churn score.
Sales Cloud Contact ─┐
Marketing Subscriber ─┼─► Individual (DMO) ─► Unified Individual ─► Segment
Web SDK Event Stream ─┤
Stripe Customer ─┘ (Identity Resolution ruleset)
Identity Resolution rules that actually work
Start with deterministic matching, add fuzzy rules only after you measure false positives.
Rule 1 (exact): normalized_email = normalized_email
Rule 2 (exact): phone_e164 = phone_e164
Rule 3 (fuzzy): last_name + zip5 + fuzzy(first_name) + fuzzy(street)
Normalize before the ruleset runs (email lowercased, phone in E.164, ZIP trimmed to 5). Otherwise Rule 1 silently misses 15–30% of matches.
Streaming ingestion in practice
The Ingestion API accepts JSON batches up to 200 KB per request. Use it for web/mobile events:
curl -X POST "$DATA_CLOUD_URL/api/v1/ingest/sources/Web_Events/PageView" \
-H "Authorization: Bearer $OFFCORE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data":[{
"event_id":"evt_01HZ...",
"occurred_at":"2026-06-15T12:03:11Z",
"user_id":"u_9182",
"url":"/pricing",
"utm_source":"linkedin"
}]}'
For CRM and warehouse data, use the CDC connector or Snowflake Zero-Copy Sharing — no ETL, no duplication.
Querying the profile
Data Cloud exposes a Postgres-compatible SQL surface via the Query API:
SELECT
ui.ssot__Id__c AS unified_id,
ui.ssot__FirstName__c AS first_name,
ci.LTV_90d__c AS ltv_90d,
ci.Churn_Score__c AS churn
FROM UnifiedIndividual__dlm ui
JOIN Customer_Insights__cio ci
ON ci.UnifiedIndividualId__c = ui.ssot__Id__c
WHERE ci.Churn_Score__c > 0.7
ORDER BY ci.LTV_90d__c DESC
LIMIT 500;
Activating profiles back into tools
Once resolved, push segments to Marketing Cloud, Ads, or Sales Cloud through Activation Targets. The pattern that scales:
- Keep segments narrow and named by intent (
high_ltv_at_risk_90d, notsegment_47). - Set refresh cadence per activation (real-time for web personalization, hourly for email, daily for ads).
- Version segments in Git via the Metadata API — never edit in prod UI.
Common pitfalls
- Over-mapping DMOs on day one. Start with Individual + Contact Point Email + Order.
- Skipping normalization Flows. Identity Resolution is only as good as your keys.
- Treating CIOs like reports. They're materialized — budget storage and refresh compute.
Outcome
Teams that follow this pattern typically collapse 4–6 disparate profile stores into a single resolved individual and unlock same-day activation across email, ads, and in-app.
