Skip to content

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

  1. System Salesforce
  2. System NetSuite
  3. Step Resolve identity
  4. Step Survivorship per field
  5. Step Golden record
  6. System Snowflake
Also Reverse ETL out

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. 1

    Each source is landed raw, unchanged

    So a survivorship decision can be revisited without re-extracting anything.

  2. 2

    Identity is resolved on several keys

    Registration number, domain, normalised name plus country, and a manual mapping table for the exceptions.

  3. 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. 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. 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. 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. 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-workflow tray-patterns

    Use 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. 2

    Resolve identity on more than email

    Email alone misses exactly the largest customers.

    Headless skills build-workflow

    Use 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. 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. 4

    Publish the record and make it referenced

    A 360 that only lives in the warehouse changes nothing operationally.

    Headless skills tray-gotchas

    Use 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. 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. 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)

Last reviewed September 2026.