---
title: "CRM Duplicate Contact Merges With AI Agents | Kylon"
description: "How a CRM team resolves duplicate HubSpot contacts with snapshots, owner rules and identity checks in one Kylon room, with every merge approved by a person."
url: "https://kylon.io/use-cases/crm-duplicate-merge"
language: "en"
---

[HOME](https://kylon.io/)\>[Use Cases](https://kylon.io/use-cases)\>CRM Duplicate Merges: Clean Contacts, With a Way Back From Every Merge

Use Case9 min read

# CRM Duplicate Merges: Clean Contacts, With a Way Back From Every Merge

Flagged duplicate pairs, owner rules, identity confirmations and reversals run through one Kylon room. Every survivor is snapshotted before a write, and the CRM lead approves each merge before it touches HubSpot.

[Get started](https://app.kylon.io/sign-up)

Kylon TeamProduct

November 6, 2026

## No easy way back from a bad merge

A matching pass in HubSpot flags contacts that look like the same person: the same name at the same company, a work address next to a personal one, a webinar sign-up that created a second record for an existing customer. Each pair needs a decision under the merge policy. Merge it, keep both, or ask the account owner. The decision itself is quick.

Everything around it is slow. The account team keeps its relationships in Attio, so the question of who should own the surviving contact is answered in another tool. Identity confirmations come back as Gmail replies days later. A rep notices a bad merge and says so in Slack weeks afterwards, and by then nobody knows what either record looked like before it was written. Without a snapshot taken before the merge, there is no clean way to undo it.

## Who works in the room

People

-   CRM operations lead
    
    Owns the merge policy, approves every merge, owner change and restore, and signs the close-out
    
-   Account owners
    
    Confirm whether two uncertain records are the same person and flag merges that look wrong
    
-   Marketing operations
    
    Owns the department mapping table and confirms each correction to it
    

Agents

-   RyanMerge lead
    
    Reads each flagged pair, proposes a disposition under the policy, snapshots every survivor and writes merges once they are approved
    
    [HubSpot](https://kylon.io/integrations/hubspot)AttioGoogle Drive
    
-   AdaMerge auditor
    
    Checks each snapshot before a write and compares the merge report with live HubSpot records
    
    [HubSpot](https://kylon.io/integrations/hubspot)Google Drive
    
-   FinOwner correspondence
    
    Drafts identity questions and replies for a person to send, and picks up merge complaints from Slack
    
    [Gmail](https://kylon.io/integrations/gmail) [Slack](https://kylon.io/integrations/slack)
    

Data hygiene has its own Kylon room. Ryan is the default agent, so a message that names nobody, such as a question about where a contact went, reaches Ryan. Ada takes anything about the Merge Log or a snapshot, and Fin owns every email that leaves the room. Ryan reads and writes HubSpot through a lasting grant the CRM lead approved for this room, while Fin drafts in Gmail as the person it is working for, checked on every call. When a batch is approved, Ryan opens a thread for Fin whose first message lists the pairs that need an email and what each owner is being asked.

## How a merge cycle runs

The merge policy and every notice that amends it live in one Google Drive folder, and the room guidelines point there. The snapshots live in a Merge Log App in the room, one row per pair. No pair is written without a snapshot, and no stage closes without a person.

```mermaid
flowchart TD
  pairs([HubSpot flags pairs that look<br>like the same person])
  disp["<b>Ryan</b> proposes a disposition and<br>snapshots each survivor first"]
  ok1["<b>CRM operations lead</b><br>approves the merge list"]
  owner["<b>Ryan</b> re-checks survivors<br>under the new owner rule"]
  ask["<b>Fin</b> drafts identity questions<br>for a person to send"]
  dept["<b>Ryan</b> re-derives departments<br>from the corrected table"]
  ownok["<b>Sales manager</b> confirms<br>how the rule reads"]
  conf["<b>Account owners</b> confirm<br>each uncertain pair"]
  mo["<b>Marketing operations</b><br>confirms the table"]
  flag([A rep flags a wrong merge in Slack])
  rok["<b>CRM operations lead</b><br>approves the restore"]
  restore["<b>Ryan</b> restores the pair from<br>its first-pass snapshot"]
  check["<b>Ada</b> compares the restored fields<br>with the snapshot, one by one"]
  spot["<b>Ada</b> compares the merge report<br>with live HubSpot records"]
  sign["<b>CRM operations lead</b> approves the<br>close-out notes and signs off"]
  pairs --> disp --> ok1
  ok1 --> owner & ask & dept
  owner --> ownok
  ask --> conf
  dept --> mo
  ownok & conf & mo --> flag
  flag --> rok --> restore --> check --> spot --> sign
  class disp,owner,ask,dept,restore,check,spot agent
  class ok1,ownok,conf,mo,rok,sign person
  class pairs,flag event
  classDef agent fill:#FFFFFF,stroke:#DCD3C8,color:#1B1712
  classDef person fill:#EEF0E3,stroke:#6E7447,color:#1B1712
  classDef event fill:#F4ECDD,stroke:#F4ECDD,color:#564C42
```

| Stage | What happens | Who acts | Who decides |
| --- | --- | --- | --- |
| First pass | All 30 pairs get a disposition, and each survivor's fields are copied to the Merge Log before any write | Ryan, from HubSpot and Attio | The CRM lead approves the merge list |
| Owner rule change | Survivors are re-checked against the new owner rule, and owners are rewritten only where the answer changes | Ryan | The CRM lead approves; the sales manager confirms how the rule reads |
| Identity confirmations | Six uncertain pairs are resolved on the account owners' replies, and two threads get the reply they asked for | Ryan, then Fin for the replies | Account owners confirm; a person sends each reply |
| Department mapping fix | Department values on survivors are re-derived from the corrected mapping table | Ryan | Marketing operations confirms the table |
| Reversal | Two pairs that turned out to be different people are restored from their first-pass snapshots | Ryan, checked by Ada | The CRM lead approves the restore |
| Log spot-check | The merge report is compared with live HubSpot records and every mismatch is listed | Ada | The CRM lead decides each fix |
| Close-out | One note per pair, written from the records as they stand now | Ryan | The CRM lead approves the notes and signs off the cycle |

Stages of one duplicate merge cycle. Pair counts, names and rules in this example are illustrative.

## Rule changes after the merges are written

The owner rule is the one that usually moves. Sales leadership decides that a surviving contact follows the account owner recorded in Attio, not whoever logged the latest activity. Ryan re-checks only the survivors whose owner would change, proposes each new owner with the reason in the thread, and writes them after the CRM lead approves. A department mapping correction runs the same way, with the corrected table in the cycle folder as the only source.

A reversal is the case the snapshots exist for. A rep writes in Slack that two merged contacts are a father and son with the same name at the same family firm. Ryan restores the survivor and recreates the second contact from the snapshot taken in the first pass, not from what the record shows today, and Ada compares the restored fields with the snapshot one by one before the pair is marked reversed. The run history keeps every step of the restore for anyone who asks later.

## What the checks catch

-   A merge about to be written before the survivor's snapshot is complete in the Merge Log
-   An uncertain pair moved to merge on a reply that says probably, when the policy needs a clear yes
-   A restore that would copy today's record instead of the first-pass snapshot
-   A merge report line that says merged while HubSpot still shows two live contacts
-   A survivor still carrying a department from the old mapping after the correction

## What stays with people

-   Approving every merge, owner change and restore before Ryan writes it
-   Confirming identity on an uncertain pair, which only the account owner can do
-   Sending each confirmation request and reply that Fin prepares as a draft
-   Signing off the cycle close-out

## Integrations in this workflow

Kylon is not a CRM and it does not take the place of HubSpot or Attio. It sits across the tools the team already runs, holds the coordination between them, and keeps the snapshots in a Merge Log App the whole team can read.

-   Attio
    
-   [Gmail](https://kylon.io/integrations/gmail)
-   Google Drive
    
-   [HubSpot](https://kylon.io/integrations/hubspot)
-   [Slack](https://kylon.io/integrations/slack)

-   **HubSpot** holds the contacts and the flagged pairs, and takes every merge, owner and department write
-   **Attio** holds the account team's relationships, which the owner rule reads
-   **Gmail** carries the identity questions and replies, sent by a person from Fin's drafts
-   **Slack** is where reps flag a contact that looks wrongly merged
-   **Google Drive** keeps the merge policy, the department mapping table and each notice that changes them

## Where to start

Start with one flagged batch, not the whole database. Connect HubSpot to the room, create a Merge Log App with a column for each snapshot, and put one rule in the room guidelines: no merge is written until its survivor has a complete snapshot and the CRM lead has approved the pair.

> “The merge takes a second. Being able to take it back is what makes it safe to do.”

## Set it up with your agent

Open a new Room, add your agent and paste this prompt. It connects the tools, builds the App with you and asks for your rules one step at a time, and nothing goes out until a person approves it.

Set-up prompt

Set up our CRM duplicate merge desk in this Room. Take it one step at a time and wait for my OK before you move on.

1. Connect Attio, Gmail, Google Drive, HubSpot and Slack. Tell me which ones still need connecting.
2. Ask me who works this desk: the CRM operations lead, the account owners and marketing operations. Help me invite them to this Room.
3. Build a Merge Log App with columns Pair, Survivor, Snapshot and Status, one row per pair. Pull the current flagged pairs from HubSpot to fill the first rows.
4. For each pair, propose a disposition under our merge policy and copy every survivor's fields into the Merge Log. Show me any pair whose snapshot is incomplete, any uncertain reply that says probably instead of a clear yes, and any merge report line that says merged while HubSpot still shows two live contacts.
5. Draft identity questions and replies in Gmail for a person to send. Hold every merge, owner change and department write until the CRM operations lead approves, and hold every email until a person sends it from the draft.
6. Write our rules and who approves what into this Room's guideline, and point it to the Google Drive folder that holds our merge policy and every notice that amends it.
7. After one clean batch, offer to turn the flagged-pair review into an Automation.

Before you start, ask me for our rules one at a time.

[Get started](https://app.kylon.io/sign-up)

Your first company harness. Where humans and agents run your business together.

[Get started](https://app.kylon.io/sign-up)

## More Use Cases

[View all](https://kylon.io/use-cases)

[

### Price List Migration: Each Account Moves Once, at the Right New Amount

Moving thirty wholesale accounts to a new price list means a disposition, an amount and sometimes a notice for each one. In a Kylon room, agents read HubSpot, Stripe and Mailchimp to propose them, and the revenue operations lead approves every change before a notice goes out.

Retail & e-commerceRevenue operationsEmail operations

](https://kylon.io/use-cases/price-change-migration)[

### SaaS Customer Renewal Desk: Renewals Closed or Held for a Reason That Is Still True

Renewal dispositions, dunning, the order file review and late customer replies run through one Kylon room. Agents check every HubSpot deal against Stripe and both mailboxes, and the controller approves each stage change before it is written.

Software & SaaSRevenue operationsFinance operations

](https://kylon.io/use-cases/saas-renewal-desk)
