Prerequisites
Confirm each item before you build. A missing key or an unscoped list turns this recipe into a source of false positives. A false positive is a record the workflow flags as a duplicate when it is not one.- Plan: Plus or higher, which runs on the new Workflows engine.
- Integrations: Slack is connected to the workspace and has a channel the workflow can post to, such as
#crm-hygiene. - Objects and attributes: the Companies object has a populated
domainattribute, or the People object has a populatedemailattribute. Use whichever one you are deduping. The chosen key must be the field your team actually fills in, not an optional one. - A review list: a list named “Possible duplicate” exists on the same object. It needs at least a
Matched recordreference attribute and aReviewed?checkbox so a person can clear entries. See Records vs list entries for why a list is the right home for review state. - Access: the workflow runs under the workspace’s automation identity. Confirm in Permissions & workflow access that this identity can read the object and write to the list.
How it works
The workflow reads the new record’s dedup key. The dedup key is the one field you trust to tell records apart, such as a company domain. It then searches the same object for any other record that carries that key. It branches on the result. When a match exists, it copies the safe fields onto the older record and flags the new one for human review. When no match exists, the run stops for free. The workflow never auto-merges. A single key collision can still be two different real-world entities. A deliberate split is safer than a wrong merge. The blocks execute in this order:- Record created fires on a new Company or Person.
- Find records searches the same object for the matching key and excludes the new record’s own ID.
- If checks whether Find returned at least one record.
- On the match branch, Update record consolidates fields onto the existing record, Add record to list flags the new record for review, and the Slack block posts a heads-up.
- On the no-match branch, the If condition stops the run, which costs nothing.
Build steps
1
Add the Record created trigger
Create a new workflow and add the Record created trigger. Scope it to a single object. Run one copy for Companies and a separate copy for People, because the dedup key differs between them.
2
Find a record with the same key
Add a Find records block. Search the same object for any record whose key equals the new record’s key. Exclude the new record itself so a record never matches on its own value.
For People, set the filter to
email is {{trigger.record.email}}. Use one exact key, such as acme.com, rather than a partial name match. Normalize the key first, which means strip stray spaces and make the case consistent so two versions of the same value still match.3
Branch on whether a match exists
Add an If condition that checks whether Find returned anything. When the count is zero, the condition stops the run for free.
4
Consolidate safe fields onto the existing record
On the true branch, add an Update record block that targets the oldest match, which is the first record Find returned. Copy only fields that can safely be added: fill blank fields on the existing record from the new one. Never overwrite a populated field. Never delete the new record automatically.
5
Flag the new record for human review
Add an Add record to list block that puts the new record onto the “Possible duplicate” list with a pointer to its match. This is the safety valve: a person, not the workflow, decides the merge.
6
Post a Slack heads-up
Add a Slack block so the data owner sees the collision in real time rather than discovering it in a report.
Variable mapping
For People runs, the key variable is
trigger.record.email, for example jane@acme.com. See Variables & data passing for the full reference syntax.
Credit cost worked example
The Record created trigger, the Find records lookup, and the If condition are all free. A condition that stops the run costs nothing. Only the writes on the match branch cost credits:- Update record costs 1 credit.
- Add record to list costs 1 credit.
- Slack costs 1 credit.
32 × 3 = 96 credits a month, while the other 768 creates cost nothing. Compare that monthly total against your plan’s included allowance on Credits & pricing explained. This recipe adds no AI block, so the cost per run is fixed and easy to predict.
You can add a Classify record step later to score fuzzy matches. Fuzzy matches are records that look like the same entity but do not share an exact key. Gate that step behind the If so it runs only on collisions. AI steps cost a variable number of credits based on how much text they process. So sample about 10 records and read the per-run cost in the run viewer rather than assuming a fixed number.
Test plan
- Create a known duplicate. With the workflow live, create a new company
Acme Corpwith domainacme.comwhile anacme.comrecord already exists. This fires Record created. - Check Find. In run history, open the Find records step and confirm it returned exactly the older
acme.comrecord and excluded the new one. The value ofstep2.records.countshould be1. - Check the branch. The If condition should resolve true and continue.
- Check the writes. Confirm Update record filled only blank fields on the older record, Add record to list added the new record to “Possible duplicate” with the match pointer, and the Slack block posted to
#crm-hygiene. - Send a deliberately failing input. Create
Globex Incwith domainglobex.io, a domain nothing else uses. The run should reach If, resolve false, and stop. In run history the run shows 0 credits and no writes. If it still flags something, your Find filter is not using a unique key. - Confirm where to look. Open Runs, debugging & publishing to inspect each step’s inputs, outputs, and credit usage for both runs.
Failure modes
Variations
People by email and companies by domain
Run two copies of this workflow. For People, scope the Record created trigger to People and set the Find records filter toemail is {{trigger.record.email}}. Everything else stays the same: the If, the flag, and the Slack post. Do not try to handle both objects in one workflow, because the keys and consolidation fields differ.
Flag only, no consolidation
When your team does not trust automated field copying, remove the Update record step. Keep Find records, the If, Add record to list, and the Slack heads-up. This drops the per-flag cost to 2 credits and leaves every merge decision to a person reviewing the “Possible duplicate” list.See also
Source: Attio Help Center: Workflows overview. Last reviewed against the Attio Help Center, June 2026.