[{"data":1,"prerenderedAt":2303},["ShallowReactive",2],{"article-alternates":3,"article-\u002Fen\u002Fdata\u002Fidentity-resolution-six-signals-unified-customer":12},{"i18nKey":4,"paths":5},"data-003-2026-07",{"de":6,"en":7,"es":8,"fr":9,"it":10,"ru":11},"\u002Fde\u002Fdata\u002Fidentity-resolution-6-signale-zu-einer-kundenidentitaet","\u002Fen\u002Fdata\u002Fidentity-resolution-unifying-6-signals-into-single-customer-identity","\u002Fes\u002Fdata\u002Fresolucion-identidad-seis-senales-un-perfil","\u002Ffr\u002Fdata\u002Fresolution-identite-6-signaux-vers-profil-client-unique","\u002Fit\u002Fdata\u002Frisoluzione-identita-sei-segnali-a-profilo-cliente-unico","\u002Fru\u002Fdata\u002Frazreshenie-identichnosti-6-signalov-v-yedin-profil",{"_path":13,"_dir":14,"_draft":15,"_partial":15,"_locale":16,"title":17,"description":18,"publishedAt":19,"modifiedAt":19,"category":14,"i18nKey":4,"tags":20,"readingTime":26,"author":27,"body":28,"_type":2297,"_id":2298,"_source":2299,"_file":2300,"_stem":2301,"_extension":2302},"\u002Fen\u002Fdata\u002Fidentity-resolution-six-signals-unified-customer","data",false,"","Identity Resolution: From 6 Signals to a Single Customer Identity","How to unify fragmented touchpoints into one customer identity using hash matching, probabilistic linking, and household identity. Server-side pipeline and practical schema.","2026-07-19",[21,22,23,24,25],"identity-resolution","hash-matching","probabilistic-linking","cdp","first-party-data",8,"Roibase",{"type":29,"children":30,"toc":2283},"root",[31,63,70,116,121,140,146,159,171,338,391,403,498,511,518,549,555,567,572,1040,1060,1085,1091,1096,1102,1107,1250,1263,1572,1584,1937,1950,1956,1968,1988,2000,2081,2094,2100,2113,2142,2147,2153,2190,2245,2272,2277],{"type":32,"tag":33,"props":34,"children":35},"element","p",{},[36,39,46,48,54,55,61],{"type":37,"value":38},"text","A user clicks a campaign from mobile, adds a product to cart on desktop, purchases in-store. These three signals represent three separate identities: ",{"type":32,"tag":40,"props":41,"children":43},"code",{"className":42},[],[44],{"type":37,"value":45},"device_id",{"type":37,"value":47},", ",{"type":32,"tag":40,"props":49,"children":51},{"className":50},[],[52],{"type":37,"value":53},"cookie_hash",{"type":37,"value":47},{"type":32,"tag":40,"props":56,"children":58},{"className":57},[],[59],{"type":37,"value":60},"email_hash",{"type":37,"value":62},". Identity resolution is the data pipeline that consolidates these fragments into a single customer profile. In the post-cookie era — Consent Mode v2, iOS ATT, CCPA — server-side architecture built on first-party data has shifted from recommendation to requirement.",{"type":32,"tag":64,"props":65,"children":67},"h2",{"id":66},"why-six-different-signals-exist",[68],{"type":37,"value":69},"Why six different signals exist",{"type":32,"tag":33,"props":71,"children":72},{},[73,75,81,82,87,89,94,96,101,103,108,109,114],{"type":37,"value":74},"The modern marketing stack collects identity signals across six layers: ",{"type":32,"tag":76,"props":77,"children":78},"strong",{},[79],{"type":37,"value":80},"browser cookie",{"type":37,"value":47},{"type":32,"tag":76,"props":83,"children":84},{},[85],{"type":37,"value":86},"device ID",{"type":37,"value":88}," (IDFA\u002FGAID), ",{"type":32,"tag":76,"props":90,"children":91},{},[92],{"type":37,"value":93},"authenticated hash",{"type":37,"value":95}," (email SHA-256), ",{"type":32,"tag":76,"props":97,"children":98},{},[99],{"type":37,"value":100},"customer ID",{"type":37,"value":102}," (CRM\u002FCDP internal), ",{"type":32,"tag":76,"props":104,"children":105},{},[106],{"type":37,"value":107},"IP+user-agent fingerprint",{"type":37,"value":47},{"type":32,"tag":76,"props":110,"children":111},{},[112],{"type":37,"value":113},"household graph",{"type":37,"value":115},". Each activates at a different lifecycle stage.",{"type":32,"tag":33,"props":117,"children":118},{},[119],{"type":37,"value":120},"Browser cookie fires at first touchpoint; device ID on mobile app; authenticated hash when email or phone is collected; customer ID post-checkout; fingerprint enables probabilistic matching without consent; household graph groups devices on the same router. The problem: these six signals live in separate tables with different TTLs (cookie 90 days, IDFA indefinite, email hash until customer deletion). Without resolution, each channel counts different users — marketing mix models double-count, incrementality tests overestimate, retention cohorts show false churn.",{"type":32,"tag":33,"props":122,"children":123},{},[124,126,131,133,138],{"type":37,"value":125},"Resolution logic operates via two methods: ",{"type":32,"tag":76,"props":127,"children":128},{},[129],{"type":37,"value":130},"deterministic (hash matching)",{"type":37,"value":132}," and ",{"type":32,"tag":76,"props":134,"children":135},{},[136],{"type":37,"value":137},"probabilistic (graph linking)",{"type":37,"value":139},". Deterministic: an email SHA-256 hash links a browser event to a backend transaction with 100% certainty. Probabilistic: if the same IP+user-agent appears in two events within 24 hours, the match probability is ~73% (at standard threshold). Skip resolution entirely and your unique user count inflates by 40-80% (category and device mix dependent).",{"type":32,"tag":64,"props":141,"children":143},{"id":142},"hash-matching-converting-email-and-phone-to-identity-keys",[144],{"type":37,"value":145},"Hash matching: converting email and phone to identity keys",{"type":32,"tag":33,"props":147,"children":148},{},[149,151,157],{"type":37,"value":150},"Hash matching is the backbone of server-side identity resolution. The moment a user provides email or phone, client-side or sGTM produces a SHA-256 hash, writing it to ",{"type":32,"tag":40,"props":152,"children":154},{"className":153},[],[155],{"type":37,"value":156},"identity_map",{"type":37,"value":158},". Subsequent anonymous events lookup by cookie or device ID, retrieving the hash.",{"type":32,"tag":33,"props":160,"children":161},{},[162,164,169],{"type":37,"value":163},"Simple ",{"type":32,"tag":40,"props":165,"children":167},{"className":166},[],[168],{"type":37,"value":156},{"type":37,"value":170}," schema:",{"type":32,"tag":172,"props":173,"children":177},"pre",{"className":174,"code":175,"language":176,"meta":16,"style":16},"language-sql shiki shiki-themes github-dark","CREATE TABLE identity_map (\n  canonical_id STRING NOT NULL,      -- UUID, internal ID\n  signal_type STRING NOT NULL,       -- 'email_sha256', 'phone_sha256', 'device_id', 'cookie'\n  signal_value STRING NOT NULL,      -- hash or ID\n  first_seen TIMESTAMP,\n  last_seen TIMESTAMP,\n  PRIMARY KEY (signal_type, signal_value)\n);\n","sql",[178],{"type":32,"tag":40,"props":179,"children":180},{"__ignoreMap":16},[181,210,235,258,280,299,316,330],{"type":32,"tag":182,"props":183,"children":186},"span",{"class":184,"line":185},"line",1,[187,193,198,204],{"type":32,"tag":182,"props":188,"children":190},{"style":189},"--shiki-default:#F97583",[191],{"type":37,"value":192},"CREATE",{"type":32,"tag":182,"props":194,"children":195},{"style":189},[196],{"type":37,"value":197}," TABLE",{"type":32,"tag":182,"props":199,"children":201},{"style":200},"--shiki-default:#B392F0",[202],{"type":37,"value":203}," identity_map",{"type":32,"tag":182,"props":205,"children":207},{"style":206},"--shiki-default:#E1E4E8",[208],{"type":37,"value":209}," (\n",{"type":32,"tag":182,"props":211,"children":213},{"class":184,"line":212},2,[214,219,224,229],{"type":32,"tag":182,"props":215,"children":216},{"style":206},[217],{"type":37,"value":218},"  canonical_id STRING ",{"type":32,"tag":182,"props":220,"children":221},{"style":189},[222],{"type":37,"value":223},"NOT NULL",{"type":32,"tag":182,"props":225,"children":226},{"style":206},[227],{"type":37,"value":228},",      ",{"type":32,"tag":182,"props":230,"children":232},{"style":231},"--shiki-default:#6A737D",[233],{"type":37,"value":234},"-- UUID, internal ID\n",{"type":32,"tag":182,"props":236,"children":238},{"class":184,"line":237},3,[239,244,248,253],{"type":32,"tag":182,"props":240,"children":241},{"style":206},[242],{"type":37,"value":243},"  signal_type STRING ",{"type":32,"tag":182,"props":245,"children":246},{"style":189},[247],{"type":37,"value":223},{"type":32,"tag":182,"props":249,"children":250},{"style":206},[251],{"type":37,"value":252},",       ",{"type":32,"tag":182,"props":254,"children":255},{"style":231},[256],{"type":37,"value":257},"-- 'email_sha256', 'phone_sha256', 'device_id', 'cookie'\n",{"type":32,"tag":182,"props":259,"children":261},{"class":184,"line":260},4,[262,267,271,275],{"type":32,"tag":182,"props":263,"children":264},{"style":206},[265],{"type":37,"value":266},"  signal_value STRING ",{"type":32,"tag":182,"props":268,"children":269},{"style":189},[270],{"type":37,"value":223},{"type":32,"tag":182,"props":272,"children":273},{"style":206},[274],{"type":37,"value":228},{"type":32,"tag":182,"props":276,"children":277},{"style":231},[278],{"type":37,"value":279},"-- hash or ID\n",{"type":32,"tag":182,"props":281,"children":283},{"class":184,"line":282},5,[284,289,294],{"type":32,"tag":182,"props":285,"children":286},{"style":206},[287],{"type":37,"value":288},"  first_seen ",{"type":32,"tag":182,"props":290,"children":291},{"style":189},[292],{"type":37,"value":293},"TIMESTAMP",{"type":32,"tag":182,"props":295,"children":296},{"style":206},[297],{"type":37,"value":298},",\n",{"type":32,"tag":182,"props":300,"children":302},{"class":184,"line":301},6,[303,308,312],{"type":32,"tag":182,"props":304,"children":305},{"style":206},[306],{"type":37,"value":307},"  last_seen ",{"type":32,"tag":182,"props":309,"children":310},{"style":189},[311],{"type":37,"value":293},{"type":32,"tag":182,"props":313,"children":314},{"style":206},[315],{"type":37,"value":298},{"type":32,"tag":182,"props":317,"children":319},{"class":184,"line":318},7,[320,325],{"type":32,"tag":182,"props":321,"children":322},{"style":189},[323],{"type":37,"value":324},"  PRIMARY KEY",{"type":32,"tag":182,"props":326,"children":327},{"style":206},[328],{"type":37,"value":329}," (signal_type, signal_value)\n",{"type":32,"tag":182,"props":331,"children":332},{"class":184,"line":26},[333],{"type":32,"tag":182,"props":334,"children":335},{"style":206},[336],{"type":37,"value":337},");\n",{"type":32,"tag":33,"props":339,"children":340},{},[341,343,349,351,357,359,365,367,373,375,381,383,389],{"type":37,"value":342},"When a user enters ",{"type":32,"tag":40,"props":344,"children":346},{"className":345},[],[347],{"type":37,"value":348},"user@example.com",{"type":37,"value":350}," in a signup form, sGTM SHA-256 hashes the email and performs an ",{"type":32,"tag":40,"props":352,"children":354},{"className":353},[],[355],{"type":37,"value":356},"INSERT",{"type":37,"value":358},": ",{"type":32,"tag":40,"props":360,"children":362},{"className":361},[],[363],{"type":37,"value":364},"('uuid-123', 'email_sha256', 'abc123...', NOW(), NOW())",{"type":37,"value":366},". If the same session carries cookie ",{"type":32,"tag":40,"props":368,"children":370},{"className":369},[],[371],{"type":37,"value":372},"_ga=GA1.1.xyz",{"type":37,"value":374},", a second row follows: ",{"type":32,"tag":40,"props":376,"children":378},{"className":377},[],[379],{"type":37,"value":380},"('uuid-123', 'cookie', 'GA1.1.xyz', NOW(), NOW())",{"type":37,"value":382},". Now ",{"type":32,"tag":40,"props":384,"children":386},{"className":385},[],[387],{"type":37,"value":388},"canonical_id = uuid-123",{"type":37,"value":390}," binds two signals.",{"type":32,"tag":33,"props":392,"children":393},{},[394,396,401],{"type":37,"value":395},"Next session: the user arrives with ",{"type":32,"tag":40,"props":397,"children":399},{"className":398},[],[400],{"type":37,"value":372},{"type":37,"value":402}," alone, no email. BigQuery lookup:",{"type":32,"tag":172,"props":404,"children":406},{"className":174,"code":405,"language":176,"meta":16,"style":16},"SELECT canonical_id\nFROM identity_map\nWHERE signal_type = 'cookie' AND signal_value = 'GA1.1.xyz'\nLIMIT 1;\n",[407],{"type":32,"tag":40,"props":408,"children":409},{"__ignoreMap":16},[410,423,436,479],{"type":32,"tag":182,"props":411,"children":412},{"class":184,"line":185},[413,418],{"type":32,"tag":182,"props":414,"children":415},{"style":189},[416],{"type":37,"value":417},"SELECT",{"type":32,"tag":182,"props":419,"children":420},{"style":206},[421],{"type":37,"value":422}," canonical_id\n",{"type":32,"tag":182,"props":424,"children":425},{"class":184,"line":212},[426,431],{"type":32,"tag":182,"props":427,"children":428},{"style":189},[429],{"type":37,"value":430},"FROM",{"type":32,"tag":182,"props":432,"children":433},{"style":206},[434],{"type":37,"value":435}," identity_map\n",{"type":32,"tag":182,"props":437,"children":438},{"class":184,"line":237},[439,444,449,454,460,465,470,474],{"type":32,"tag":182,"props":440,"children":441},{"style":189},[442],{"type":37,"value":443},"WHERE",{"type":32,"tag":182,"props":445,"children":446},{"style":206},[447],{"type":37,"value":448}," signal_type ",{"type":32,"tag":182,"props":450,"children":451},{"style":189},[452],{"type":37,"value":453},"=",{"type":32,"tag":182,"props":455,"children":457},{"style":456},"--shiki-default:#9ECBFF",[458],{"type":37,"value":459}," 'cookie'",{"type":32,"tag":182,"props":461,"children":462},{"style":189},[463],{"type":37,"value":464}," AND",{"type":32,"tag":182,"props":466,"children":467},{"style":206},[468],{"type":37,"value":469}," signal_value ",{"type":32,"tag":182,"props":471,"children":472},{"style":189},[473],{"type":37,"value":453},{"type":32,"tag":182,"props":475,"children":476},{"style":456},[477],{"type":37,"value":478}," 'GA1.1.xyz'\n",{"type":32,"tag":182,"props":480,"children":481},{"class":184,"line":260},[482,487,493],{"type":32,"tag":182,"props":483,"children":484},{"style":189},[485],{"type":37,"value":486},"LIMIT",{"type":32,"tag":182,"props":488,"children":490},{"style":489},"--shiki-default:#79B8FF",[491],{"type":37,"value":492}," 1",{"type":32,"tag":182,"props":494,"children":495},{"style":206},[496],{"type":37,"value":497},";\n",{"type":32,"tag":33,"props":499,"children":500},{},[501,503,509],{"type":37,"value":502},"Returns: ",{"type":32,"tag":40,"props":504,"children":506},{"className":505},[],[507],{"type":37,"value":508},"uuid-123",{"type":37,"value":510},". Attribute the event to this ID — same user recognized without the email hash. Hash matching precision is 100% because cryptographic collision is infeasible. The coverage problem remains: if the user never provides email, no hash exists, and you fall back to probabilistic.",{"type":32,"tag":512,"props":513,"children":515},"h3",{"id":514},"collision-risk-and-salt",[516],{"type":37,"value":517},"Collision risk and salt",{"type":32,"tag":33,"props":519,"children":520},{},[521,523,528,530,536,538,547],{"type":37,"value":522},"SHA-256 collision risk is theoretical: 1 in 2^128 attempts. Production's real issue: ",{"type":32,"tag":76,"props":524,"children":525},{},[526],{"type":37,"value":527},"the same email linked to different canonical_ids",{"type":37,"value":529}," (manual error, legacy migration artifact). This is why you enforce ",{"type":32,"tag":40,"props":531,"children":533},{"className":532},[],[534],{"type":37,"value":535},"UNIQUE INDEX (signal_type, signal_value)",{"type":37,"value":537},". Using salt (email + secret string, then hash) doesn't increase collision risk but adds a privacy layer in ",{"type":32,"tag":539,"props":540,"children":544},"a",{"href":541,"rel":542},"https:\u002F\u002Fwww.roibase.com.tr\u002Fen\u002Ffirstparty",[543],"nofollow",[545],{"type":37,"value":546},"first-party data architecture",{"type":37,"value":548}," — rotate the salt and old hashes become invalid, supporting GDPR \"right to be forgotten\".",{"type":32,"tag":64,"props":550,"children":552},{"id":551},"probabilistic-linking-ip-user-agent-and-device-graph",[553],{"type":37,"value":554},"Probabilistic linking: IP, user-agent, and device graph",{"type":32,"tag":33,"props":556,"children":557},{},[558,560,565],{"type":37,"value":559},"If a user browses anonymously, deterministic signals don't exist. Deploy ",{"type":32,"tag":76,"props":561,"children":562},{},[563],{"type":37,"value":564},"probabilistic graph",{"type":37,"value":566},": IP + user-agent + timestamp proximity generates a \"likely same person\" score. Example: same IP, same user-agent, 15-minute gap between two events — 85% probability of the same user.",{"type":32,"tag":33,"props":568,"children":569},{},[570],{"type":37,"value":571},"Simple probabilistic merge logic:",{"type":32,"tag":172,"props":573,"children":575},{"className":174,"code":574,"language":176,"meta":16,"style":16},"WITH anon_events AS (\n  SELECT\n    event_id,\n    ip_address,\n    user_agent,\n    event_timestamp,\n    FARM_FINGERPRINT(CONCAT(ip_address, user_agent)) AS fingerprint\n  FROM events\n  WHERE canonical_id IS NULL\n),\nclusters AS (\n  SELECT\n    fingerprint,\n    MIN(event_timestamp) AS first_event,\n    MAX(event_timestamp) AS last_event,\n    COUNT(*) AS event_count\n  FROM anon_events\n  GROUP BY fingerprint\n  HAVING TIMESTAMP_DIFF(MAX(event_timestamp), MIN(event_timestamp), HOUR) \u003C 24\n)\nSELECT\n  a.event_id,\n  c.fingerprint AS probable_cluster_id\nFROM anon_events a\nJOIN clusters c ON a.fingerprint = c.fingerprint;\n",[576],{"type":32,"tag":40,"props":577,"children":578},{"__ignoreMap":16},[579,601,609,617,625,633,641,668,681,705,714,731,739,748,771,793,826,839,852,904,913,922,945,973,986],{"type":32,"tag":182,"props":580,"children":581},{"class":184,"line":185},[582,587,592,597],{"type":32,"tag":182,"props":583,"children":584},{"style":189},[585],{"type":37,"value":586},"WITH",{"type":32,"tag":182,"props":588,"children":589},{"style":206},[590],{"type":37,"value":591}," anon_events ",{"type":32,"tag":182,"props":593,"children":594},{"style":189},[595],{"type":37,"value":596},"AS",{"type":32,"tag":182,"props":598,"children":599},{"style":206},[600],{"type":37,"value":209},{"type":32,"tag":182,"props":602,"children":603},{"class":184,"line":212},[604],{"type":32,"tag":182,"props":605,"children":606},{"style":189},[607],{"type":37,"value":608},"  SELECT\n",{"type":32,"tag":182,"props":610,"children":611},{"class":184,"line":237},[612],{"type":32,"tag":182,"props":613,"children":614},{"style":206},[615],{"type":37,"value":616},"    event_id,\n",{"type":32,"tag":182,"props":618,"children":619},{"class":184,"line":260},[620],{"type":32,"tag":182,"props":621,"children":622},{"style":206},[623],{"type":37,"value":624},"    ip_address,\n",{"type":32,"tag":182,"props":626,"children":627},{"class":184,"line":282},[628],{"type":32,"tag":182,"props":629,"children":630},{"style":206},[631],{"type":37,"value":632},"    user_agent,\n",{"type":32,"tag":182,"props":634,"children":635},{"class":184,"line":301},[636],{"type":32,"tag":182,"props":637,"children":638},{"style":206},[639],{"type":37,"value":640},"    event_timestamp,\n",{"type":32,"tag":182,"props":642,"children":643},{"class":184,"line":318},[644,649,654,659,663],{"type":32,"tag":182,"props":645,"children":646},{"style":206},[647],{"type":37,"value":648},"    FARM_FINGERPRINT(",{"type":32,"tag":182,"props":650,"children":651},{"style":489},[652],{"type":37,"value":653},"CONCAT",{"type":32,"tag":182,"props":655,"children":656},{"style":206},[657],{"type":37,"value":658},"(ip_address, user_agent)) ",{"type":32,"tag":182,"props":660,"children":661},{"style":189},[662],{"type":37,"value":596},{"type":32,"tag":182,"props":664,"children":665},{"style":206},[666],{"type":37,"value":667}," fingerprint\n",{"type":32,"tag":182,"props":669,"children":670},{"class":184,"line":26},[671,676],{"type":32,"tag":182,"props":672,"children":673},{"style":189},[674],{"type":37,"value":675},"  FROM",{"type":32,"tag":182,"props":677,"children":678},{"style":206},[679],{"type":37,"value":680}," events\n",{"type":32,"tag":182,"props":682,"children":684},{"class":184,"line":683},9,[685,690,695,700],{"type":32,"tag":182,"props":686,"children":687},{"style":189},[688],{"type":37,"value":689},"  WHERE",{"type":32,"tag":182,"props":691,"children":692},{"style":206},[693],{"type":37,"value":694}," canonical_id ",{"type":32,"tag":182,"props":696,"children":697},{"style":189},[698],{"type":37,"value":699},"IS",{"type":32,"tag":182,"props":701,"children":702},{"style":189},[703],{"type":37,"value":704}," NULL\n",{"type":32,"tag":182,"props":706,"children":708},{"class":184,"line":707},10,[709],{"type":32,"tag":182,"props":710,"children":711},{"style":206},[712],{"type":37,"value":713},"),\n",{"type":32,"tag":182,"props":715,"children":717},{"class":184,"line":716},11,[718,723,727],{"type":32,"tag":182,"props":719,"children":720},{"style":206},[721],{"type":37,"value":722},"clusters ",{"type":32,"tag":182,"props":724,"children":725},{"style":189},[726],{"type":37,"value":596},{"type":32,"tag":182,"props":728,"children":729},{"style":206},[730],{"type":37,"value":209},{"type":32,"tag":182,"props":732,"children":734},{"class":184,"line":733},12,[735],{"type":32,"tag":182,"props":736,"children":737},{"style":189},[738],{"type":37,"value":608},{"type":32,"tag":182,"props":740,"children":742},{"class":184,"line":741},13,[743],{"type":32,"tag":182,"props":744,"children":745},{"style":206},[746],{"type":37,"value":747},"    fingerprint,\n",{"type":32,"tag":182,"props":749,"children":751},{"class":184,"line":750},14,[752,757,762,766],{"type":32,"tag":182,"props":753,"children":754},{"style":489},[755],{"type":37,"value":756},"    MIN",{"type":32,"tag":182,"props":758,"children":759},{"style":206},[760],{"type":37,"value":761},"(event_timestamp) ",{"type":32,"tag":182,"props":763,"children":764},{"style":189},[765],{"type":37,"value":596},{"type":32,"tag":182,"props":767,"children":768},{"style":206},[769],{"type":37,"value":770}," first_event,\n",{"type":32,"tag":182,"props":772,"children":774},{"class":184,"line":773},15,[775,780,784,788],{"type":32,"tag":182,"props":776,"children":777},{"style":489},[778],{"type":37,"value":779},"    MAX",{"type":32,"tag":182,"props":781,"children":782},{"style":206},[783],{"type":37,"value":761},{"type":32,"tag":182,"props":785,"children":786},{"style":189},[787],{"type":37,"value":596},{"type":32,"tag":182,"props":789,"children":790},{"style":206},[791],{"type":37,"value":792}," last_event,\n",{"type":32,"tag":182,"props":794,"children":796},{"class":184,"line":795},16,[797,802,807,812,817,821],{"type":32,"tag":182,"props":798,"children":799},{"style":489},[800],{"type":37,"value":801},"    COUNT",{"type":32,"tag":182,"props":803,"children":804},{"style":206},[805],{"type":37,"value":806},"(",{"type":32,"tag":182,"props":808,"children":809},{"style":189},[810],{"type":37,"value":811},"*",{"type":32,"tag":182,"props":813,"children":814},{"style":206},[815],{"type":37,"value":816},") ",{"type":32,"tag":182,"props":818,"children":819},{"style":189},[820],{"type":37,"value":596},{"type":32,"tag":182,"props":822,"children":823},{"style":206},[824],{"type":37,"value":825}," event_count\n",{"type":32,"tag":182,"props":827,"children":829},{"class":184,"line":828},17,[830,834],{"type":32,"tag":182,"props":831,"children":832},{"style":189},[833],{"type":37,"value":675},{"type":32,"tag":182,"props":835,"children":836},{"style":206},[837],{"type":37,"value":838}," anon_events\n",{"type":32,"tag":182,"props":840,"children":842},{"class":184,"line":841},18,[843,848],{"type":32,"tag":182,"props":844,"children":845},{"style":189},[846],{"type":37,"value":847},"  GROUP BY",{"type":32,"tag":182,"props":849,"children":850},{"style":206},[851],{"type":37,"value":667},{"type":32,"tag":182,"props":853,"children":855},{"class":184,"line":854},19,[856,861,866,871,876,881,885,890,894,899],{"type":32,"tag":182,"props":857,"children":858},{"style":189},[859],{"type":37,"value":860},"  HAVING",{"type":32,"tag":182,"props":862,"children":863},{"style":206},[864],{"type":37,"value":865}," TIMESTAMP_DIFF(",{"type":32,"tag":182,"props":867,"children":868},{"style":489},[869],{"type":37,"value":870},"MAX",{"type":32,"tag":182,"props":872,"children":873},{"style":206},[874],{"type":37,"value":875},"(event_timestamp), ",{"type":32,"tag":182,"props":877,"children":878},{"style":489},[879],{"type":37,"value":880},"MIN",{"type":32,"tag":182,"props":882,"children":883},{"style":206},[884],{"type":37,"value":875},{"type":32,"tag":182,"props":886,"children":887},{"style":189},[888],{"type":37,"value":889},"HOUR",{"type":32,"tag":182,"props":891,"children":892},{"style":206},[893],{"type":37,"value":816},{"type":32,"tag":182,"props":895,"children":896},{"style":189},[897],{"type":37,"value":898},"\u003C",{"type":32,"tag":182,"props":900,"children":901},{"style":489},[902],{"type":37,"value":903}," 24\n",{"type":32,"tag":182,"props":905,"children":907},{"class":184,"line":906},20,[908],{"type":32,"tag":182,"props":909,"children":910},{"style":206},[911],{"type":37,"value":912},")\n",{"type":32,"tag":182,"props":914,"children":916},{"class":184,"line":915},21,[917],{"type":32,"tag":182,"props":918,"children":919},{"style":189},[920],{"type":37,"value":921},"SELECT\n",{"type":32,"tag":182,"props":923,"children":925},{"class":184,"line":924},22,[926,931,936,941],{"type":32,"tag":182,"props":927,"children":928},{"style":489},[929],{"type":37,"value":930},"  a",{"type":32,"tag":182,"props":932,"children":933},{"style":206},[934],{"type":37,"value":935},".",{"type":32,"tag":182,"props":937,"children":938},{"style":489},[939],{"type":37,"value":940},"event_id",{"type":32,"tag":182,"props":942,"children":943},{"style":206},[944],{"type":37,"value":298},{"type":32,"tag":182,"props":946,"children":948},{"class":184,"line":947},23,[949,954,958,963,968],{"type":32,"tag":182,"props":950,"children":951},{"style":489},[952],{"type":37,"value":953},"  c",{"type":32,"tag":182,"props":955,"children":956},{"style":206},[957],{"type":37,"value":935},{"type":32,"tag":182,"props":959,"children":960},{"style":489},[961],{"type":37,"value":962},"fingerprint",{"type":32,"tag":182,"props":964,"children":965},{"style":189},[966],{"type":37,"value":967}," AS",{"type":32,"tag":182,"props":969,"children":970},{"style":206},[971],{"type":37,"value":972}," probable_cluster_id\n",{"type":32,"tag":182,"props":974,"children":976},{"class":184,"line":975},24,[977,981],{"type":32,"tag":182,"props":978,"children":979},{"style":189},[980],{"type":37,"value":430},{"type":32,"tag":182,"props":982,"children":983},{"style":206},[984],{"type":37,"value":985}," anon_events a\n",{"type":32,"tag":182,"props":987,"children":989},{"class":184,"line":988},25,[990,995,1000,1005,1010,1014,1018,1023,1028,1032,1036],{"type":32,"tag":182,"props":991,"children":992},{"style":189},[993],{"type":37,"value":994},"JOIN",{"type":32,"tag":182,"props":996,"children":997},{"style":206},[998],{"type":37,"value":999}," clusters c ",{"type":32,"tag":182,"props":1001,"children":1002},{"style":189},[1003],{"type":37,"value":1004},"ON",{"type":32,"tag":182,"props":1006,"children":1007},{"style":489},[1008],{"type":37,"value":1009}," a",{"type":32,"tag":182,"props":1011,"children":1012},{"style":206},[1013],{"type":37,"value":935},{"type":32,"tag":182,"props":1015,"children":1016},{"style":489},[1017],{"type":37,"value":962},{"type":32,"tag":182,"props":1019,"children":1020},{"style":189},[1021],{"type":37,"value":1022}," =",{"type":32,"tag":182,"props":1024,"children":1025},{"style":489},[1026],{"type":37,"value":1027}," c",{"type":32,"tag":182,"props":1029,"children":1030},{"style":206},[1031],{"type":37,"value":935},{"type":32,"tag":182,"props":1033,"children":1034},{"style":489},[1035],{"type":37,"value":962},{"type":32,"tag":182,"props":1037,"children":1038},{"style":206},[1039],{"type":37,"value":497},{"type":32,"tag":33,"props":1041,"children":1042},{},[1043,1045,1051,1053,1059],{"type":37,"value":1044},"This query groups events by IP+UA hash within a 24-hour window. Use the cluster ID as a provisional ",{"type":32,"tag":40,"props":1046,"children":1048},{"className":1047},[],[1049],{"type":37,"value":1050},"canonical_id",{"type":37,"value":1052},", but add confidence: ",{"type":32,"tag":40,"props":1054,"children":1056},{"className":1055},[],[1057],{"type":37,"value":1058},"event_count > 3 AND time_span \u003C 1 HOUR → confidence=0.9",{"type":37,"value":935},{"type":32,"tag":33,"props":1061,"children":1062},{},[1063,1068,1070,1076,1078,1083],{"type":32,"tag":76,"props":1064,"children":1065},{},[1066],{"type":37,"value":1067},"Household graph:",{"type":37,"value":1069}," Different user-agents from the same IP (laptop, tablet, phone) likely share a home. Create a ",{"type":32,"tag":40,"props":1071,"children":1073},{"className":1072},[],[1074],{"type":37,"value":1075},"household_id",{"type":37,"value":1077}," and nest individual ",{"type":32,"tag":40,"props":1079,"children":1081},{"className":1080},[],[1082],{"type":37,"value":1050},{"type":37,"value":1084}," beneath it. Example: Amazon Prime household — 1 subscription, 6 profiles — identity resolution aggregates at household level.",{"type":32,"tag":512,"props":1086,"children":1088},{"id":1087},"false-positive-rate",[1089],{"type":37,"value":1090},"False positive rate",{"type":32,"tag":33,"props":1092,"children":1093},{},[1094],{"type":37,"value":1095},"Probabilistic linking carries false-positive risk. The same IP + user-agent can come from two different users (office WiFi, library). Threshold too loose (50% confidence) and you see 15-25% false positives. Industry best practice: 75%+ confidence threshold, 1-hour time window, minimum 2 matching events. Vendors like LiveRamp use graph databases (Neo4j) combining 30+ signals, claiming 95%+ accuracy — but on your own first-party pipeline, 2-3 signals yield 80% accuracy sufficient.",{"type":32,"tag":64,"props":1097,"children":1099},{"id":1098},"server-side-pipeline-sgtm-bigquery-dbt",[1100],{"type":37,"value":1101},"Server-side pipeline: sGTM + BigQuery + dbt",{"type":32,"tag":33,"props":1103,"children":1104},{},[1105],{"type":37,"value":1106},"In production, identity resolution follows this data flow:",{"type":32,"tag":1108,"props":1109,"children":1110},"ol",{},[1111,1130,1170,1195,1219],{"type":32,"tag":1112,"props":1113,"children":1114},"li",{},[1115,1120,1122,1128],{"type":32,"tag":76,"props":1116,"children":1117},{},[1118],{"type":37,"value":1119},"sGTM event ingestion:",{"type":37,"value":1121}," Client-side GTM event reaches sGTM; if email present, sGTM appends SHA-256 hash; raw event writes to BigQuery (",{"type":32,"tag":40,"props":1123,"children":1125},{"className":1124},[],[1126],{"type":37,"value":1127},"events_raw",{"type":37,"value":1129},").",{"type":32,"tag":1112,"props":1131,"children":1132},{},[1133,1138,1140,1146,1148,1153,1155,1161,1162,1168],{"type":32,"tag":76,"props":1134,"children":1135},{},[1136],{"type":37,"value":1137},"dbt staging model:",{"type":37,"value":1139}," ",{"type":32,"tag":40,"props":1141,"children":1143},{"className":1142},[],[1144],{"type":37,"value":1145},"stg_events",{"type":37,"value":1147}," cleans ",{"type":32,"tag":40,"props":1149,"children":1151},{"className":1150},[],[1152],{"type":37,"value":1127},{"type":37,"value":1154},", parsing ",{"type":32,"tag":40,"props":1156,"children":1158},{"className":1157},[],[1159],{"type":37,"value":1160},"signal_type",{"type":37,"value":132},{"type":32,"tag":40,"props":1163,"children":1165},{"className":1164},[],[1166],{"type":37,"value":1167},"signal_value",{"type":37,"value":1169}," columns.",{"type":32,"tag":1112,"props":1171,"children":1172},{},[1173,1178,1180,1186,1188,1193],{"type":32,"tag":76,"props":1174,"children":1175},{},[1176],{"type":37,"value":1177},"dbt identity_map merge:",{"type":37,"value":1179}," When a new hash appears, ",{"type":32,"tag":40,"props":1181,"children":1183},{"className":1182},[],[1184],{"type":37,"value":1185},"MERGE",{"type":37,"value":1187}," executes against ",{"type":32,"tag":40,"props":1189,"children":1191},{"className":1190},[],[1192],{"type":37,"value":156},{"type":37,"value":1194}," (upsert logic).",{"type":32,"tag":1112,"props":1196,"children":1197},{},[1198,1203,1205,1210,1212,1217],{"type":32,"tag":76,"props":1199,"children":1200},{},[1201],{"type":37,"value":1202},"dbt canonical_id enrichment:",{"type":37,"value":1204}," Each event joins ",{"type":32,"tag":40,"props":1206,"children":1208},{"className":1207},[],[1209],{"type":37,"value":156},{"type":37,"value":1211},"; ",{"type":32,"tag":40,"props":1213,"children":1215},{"className":1214},[],[1216],{"type":37,"value":1050},{"type":37,"value":1218}," lookup resolves.",{"type":32,"tag":1112,"props":1220,"children":1221},{},[1222,1227,1229,1235,1236,1242,1244,1249],{"type":32,"tag":76,"props":1223,"children":1224},{},[1225],{"type":37,"value":1226},"dbt aggregation:",{"type":37,"value":1228}," User-level metrics (",{"type":32,"tag":40,"props":1230,"children":1232},{"className":1231},[],[1233],{"type":37,"value":1234},"user_ltv",{"type":37,"value":47},{"type":32,"tag":40,"props":1237,"children":1239},{"className":1238},[],[1240],{"type":37,"value":1241},"session_count",{"type":37,"value":1243},") aggregate by ",{"type":32,"tag":40,"props":1245,"children":1247},{"className":1246},[],[1248],{"type":37,"value":1050},{"type":37,"value":935},{"type":32,"tag":33,"props":1251,"children":1252},{},[1253,1255,1261],{"type":37,"value":1254},"Example dbt model snippet (",{"type":32,"tag":40,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":37,"value":1260},"models\u002Fstaging\u002Fstg_events.sql",{"type":37,"value":1262},"):",{"type":32,"tag":172,"props":1264,"children":1266},{"className":174,"code":1265,"language":176,"meta":16,"style":16},"{{ config(materialized='incremental') }}\n\nWITH events_with_signals AS (\n  SELECT\n    event_id,\n    event_timestamp,\n    COALESCE(user_properties.email_sha256, NULL) AS email_hash,\n    COALESCE(user_properties.ga_client_id, NULL) AS cookie_id,\n    event_params\n  FROM {{ source('bigquery', 'events_raw') }}\n  {% if is_incremental() %}\n  WHERE event_timestamp > (SELECT MAX(event_timestamp) FROM {{ this }})\n  {% endif %}\n)\nSELECT * FROM events_with_signals;\n",[1267],{"type":32,"tag":40,"props":1268,"children":1269},{"__ignoreMap":16},[1270,1292,1301,1321,1328,1335,1342,1390,1435,1443,1473,1491,1535,1543,1550],{"type":32,"tag":182,"props":1271,"children":1272},{"class":184,"line":185},[1273,1278,1282,1287],{"type":32,"tag":182,"props":1274,"children":1275},{"style":206},[1276],{"type":37,"value":1277},"{{ config(materialized",{"type":32,"tag":182,"props":1279,"children":1280},{"style":189},[1281],{"type":37,"value":453},{"type":32,"tag":182,"props":1283,"children":1284},{"style":456},[1285],{"type":37,"value":1286},"'incremental'",{"type":32,"tag":182,"props":1288,"children":1289},{"style":206},[1290],{"type":37,"value":1291},") }}\n",{"type":32,"tag":182,"props":1293,"children":1294},{"class":184,"line":212},[1295],{"type":32,"tag":182,"props":1296,"children":1298},{"emptyLinePlaceholder":1297},true,[1299],{"type":37,"value":1300},"\n",{"type":32,"tag":182,"props":1302,"children":1303},{"class":184,"line":237},[1304,1308,1313,1317],{"type":32,"tag":182,"props":1305,"children":1306},{"style":189},[1307],{"type":37,"value":586},{"type":32,"tag":182,"props":1309,"children":1310},{"style":206},[1311],{"type":37,"value":1312}," events_with_signals ",{"type":32,"tag":182,"props":1314,"children":1315},{"style":189},[1316],{"type":37,"value":596},{"type":32,"tag":182,"props":1318,"children":1319},{"style":206},[1320],{"type":37,"value":209},{"type":32,"tag":182,"props":1322,"children":1323},{"class":184,"line":260},[1324],{"type":32,"tag":182,"props":1325,"children":1326},{"style":189},[1327],{"type":37,"value":608},{"type":32,"tag":182,"props":1329,"children":1330},{"class":184,"line":282},[1331],{"type":32,"tag":182,"props":1332,"children":1333},{"style":206},[1334],{"type":37,"value":616},{"type":32,"tag":182,"props":1336,"children":1337},{"class":184,"line":301},[1338],{"type":32,"tag":182,"props":1339,"children":1340},{"style":206},[1341],{"type":37,"value":640},{"type":32,"tag":182,"props":1343,"children":1344},{"class":184,"line":318},[1345,1350,1354,1359,1363,1368,1372,1377,1381,1385],{"type":32,"tag":182,"props":1346,"children":1347},{"style":489},[1348],{"type":37,"value":1349},"    COALESCE",{"type":32,"tag":182,"props":1351,"children":1352},{"style":206},[1353],{"type":37,"value":806},{"type":32,"tag":182,"props":1355,"children":1356},{"style":489},[1357],{"type":37,"value":1358},"user_properties",{"type":32,"tag":182,"props":1360,"children":1361},{"style":206},[1362],{"type":37,"value":935},{"type":32,"tag":182,"props":1364,"children":1365},{"style":489},[1366],{"type":37,"value":1367},"email_sha256",{"type":32,"tag":182,"props":1369,"children":1370},{"style":206},[1371],{"type":37,"value":47},{"type":32,"tag":182,"props":1373,"children":1374},{"style":189},[1375],{"type":37,"value":1376},"NULL",{"type":32,"tag":182,"props":1378,"children":1379},{"style":206},[1380],{"type":37,"value":816},{"type":32,"tag":182,"props":1382,"children":1383},{"style":189},[1384],{"type":37,"value":596},{"type":32,"tag":182,"props":1386,"children":1387},{"style":206},[1388],{"type":37,"value":1389}," email_hash,\n",{"type":32,"tag":182,"props":1391,"children":1392},{"class":184,"line":26},[1393,1397,1401,1405,1409,1414,1418,1422,1426,1430],{"type":32,"tag":182,"props":1394,"children":1395},{"style":489},[1396],{"type":37,"value":1349},{"type":32,"tag":182,"props":1398,"children":1399},{"style":206},[1400],{"type":37,"value":806},{"type":32,"tag":182,"props":1402,"children":1403},{"style":489},[1404],{"type":37,"value":1358},{"type":32,"tag":182,"props":1406,"children":1407},{"style":206},[1408],{"type":37,"value":935},{"type":32,"tag":182,"props":1410,"children":1411},{"style":489},[1412],{"type":37,"value":1413},"ga_client_id",{"type":32,"tag":182,"props":1415,"children":1416},{"style":206},[1417],{"type":37,"value":47},{"type":32,"tag":182,"props":1419,"children":1420},{"style":189},[1421],{"type":37,"value":1376},{"type":32,"tag":182,"props":1423,"children":1424},{"style":206},[1425],{"type":37,"value":816},{"type":32,"tag":182,"props":1427,"children":1428},{"style":189},[1429],{"type":37,"value":596},{"type":32,"tag":182,"props":1431,"children":1432},{"style":206},[1433],{"type":37,"value":1434}," cookie_id,\n",{"type":32,"tag":182,"props":1436,"children":1437},{"class":184,"line":683},[1438],{"type":32,"tag":182,"props":1439,"children":1440},{"style":206},[1441],{"type":37,"value":1442},"    event_params\n",{"type":32,"tag":182,"props":1444,"children":1445},{"class":184,"line":707},[1446,1450,1455,1460,1464,1469],{"type":32,"tag":182,"props":1447,"children":1448},{"style":189},[1449],{"type":37,"value":675},{"type":32,"tag":182,"props":1451,"children":1452},{"style":206},[1453],{"type":37,"value":1454}," {{ source(",{"type":32,"tag":182,"props":1456,"children":1457},{"style":456},[1458],{"type":37,"value":1459},"'bigquery'",{"type":32,"tag":182,"props":1461,"children":1462},{"style":206},[1463],{"type":37,"value":47},{"type":32,"tag":182,"props":1465,"children":1466},{"style":456},[1467],{"type":37,"value":1468},"'events_raw'",{"type":32,"tag":182,"props":1470,"children":1471},{"style":206},[1472],{"type":37,"value":1291},{"type":32,"tag":182,"props":1474,"children":1475},{"class":184,"line":716},[1476,1481,1486],{"type":32,"tag":182,"props":1477,"children":1478},{"style":206},[1479],{"type":37,"value":1480},"  {% ",{"type":32,"tag":182,"props":1482,"children":1483},{"style":189},[1484],{"type":37,"value":1485},"if",{"type":32,"tag":182,"props":1487,"children":1488},{"style":206},[1489],{"type":37,"value":1490}," is_incremental() %}\n",{"type":32,"tag":182,"props":1492,"children":1493},{"class":184,"line":733},[1494,1498,1503,1508,1513,1517,1522,1526,1530],{"type":32,"tag":182,"props":1495,"children":1496},{"style":189},[1497],{"type":37,"value":689},{"type":32,"tag":182,"props":1499,"children":1500},{"style":206},[1501],{"type":37,"value":1502}," event_timestamp ",{"type":32,"tag":182,"props":1504,"children":1505},{"style":189},[1506],{"type":37,"value":1507},">",{"type":32,"tag":182,"props":1509,"children":1510},{"style":206},[1511],{"type":37,"value":1512}," (",{"type":32,"tag":182,"props":1514,"children":1515},{"style":189},[1516],{"type":37,"value":417},{"type":32,"tag":182,"props":1518,"children":1519},{"style":489},[1520],{"type":37,"value":1521}," MAX",{"type":32,"tag":182,"props":1523,"children":1524},{"style":206},[1525],{"type":37,"value":761},{"type":32,"tag":182,"props":1527,"children":1528},{"style":189},[1529],{"type":37,"value":430},{"type":32,"tag":182,"props":1531,"children":1532},{"style":206},[1533],{"type":37,"value":1534}," {{ this }})\n",{"type":32,"tag":182,"props":1536,"children":1537},{"class":184,"line":741},[1538],{"type":32,"tag":182,"props":1539,"children":1540},{"style":206},[1541],{"type":37,"value":1542},"  {% endif %}\n",{"type":32,"tag":182,"props":1544,"children":1545},{"class":184,"line":750},[1546],{"type":32,"tag":182,"props":1547,"children":1548},{"style":206},[1549],{"type":37,"value":912},{"type":32,"tag":182,"props":1551,"children":1552},{"class":184,"line":773},[1553,1557,1562,1567],{"type":32,"tag":182,"props":1554,"children":1555},{"style":189},[1556],{"type":37,"value":417},{"type":32,"tag":182,"props":1558,"children":1559},{"style":189},[1560],{"type":37,"value":1561}," *",{"type":32,"tag":182,"props":1563,"children":1564},{"style":189},[1565],{"type":37,"value":1566}," FROM",{"type":32,"tag":182,"props":1568,"children":1569},{"style":206},[1570],{"type":37,"value":1571}," events_with_signals;\n",{"type":32,"tag":33,"props":1573,"children":1574},{},[1575,1577,1583],{"type":37,"value":1576},"The incremental model runs hourly, processing the latest batch. Identity merge logic lives in a separate model (",{"type":32,"tag":40,"props":1578,"children":1580},{"className":1579},[],[1581],{"type":37,"value":1582},"models\u002Fcore\u002Ffct_identity_resolved.sql",{"type":37,"value":1262},{"type":32,"tag":172,"props":1585,"children":1587},{"className":174,"code":1586,"language":176,"meta":16,"style":16},"SELECT\n  e.event_id,\n  COALESCE(im_email.canonical_id, im_cookie.canonical_id) AS canonical_id,\n  e.event_timestamp\nFROM {{ ref('stg_events') }} e\nLEFT JOIN {{ ref('identity_map') }} im_email\n  ON e.email_hash IS NOT NULL\n  AND im_email.signal_type = 'email_sha256'\n  AND im_email.signal_value = e.email_hash\nLEFT JOIN {{ ref('identity_map') }} im_cookie\n  ON e.cookie_id IS NOT NULL\n  AND im_cookie.signal_type = 'cookie'\n  AND im_cookie.signal_value = e.cookie_id;\n",[1588],{"type":32,"tag":40,"props":1589,"children":1590},{"__ignoreMap":16},[1591,1598,1618,1673,1689,1711,1733,1759,1789,1825,1845,1869,1898],{"type":32,"tag":182,"props":1592,"children":1593},{"class":184,"line":185},[1594],{"type":32,"tag":182,"props":1595,"children":1596},{"style":189},[1597],{"type":37,"value":921},{"type":32,"tag":182,"props":1599,"children":1600},{"class":184,"line":212},[1601,1606,1610,1614],{"type":32,"tag":182,"props":1602,"children":1603},{"style":489},[1604],{"type":37,"value":1605},"  e",{"type":32,"tag":182,"props":1607,"children":1608},{"style":206},[1609],{"type":37,"value":935},{"type":32,"tag":182,"props":1611,"children":1612},{"style":489},[1613],{"type":37,"value":940},{"type":32,"tag":182,"props":1615,"children":1616},{"style":206},[1617],{"type":37,"value":298},{"type":32,"tag":182,"props":1619,"children":1620},{"class":184,"line":237},[1621,1626,1630,1635,1639,1643,1647,1652,1656,1660,1664,1668],{"type":32,"tag":182,"props":1622,"children":1623},{"style":489},[1624],{"type":37,"value":1625},"  COALESCE",{"type":32,"tag":182,"props":1627,"children":1628},{"style":206},[1629],{"type":37,"value":806},{"type":32,"tag":182,"props":1631,"children":1632},{"style":489},[1633],{"type":37,"value":1634},"im_email",{"type":32,"tag":182,"props":1636,"children":1637},{"style":206},[1638],{"type":37,"value":935},{"type":32,"tag":182,"props":1640,"children":1641},{"style":489},[1642],{"type":37,"value":1050},{"type":32,"tag":182,"props":1644,"children":1645},{"style":206},[1646],{"type":37,"value":47},{"type":32,"tag":182,"props":1648,"children":1649},{"style":489},[1650],{"type":37,"value":1651},"im_cookie",{"type":32,"tag":182,"props":1653,"children":1654},{"style":206},[1655],{"type":37,"value":935},{"type":32,"tag":182,"props":1657,"children":1658},{"style":489},[1659],{"type":37,"value":1050},{"type":32,"tag":182,"props":1661,"children":1662},{"style":206},[1663],{"type":37,"value":816},{"type":32,"tag":182,"props":1665,"children":1666},{"style":189},[1667],{"type":37,"value":596},{"type":32,"tag":182,"props":1669,"children":1670},{"style":206},[1671],{"type":37,"value":1672}," canonical_id,\n",{"type":32,"tag":182,"props":1674,"children":1675},{"class":184,"line":260},[1676,1680,1684],{"type":32,"tag":182,"props":1677,"children":1678},{"style":489},[1679],{"type":37,"value":1605},{"type":32,"tag":182,"props":1681,"children":1682},{"style":206},[1683],{"type":37,"value":935},{"type":32,"tag":182,"props":1685,"children":1686},{"style":489},[1687],{"type":37,"value":1688},"event_timestamp\n",{"type":32,"tag":182,"props":1690,"children":1691},{"class":184,"line":282},[1692,1696,1701,1706],{"type":32,"tag":182,"props":1693,"children":1694},{"style":189},[1695],{"type":37,"value":430},{"type":32,"tag":182,"props":1697,"children":1698},{"style":206},[1699],{"type":37,"value":1700}," {{ ref(",{"type":32,"tag":182,"props":1702,"children":1703},{"style":456},[1704],{"type":37,"value":1705},"'stg_events'",{"type":32,"tag":182,"props":1707,"children":1708},{"style":206},[1709],{"type":37,"value":1710},") }} e\n",{"type":32,"tag":182,"props":1712,"children":1713},{"class":184,"line":301},[1714,1719,1723,1728],{"type":32,"tag":182,"props":1715,"children":1716},{"style":189},[1717],{"type":37,"value":1718},"LEFT JOIN",{"type":32,"tag":182,"props":1720,"children":1721},{"style":206},[1722],{"type":37,"value":1700},{"type":32,"tag":182,"props":1724,"children":1725},{"style":456},[1726],{"type":37,"value":1727},"'identity_map'",{"type":32,"tag":182,"props":1729,"children":1730},{"style":206},[1731],{"type":37,"value":1732},") }} im_email\n",{"type":32,"tag":182,"props":1734,"children":1735},{"class":184,"line":318},[1736,1741,1746,1750,1754],{"type":32,"tag":182,"props":1737,"children":1738},{"style":189},[1739],{"type":37,"value":1740},"  ON",{"type":32,"tag":182,"props":1742,"children":1743},{"style":489},[1744],{"type":37,"value":1745}," e",{"type":32,"tag":182,"props":1747,"children":1748},{"style":206},[1749],{"type":37,"value":935},{"type":32,"tag":182,"props":1751,"children":1752},{"style":489},[1753],{"type":37,"value":60},{"type":32,"tag":182,"props":1755,"children":1756},{"style":189},[1757],{"type":37,"value":1758}," IS NOT NULL\n",{"type":32,"tag":182,"props":1760,"children":1761},{"class":184,"line":26},[1762,1767,1772,1776,1780,1784],{"type":32,"tag":182,"props":1763,"children":1764},{"style":189},[1765],{"type":37,"value":1766},"  AND",{"type":32,"tag":182,"props":1768,"children":1769},{"style":489},[1770],{"type":37,"value":1771}," im_email",{"type":32,"tag":182,"props":1773,"children":1774},{"style":206},[1775],{"type":37,"value":935},{"type":32,"tag":182,"props":1777,"children":1778},{"style":489},[1779],{"type":37,"value":1160},{"type":32,"tag":182,"props":1781,"children":1782},{"style":189},[1783],{"type":37,"value":1022},{"type":32,"tag":182,"props":1785,"children":1786},{"style":456},[1787],{"type":37,"value":1788}," 'email_sha256'\n",{"type":32,"tag":182,"props":1790,"children":1791},{"class":184,"line":683},[1792,1796,1800,1804,1808,1812,1816,1820],{"type":32,"tag":182,"props":1793,"children":1794},{"style":189},[1795],{"type":37,"value":1766},{"type":32,"tag":182,"props":1797,"children":1798},{"style":489},[1799],{"type":37,"value":1771},{"type":32,"tag":182,"props":1801,"children":1802},{"style":206},[1803],{"type":37,"value":935},{"type":32,"tag":182,"props":1805,"children":1806},{"style":489},[1807],{"type":37,"value":1167},{"type":32,"tag":182,"props":1809,"children":1810},{"style":189},[1811],{"type":37,"value":1022},{"type":32,"tag":182,"props":1813,"children":1814},{"style":489},[1815],{"type":37,"value":1745},{"type":32,"tag":182,"props":1817,"children":1818},{"style":206},[1819],{"type":37,"value":935},{"type":32,"tag":182,"props":1821,"children":1822},{"style":489},[1823],{"type":37,"value":1824},"email_hash\n",{"type":32,"tag":182,"props":1826,"children":1827},{"class":184,"line":707},[1828,1832,1836,1840],{"type":32,"tag":182,"props":1829,"children":1830},{"style":189},[1831],{"type":37,"value":1718},{"type":32,"tag":182,"props":1833,"children":1834},{"style":206},[1835],{"type":37,"value":1700},{"type":32,"tag":182,"props":1837,"children":1838},{"style":456},[1839],{"type":37,"value":1727},{"type":32,"tag":182,"props":1841,"children":1842},{"style":206},[1843],{"type":37,"value":1844},") }} im_cookie\n",{"type":32,"tag":182,"props":1846,"children":1847},{"class":184,"line":716},[1848,1852,1856,1860,1865],{"type":32,"tag":182,"props":1849,"children":1850},{"style":189},[1851],{"type":37,"value":1740},{"type":32,"tag":182,"props":1853,"children":1854},{"style":489},[1855],{"type":37,"value":1745},{"type":32,"tag":182,"props":1857,"children":1858},{"style":206},[1859],{"type":37,"value":935},{"type":32,"tag":182,"props":1861,"children":1862},{"style":489},[1863],{"type":37,"value":1864},"cookie_id",{"type":32,"tag":182,"props":1866,"children":1867},{"style":189},[1868],{"type":37,"value":1758},{"type":32,"tag":182,"props":1870,"children":1871},{"class":184,"line":733},[1872,1876,1881,1885,1889,1893],{"type":32,"tag":182,"props":1873,"children":1874},{"style":189},[1875],{"type":37,"value":1766},{"type":32,"tag":182,"props":1877,"children":1878},{"style":489},[1879],{"type":37,"value":1880}," im_cookie",{"type":32,"tag":182,"props":1882,"children":1883},{"style":206},[1884],{"type":37,"value":935},{"type":32,"tag":182,"props":1886,"children":1887},{"style":489},[1888],{"type":37,"value":1160},{"type":32,"tag":182,"props":1890,"children":1891},{"style":189},[1892],{"type":37,"value":1022},{"type":32,"tag":182,"props":1894,"children":1895},{"style":456},[1896],{"type":37,"value":1897}," 'cookie'\n",{"type":32,"tag":182,"props":1899,"children":1900},{"class":184,"line":741},[1901,1905,1909,1913,1917,1921,1925,1929,1933],{"type":32,"tag":182,"props":1902,"children":1903},{"style":189},[1904],{"type":37,"value":1766},{"type":32,"tag":182,"props":1906,"children":1907},{"style":489},[1908],{"type":37,"value":1880},{"type":32,"tag":182,"props":1910,"children":1911},{"style":206},[1912],{"type":37,"value":935},{"type":32,"tag":182,"props":1914,"children":1915},{"style":489},[1916],{"type":37,"value":1167},{"type":32,"tag":182,"props":1918,"children":1919},{"style":189},[1920],{"type":37,"value":1022},{"type":32,"tag":182,"props":1922,"children":1923},{"style":489},[1924],{"type":37,"value":1745},{"type":32,"tag":182,"props":1926,"children":1927},{"style":206},[1928],{"type":37,"value":935},{"type":32,"tag":182,"props":1930,"children":1931},{"style":489},[1932],{"type":37,"value":1864},{"type":32,"tag":182,"props":1934,"children":1935},{"style":206},[1936],{"type":37,"value":497},{"type":32,"tag":33,"props":1938,"children":1939},{},[1940,1942,1948],{"type":37,"value":1941},"This join logic executes deterministic hash matching. For probabilistic matching, add a separate ",{"type":32,"tag":40,"props":1943,"children":1945},{"className":1944},[],[1946],{"type":37,"value":1947},"fct_probabilistic_clusters",{"type":37,"value":1949}," model.",{"type":32,"tag":64,"props":1951,"children":1953},{"id":1952},"consent-and-privacy-gdpr-ccpa-compliance",[1954],{"type":37,"value":1955},"Consent and privacy: GDPR, CCPA compliance",{"type":32,"tag":33,"props":1957,"children":1958},{},[1959,1961,1966],{"type":37,"value":1960},"Identity resolution falls under GDPR Article 6 (lawful basis) and CCPA \"do not sell\" rules. Email hash qualifies as ",{"type":32,"tag":76,"props":1962,"children":1963},{},[1964],{"type":37,"value":1965},"personal data",{"type":37,"value":1967}," (CJEU 2019 ruling), requiring consent or legitimate interest.",{"type":32,"tag":33,"props":1969,"children":1970},{},[1971,1973,1979,1981,1986],{"type":37,"value":1972},"Under Consent Mode v2, if a user sets analytics_storage=denied, you cannot collect the email hash. In this case, rely on IP+UA fingerprint alone (legitimate interest scope — though CJEU interpretation remains contested). Best practice: add a ",{"type":32,"tag":40,"props":1974,"children":1976},{"className":1975},[],[1977],{"type":37,"value":1978},"consent_status",{"type":37,"value":1980}," column to ",{"type":32,"tag":40,"props":1982,"children":1984},{"className":1983},[],[1985],{"type":37,"value":156},{"type":37,"value":1987},", writing hash only from analytics_storage=granted events.",{"type":32,"tag":33,"props":1989,"children":1990},{},[1991,1993,1998],{"type":37,"value":1992},"For CCPA \"right to delete,\" implement cascade deletion by ",{"type":32,"tag":40,"props":1994,"children":1996},{"className":1995},[],[1997],{"type":37,"value":1050},{"type":37,"value":1999},":",{"type":32,"tag":172,"props":2001,"children":2003},{"className":174,"code":2002,"language":176,"meta":16,"style":16},"DELETE FROM identity_map WHERE canonical_id = 'uuid-123';\nDELETE FROM events WHERE canonical_id = 'uuid-123';\n",[2004],{"type":32,"tag":40,"props":2005,"children":2006},{"__ignoreMap":16},[2007,2045],{"type":32,"tag":182,"props":2008,"children":2009},{"class":184,"line":185},[2010,2015,2019,2024,2028,2032,2036,2041],{"type":32,"tag":182,"props":2011,"children":2012},{"style":189},[2013],{"type":37,"value":2014},"DELETE",{"type":32,"tag":182,"props":2016,"children":2017},{"style":189},[2018],{"type":37,"value":1566},{"type":32,"tag":182,"props":2020,"children":2021},{"style":206},[2022],{"type":37,"value":2023}," identity_map ",{"type":32,"tag":182,"props":2025,"children":2026},{"style":189},[2027],{"type":37,"value":443},{"type":32,"tag":182,"props":2029,"children":2030},{"style":206},[2031],{"type":37,"value":694},{"type":32,"tag":182,"props":2033,"children":2034},{"style":189},[2035],{"type":37,"value":453},{"type":32,"tag":182,"props":2037,"children":2038},{"style":456},[2039],{"type":37,"value":2040}," 'uuid-123'",{"type":32,"tag":182,"props":2042,"children":2043},{"style":206},[2044],{"type":37,"value":497},{"type":32,"tag":182,"props":2046,"children":2047},{"class":184,"line":212},[2048,2052,2056,2061,2065,2069,2073,2077],{"type":32,"tag":182,"props":2049,"children":2050},{"style":189},[2051],{"type":37,"value":2014},{"type":32,"tag":182,"props":2053,"children":2054},{"style":189},[2055],{"type":37,"value":1566},{"type":32,"tag":182,"props":2057,"children":2058},{"style":206},[2059],{"type":37,"value":2060}," events ",{"type":32,"tag":182,"props":2062,"children":2063},{"style":189},[2064],{"type":37,"value":443},{"type":32,"tag":182,"props":2066,"children":2067},{"style":206},[2068],{"type":37,"value":694},{"type":32,"tag":182,"props":2070,"children":2071},{"style":189},[2072],{"type":37,"value":453},{"type":32,"tag":182,"props":2074,"children":2075},{"style":456},[2076],{"type":37,"value":2040},{"type":32,"tag":182,"props":2078,"children":2079},{"style":206},[2080],{"type":37,"value":497},{"type":32,"tag":33,"props":2082,"children":2083},{},[2084,2086,2092],{"type":37,"value":2085},"Use foreign key constraints for cascade (BigQuery doesn't support them natively; Postgres\u002FSnowflake do). Alternative: soft delete (",{"type":32,"tag":40,"props":2087,"children":2089},{"className":2088},[],[2090],{"type":37,"value":2091},"deleted_at TIMESTAMP",{"type":37,"value":2093},") followed by batch purge.",{"type":32,"tag":512,"props":2095,"children":2097},{"id":2096},"tcf-22-vendor-mapping",[2098],{"type":37,"value":2099},"TCF 2.2 vendor mapping",{"type":32,"tag":33,"props":2101,"children":2102},{},[2103,2105,2111],{"type":37,"value":2104},"Under IAB TCF 2.2, identity resolution falls under \"Purpose 1 — Store and\u002For access information on a device\". If the user hasn't consented to your vendor list, cross-device linking is forbidden. In Roibase projects, we parse the TCF string in BigQuery, writing ",{"type":32,"tag":40,"props":2106,"children":2108},{"className":2107},[],[2109],{"type":37,"value":2110},"vendor_consent",{"type":37,"value":2112}," columns, then filter identity merges by consent:",{"type":32,"tag":172,"props":2114,"children":2116},{"className":174,"code":2115,"language":176,"meta":16,"style":16},"WHERE vendor_consent LIKE '%vendor_id=123%'\n",[2117],{"type":32,"tag":40,"props":2118,"children":2119},{"__ignoreMap":16},[2120],{"type":32,"tag":182,"props":2121,"children":2122},{"class":184,"line":185},[2123,2127,2132,2137],{"type":32,"tag":182,"props":2124,"children":2125},{"style":189},[2126],{"type":37,"value":443},{"type":32,"tag":182,"props":2128,"children":2129},{"style":206},[2130],{"type":37,"value":2131}," vendor_consent ",{"type":32,"tag":182,"props":2133,"children":2134},{"style":189},[2135],{"type":37,"value":2136},"LIKE",{"type":32,"tag":182,"props":2138,"children":2139},{"style":456},[2140],{"type":37,"value":2141}," '%vendor_id=123%'\n",{"type":32,"tag":33,"props":2143,"children":2144},{},[2145],{"type":37,"value":2146},"This logic prevents identity graph construction without consent — balancing compliance and data quality.",{"type":32,"tag":64,"props":2148,"children":2150},{"id":2149},"cdp-integration-segment-mparticle-rudderstack",[2151],{"type":37,"value":2152},"CDP integration: Segment, mParticle, Rudderstack",{"type":32,"tag":33,"props":2154,"children":2155},{},[2156,2158,2165,2167,2173,2175,2181,2182,2188],{"type":37,"value":2157},"Modern CDPs provide their own identity graphs, but typically as black boxes. Building your own pipeline gives you control — especially critical in ",{"type":32,"tag":539,"props":2159,"children":2162},{"href":2160,"rel":2161},"https:\u002F\u002Fwww.roibase.com.tr\u002Fen\u002Fretention-engineering-cdp",[543],[2163],{"type":37,"value":2164},"CDP & Retention Engineering",{"type":37,"value":2166}," work. Segment's ",{"type":32,"tag":40,"props":2168,"children":2170},{"className":2169},[],[2171],{"type":37,"value":2172},"identify()",{"type":37,"value":2174}," call merges ",{"type":32,"tag":40,"props":2176,"children":2178},{"className":2177},[],[2179],{"type":37,"value":2180},"userId",{"type":37,"value":132},{"type":32,"tag":40,"props":2183,"children":2185},{"className":2184},[],[2186],{"type":37,"value":2187},"anonymousId",{"type":37,"value":2189},", but which signal takes priority? In your resolution logic, make the priority explicit:",{"type":32,"tag":1108,"props":2191,"children":2192},{},[2193,2204,2214,2224,2235],{"type":32,"tag":1112,"props":2194,"children":2195},{},[2196,2202],{"type":32,"tag":40,"props":2197,"children":2199},{"className":2198},[],[2200],{"type":37,"value":2201},"customer_id",{"type":37,"value":2203}," (CRM) → most trusted",{"type":32,"tag":1112,"props":2205,"children":2206},{},[2207,2212],{"type":32,"tag":40,"props":2208,"children":2210},{"className":2209},[],[2211],{"type":37,"value":1367},{"type":37,"value":2213}," → deterministic",{"type":32,"tag":1112,"props":2215,"children":2216},{},[2217,2222],{"type":32,"tag":40,"props":2218,"children":2220},{"className":2219},[],[2221],{"type":37,"value":45},{"type":37,"value":2223}," → cross-session, not cross-device",{"type":32,"tag":1112,"props":2225,"children":2226},{},[2227,2233],{"type":32,"tag":40,"props":2228,"children":2230},{"className":2229},[],[2231],{"type":37,"value":2232},"cookie",{"type":37,"value":2234}," → shortest TTL",{"type":32,"tag":1112,"props":2236,"children":2237},{},[2238,2243],{"type":32,"tag":40,"props":2239,"children":2241},{"className":2240},[],[2242],{"type":37,"value":962},{"type":37,"value":2244}," → probabilistic fallback",{"type":32,"tag":33,"props":2246,"children":2247},{},[2248,2250,2256,2258,2263,2264,2270],{"type":37,"value":2249},"Encode this priority in dbt via a ",{"type":32,"tag":40,"props":2251,"children":2253},{"className":2252},[],[2254],{"type":37,"value":2255},"COALESCE()",{"type":37,"value":2257}," chain. Send only the final ",{"type":32,"tag":40,"props":2259,"children":2261},{"className":2260},[],[2262],{"type":37,"value":1050},{"type":37,"value":132},{"type":32,"tag":40,"props":2265,"children":2267},{"className":2266},[],[2268],{"type":37,"value":2269},"confidence_score",{"type":37,"value":2271}," to the CDP; keep merge logic on your side.",{"type":32,"tag":33,"props":2273,"children":2274},{},[2275],{"type":37,"value":2276},"Identity resolution is the foundational layer of modern marketing data architecture. Hash matching delivers deterministic certainty; probabilistic linking ensures coverage; household graph unlocks family-level segmentation. When your server-side pipeline — respecting consent and privacy rules — unifies these six signals, unique user accuracy improves by 40%, retention cohort errors vanish, incrementality tests become reliable. By building resolution logic in BigQuery + dbt + sGTM rather than trusting vendor black boxes, you control the graph entirely.",{"type":32,"tag":2278,"props":2279,"children":2280},"style",{},[2281],{"type":37,"value":2282},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":16,"searchDepth":237,"depth":237,"links":2284},[2285,2286,2289,2292,2293,2296],{"id":66,"depth":212,"text":69},{"id":142,"depth":212,"text":145,"children":2287},[2288],{"id":514,"depth":237,"text":517},{"id":551,"depth":212,"text":554,"children":2290},[2291],{"id":1087,"depth":237,"text":1090},{"id":1098,"depth":212,"text":1101},{"id":1952,"depth":212,"text":1955,"children":2294},[2295],{"id":2096,"depth":237,"text":2099},{"id":2149,"depth":212,"text":2152},"markdown","content:en:data:identity-resolution-six-signals-unified-customer.md","content","en\u002Fdata\u002Fidentity-resolution-six-signals-unified-customer.md","en\u002Fdata\u002Fidentity-resolution-six-signals-unified-customer","md",1785967476118]