Integration · Data operations
How to build a customer 360 and master data sync
Four systems each hold a different company name for the same customer and every report needs a manual reconciliation. What follows is the model behind a golden record, the prompts that build it, and what changes in production.
Built with Tray Headless
- System Salesforce
- System NetSuite
- Step Resolve identity
- Step Survivorship per field
- Step Golden record
- System Snowflake
Identity resolution runs on several keys before survivorship decides anything, and the golden record is published back rather than kept in the warehouse.
The short answer
What is a customer 360?
There are four parts to a customer 360: identity resolution on several keys rather than on email alone, a survivorship order chosen per attribute rather than per system, a published golden record with a stable id every system can point at, and a stewardship queue for the matches that are genuinely ambiguous. The part teams get wrong is picking a winning system. The CRM has the best contacts and the ERP has the best legal entity, so a rule that says the CRM always wins is wrong about half the fields.
What matters here
- Resolve on several keys. Email alone misses subsidiaries, rebrands and every customer with more than one entity.
- Choose survivorship per attribute, not per system. The CRM has the best contacts and the ERP has the best legal entity.
- Publish a stable golden id and make systems reference it. A 360 that only exists in the warehouse changes nothing operationally.
- Keep a stewardship queue. Some matches are genuinely ambiguous and guessing at those is how two real customers get merged.
- Record which source won each field. Without it a disputed value has no answer and the argument repeats monthly.
Who this is for
You run data operations or enterprise architecture. Several systems each hold part of the customer record, none of them agree, and every cross-system report starts with a reconciliation.
How it works in practice
The sequence, from four systems disagreeing to one record everybody can use.
- 1
Each source is landed raw, unchanged
So a survivorship decision can be revisited without re-extracting anything.
- 2
Identity is resolved on several keys
Registration number, domain, normalised name plus country, and a manual mapping table for the exceptions.
- 3
Survivorship is applied per attribute
Legal name from the ERP, contacts from the CRM, usage from the product, each because it is the best source for that field.
- 4
Ambiguous matches go to a steward
Above a confidence band it merges, below it does not, and the middle waits for a person.
- 5
A golden record is published with a stable id
And written back, so systems reference it rather than each keeping their own version.
- 6
Every field records which source won
So a disputed value has an answer rather than starting an argument.
What a customer 360 is made of
Four, and the second is where most master data projects fail.
Multi-key identity resolution
Registration number, domain, normalised name and country, plus a manual mapping for the cases no rule catches.
Per-attribute survivorship
A source order per field instead of per system, because no single system is best at everything.
A published golden record
A stable id written back to the sources, so the 360 is operational instead of a warehouse table nobody references.
A stewardship queue
For matches in the middle band. Auto-merging an ambiguous pair joins two real customers, and unpicking that is worse than the original problem.
The Tray Headless prompts
Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.
Once per project, run
/tray-workflows:set-workspace
to pick the workspace these build in. Point it at a sandbox first.
- 1
Start here: find out which source is best at what
The survivorship order is the whole design and it is field by field.
Headless skills
build-workflowtray-patternsUse build-workflow. The systems in play are Salesforce, NetSuite and Snowflake, or whatever we run in those seats. For each of these attributes, tell me which system actually holds the most reliable value: legal entity name, trading name, registration number, billing address, primary contact, industry, employee count, parent company. Do not assume the CRM wins. It usually has the best contacts and the worst legal entity, because nobody updates a legal name in a CRM until an invoice bounces.
- 2
Resolve identity on more than email
Email alone misses exactly the largest customers.
Headless skills
build-workflowUse build-workflow. Resolve identity in this order, each producing a confidence: 1. Company registration number where we hold it. Definitive. 2. Email or website domain, with generic domains excluded and subdomains reduced. 3. Normalised name plus country: lowercase, punctuation stripped, legal suffixes removed. 4. A manual mapping table for the exceptions, which will always exist and should be first-class rather than a workaround. Above 0.95 merges automatically. Below 0.80 does not. The band between goes to a steward. Never auto-merge on name alone. Two companies with similar names in the same country are common, and merging two real customers is far worse than leaving them separate. - 3
Choose survivorship per attribute
No system is best at everything.
Build the survivorship table per attribute, not per system: legal name ERP, then registry, then CRM trading name CRM, then website registration number registry, then ERP billing address ERP only primary contact CRM only industry enrichment, then CRM employee count enrichment, most recent parent company registry, then CRM Record which source supplied each field on the golden record. Without that, a disputed value has no answer and the same argument happens every quarter. Where the chosen source is empty, fall through the order instead of leaving the field blank. An empty golden record field sends people back to the source systems, which defeats the point.
- 4
Publish the record and make it referenced
A 360 that only lives in the warehouse changes nothing operationally.
Headless skills
tray-gotchasUse tray-gotchas, then publish the golden record with a stable id that never changes, even when the underlying records merge. Write that id back to every source system in a dedicated field. That is what turns this from a warehouse table into something operational: any system can join on it, and a report stops needing a reconciliation step. Handle these: A merge in a source system, which must not change the golden id A demerger, where one golden record has to split, which needs a steward rather than a rule A new source arriving later, which should be mapped in instead of triggering a rebuild A record deleted at source, which soft deletes on the golden record instead of vanishing
- 5
Steward the middle, and measure the match
Because the ambiguous band is where the damage happens.
Build the stewardship queue: both candidate records side by side, the matching evidence, the confidence, and one action to merge or separate. Feed every decision back so the thresholds tune against real outcomes. Report weekly: match rate by key, queue size and age, steward decisions that overturned an auto-merge, records with no golden id at all, and attributes most often disputed. That last one usually points at a survivorship order that is wrong rather than at bad data, and it is the cheapest thing to fix.
- 6
Validate, then hand the survivorship table over
Because which source is authoritative is a business decision.
Run the per-step schema checks and the whole-workflow audit before this touches production. Run in report-only mode for a fortnight, resolving and scoring without merging anything. Then open the same workflow in Tray Build so data operations can amend the survivorship order and the confidence bands in the visual canvas. Which system is authoritative for an attribute is a business decision and it changes when systems do.
What it connects to
Several sources, one record, and the ids written back so it is actually used.
Salesforce
Read accounts and contacts, and write the golden id back so reports can join on it.
Reads and writes
NetSuite
Read the legal entity, billing address and registration number, which is usually the best source for all three.
Reads and writes
Snowflake
Hold the raw sources, the resolution logic and the published golden record.
Reads and writes
Clearbit
Fill industry, size and parent company where no internal system holds a reliable value.
Reads
Zendesk
Write the golden id onto the organisation, so support volume can be joined to the customer without a name match.
Writes
Slack
Post the stewardship queue to the team that owns customer data, instead of hoping they open a dashboard.
Writes
Same build, other stacks
The design does not change if you run something else in one of these seats. The same prompts build it against Microsoft Dynamics 365, SAP S/4HANA, Google BigQuery, Microsoft Teams, Jira or HubSpot.
Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.
Running it in production
Everything downstream joins on this. A wrong merge propagates everywhere at once.
This runs as infrastructure, not as a script
Resolution across several sources and the write-back of golden ids run on the same engine, with a history of every merge decision.
Every field records its source
Which system supplied each value and when. A disputed attribute has an answer instead of starting a quarterly argument.
Credentials live in the workspace, never in the repo
Assembling a customer record means reading the full customer view from several systems at once. Each source is scoped and separately rotatable, so a compromise in one is not a compromise of the record.
Data operations own the survivorship order
The per-attribute source order and confidence bands open in Tray Build, owned by the team that fields the disputes.
Merges are reversible
Both original records retained with the evidence. Merging two real customers is the expensive failure here, and it needs an undo.
Questions people ask
Why not pick one system as the master?
Because no system is best at everything. The CRM usually has the best contacts and the worst legal entity, since nobody updates a legal name in a CRM until an invoice bounces.
Why resolve on more than email?
Because email and domain matching misses subsidiaries, rebrands and any customer with several entities, which is exactly the set of largest customers you most need resolved.
Why publish the golden id back to the sources?
Because a 360 that only exists in the warehouse changes nothing operationally. Writing the id back is what lets any system join on it and removes the reconciliation step from every report.
What goes in the stewardship queue?
Matches in the middle confidence band. Auto-merging an ambiguous pair joins two real customers, and unpicking that afterwards is considerably worse than leaving them separate.
Why record which source won each field?
Because otherwise a disputed value has no answer and the same argument recurs every quarter. It also shows when a survivorship order is simply wrong.
Vibe-coding app guides
Vibe-code an entire app with Helix
This moves the data between systems. It does not give anybody a screen to work in. Build that app in Claude Code, Codex or Cursor, then deploy and run it governed on Tray Helix. Same kind of guide, same kind of prompts.
How to build a lightweight CRM (opens helix.tray.ai in a new tab)
Related guides
Data operations
How to build reverse ETL from the warehouse
Push modelled data back into the tools people work in, syncing deltas, respecting field ownership, and never overwriting a human. The prompts that build it.
Data operations
How to build a CRM to warehouse sync
Capture history instead of current state, handle deletes and field changes, land raw then model, and prove the row counts. The Headless prompts that build it.
Platform engineering
How to build an API facade
Give consumers one contract instead of six systems, absorb upstream changes rather than leaking them, and keep the caller identity intact. The prompts.
Last reviewed September 2026.