Work snippetData quality

Duplicate contact merge across ServiceM8, HubSpot and Xero

How I would approach one customer existing three times for a 35-tech group, with a cross-system registry, scored candidate pairs, merges that keep history, and entry rules that stop the duplicates coming back.

Work snippet with example figures.

Area
Data quality
Tools
ServiceM8 · HubSpot · Xero · Airtable
Typical scope
US$1,800–3,200
Timeline
About 5 weeks · 4 fixed milestones

Context and systems map

A 35-tech HVAC and plumbing group with four branches. The same customers exist in ServiceM8 as clients, in HubSpot as companies and contacts, and in Xero as contacts. Each system has its own duplicates and none of them agree on names, addresses or who the billing contact is.

The systems in play

In the example a registry gives every real customer one master record with a link to each system, duplicates are merged with approval inside each system, and entry rules stop new duplicates being created.

Systems map: who uses what
SystemWhat it does for the business
ServiceM8Clients and job addresses; the working record for field staff.
HubSpotCompanies, contacts and deals; the sales and marketing record.
XeroContacts for invoices and statements; the billing record.
Cross-system registryOne row per real customer with the id in each system, a master name and a status. An Airtable base in the example.
Review queueCandidate pairs with a score, the evidence and a decision field.
Office manager and finance leadApprove merges. The finance lead owns the billing identity.

How the data moves

  1. Export from the three systems
  2. Normalise
  3. Match and score
  4. Review queue
  5. Approved merge
  6. Registry updated
  7. Entry rules prevent new duplicates

Problem

What the owner sees

  1. Statements sent to the wrong contact
  2. Marketing emails to customers who have just had a complaint
  3. Sales and billing that disagree on a customer’s name
  4. Reports that count one customer three times

Native sync copies a contact across but does not decide whether it is the same customer. A one-off tidy fixes the problem for a month. The lasting fix is a registry, merge rules that keep history, and rules at the point of entry so the same customer cannot be created twice.

Where the drift starts
Everyday situationWhat goes wrong
Same company with two spellingsTwo clients, two jobs lists, two Xero contacts
Billing contact differs from the site contactStatement goes to the tenant instead of the owner
Person works for two companiesOne HubSpot contact has two names and two emails
Phone formats differDuplicates are missed by an exact match
Merged in one system onlyThe other systems recreate the merged record from the sync
Deleted instead of mergedHistory is lost and the number reused

Approach

Four steps, in this order. Each one ends with a result that is checked.

  1. LookRead-only export of all three systems with counts, blanks and a first pass at likely duplicates.
  2. Agree the rulesMatch keys, survivorship, who approves, and the order of merge across systems are written down.
  3. Match and reviewCandidate pairs are scored and reviewed by a person. Nothing is merged on score alone.
  4. Merge and protectApproved merges run system by system with the registry updated, then entry rules and a weekly duplicate report keep it clean.
Rules agreed in writing (example settings)
ItemExample setting
Match keys, in orderTax ID, then email domain with normalised name, then phone, then name and postcode
Score bandsAbove 95 listed as likely; 70 to 95 as possible; below 70 not shown
SurvivorThe record with the most history; the billing identity is always taken from Xero
Fields that surviveName and tax ID from Xero, site details from ServiceM8, marketing consent from HubSpot
ApprovalA person approves every merge; none are automatic
Order of mergeXero first, then ServiceM8, then HubSpot, so billing is never left pointing at a removed record
HistoryMerged, never deleted, so invoices and jobs follow the survivor
Entry rulesSearch before create in each system, and a daily list of new near-matches

Flow and data mapping

The registry is the map between systems. The tables show what is matched and which system wins each field.

Match and merge sequence
StepActionOutputOwner
1Export and normalise names, phones, emails, addressesClean comparison setManaz Afzal
2Score pairs within and across systemsCandidate pairsManaz Afzal
3Review each pairMerge, keep apart or linkOffice manager
4Merge in XeroOne billing contactFinance lead
5Merge in ServiceM8One client with all jobsOffice manager
6Merge in HubSpotOne company with all contactsSales lead
7Update the registryOne row, three idsManaz Afzal
Field survivorship (example settings)
FieldWinning systemReason
Legal name and tax IDXeroUsed on invoices and statements
Billing address and emailXeroWhere documents are sent
Site address and access notesServiceM8Where the work happens
Contact person for the siteServiceM8Updated by field staff
Marketing consent and sourceHubSpotCompliance record
Lifecycle stageHubSpotSales record
Payment termsXeroCredit decision

Edge cases handled

Agreed in advance with the finance lead and the operations manager, and tested before go-live.

Edge cases and how each is handled
SituationHow it is handled
Two companies with the same ownerKept as separate customers and linked by a group field
Customer renamed after a sale of the businessMaster name updated, previous name kept as an alias
Same phone, different companiesNot merged; shown as a shared phone for review
Contact has changed companyMoved with a dated note, not merged into the new company
Merge would join different tax IDsBlocked and listed for the finance lead
Duplicate with open invoices in bothMerged only after the invoices are checked, so statements stay right
Sync recreates a merged recordRegistry id blocks the create; the sync reads the registry first
Customer asks not to be marketed toConsent is preserved from the record with the opt-out

Worked example

The tables below show a first pass for an example group. They show the shape of the checks, not a client result.

Candidate pairs after scoring (example figures)
SystemRecordsLikely duplicatesPossible duplicatesRecords after merge
ServiceM83,1002121482,888
HubSpot2,7401671212,573
Xero2,480131882,349
A candidate pair with evidence (example data)
FieldRecord ARecord B
NameCustomer A Property GroupCustomer A Property Grp.
Tax IDSameSame
Email domaincustomer-a.examplecustomer-a.example
Phone0400 000 111+61 400 000 111
Postcode30003000
Score96Likely: approve
Registry row after a merge (example data)
Registry fieldValue
Master nameCustomer A Property Group
Xero idSurvivor, with 2 merged ids in the history
ServiceM8 idSurvivor, with 1 merged id
HubSpot idSurvivor, with 1 merged id
AliasesCustomer A Property Grp.
StatusMerged and checked
Weekly duplicate report (example settings)
SectionContent
New near-matchesCreated this week with a score above 70
Open review itemsPairs awaiting a decision, oldest first
Blocked mergesDifferent tax ID or consent conflict

Monitoring and alerting

After the clean-up, the job is to keep it clean. The registry is checked daily, and the entry rules produce a short list rather than a long report.

What is watched, and who hears about it
SignalThresholdAlert goes toFirst action
New near-match createdScore above 70Office manager daily listMerged, linked or marked different
Registry mismatchA system id not in the registryManaz AfzalRegistry row created or record merged
Sync recreates a merged recordAnyFinance lead and Manaz AfzalRecord merged again, rule corrected
Review queue ageOlder than 5 business daysOffice managerPairs decided
Merge job failureAny failed mergeManaz AfzalStopped, failed record shown, re-run alone
Duplicate rateAbove 1% of records in any systemOwner monthlyEntry rules reviewed

Test plan

Every check has a written pass condition and a written fail condition before it is run. A FAIL stops the next step until it is cleared and re-run.

Test plan with PASS and FAIL conditions
IDCheckMethodPASS whenFAIL when
T1NormalisationFifty known pairs with different spellingsAll pairs scored above 70Any missed pair
T2False matchFifty known different customersNone above 95Any above 95
T3Survivor rulesMerge a test pairEach field comes from the named systemAny field from the wrong system
T4HistoryCheck invoices and jobs after a mergeAll follow the survivorAny left behind
T5ConsentMerge a pair with an opt-outOpt-out keptOpt-out lost
T6Order of mergeRun Xero, ServiceM8, HubSpot on test dataNo record points to a removed oneAny dangling reference
T7Recreate guardCreate a merged customer again in a testBlocked by the registryCreated
T8CountsRecords before and after against the planEqual, difference equals mergesAny other difference

Merge run and rollback

Merges run in batches of 50. Before each batch the records are exported, so a batch can be reviewed and, where a system allows it, reversed.

Batch runbook and rollback triggers
StepOwnerGate to continueRollback trigger
Export before the batchManaz AfzalFile saved and countedExport incomplete
Merge in XeroFinance leadT4 on five spot checksAny invoice not following the survivor
Merge in ServiceM8Office managerJob counts equalAny job lost
Merge in HubSpotSales leadContact and deal counts equalAny consent lost
Registry updatedManaz AfzalT8 passesCounts do not tie
RollbackOwnerBatch stopped, records restored from the export where the system allows, otherwise recreated and relinkedDecision recorded with the reason

Scope and milestones

A fixed scope agreed in writing before anything starts. Each milestone is paid when you sign off its deliverable.

Scope: what a project like this covers
AreaIncluded
Systems AuditRead-only export of all three systems with counts and a first pass at likely duplicates, a 45-minute call, written findings and a fixed quote
RegistryOne row per customer with ids and master fields
Matching and scoringRules and a review queue
MergesBatches in Xero, ServiceM8 and HubSpot with approval
Survivorship rulesA signed field-by-field table
Entry rulesSearch before create, plus a daily near-match list
Duplicate reportA weekly list and a monthly rate
HandoverWritten SOPs, a recorded handover video and files you own, plus 14 days of fixes after go-live
Not includedTax filing and statutory returns.
Also outside the scopeData enrichment or purchased lists. Marketing campaigns. Changing which systems you use. Software subscriptions (billed to you by the vendors).
Fixed milestones
MilestoneDeliverableTimingShare
M1 Audit and rulesExport, fixed quote, rules in writingWeek 120%
M2 Match and reviewRegistry built, queue populated and reviewedWeeks 2 to 330%
M3 MergesBatches merged in all three systems and checkedWeek 435%
M4 Protect and handoverEntry rules, weekly report, SOPs, handover video, 14 days of fixesWeek 515%

Typical scope for this kind of project: US$1,800–3,200

About 5 weeks across 4 fixed milestones. The Systems Audit (US$300, fixed) comes first and confirms the scope.

Describe what is going wrong between your job system and your books, and I will say where I would look first.

Send a short note through the form on the home page. I will reply with where I would start, and whether the US$300 Systems Audit is the right first step.

Hire me on Upwork (opens in a new tab)Hire me on Freelancer (opens in a new tab)