Deduptio

Merging custom object records in Attio

The short answer

Attio's interface cannot merge custom object records: Merge Records exists on people and companies only. The REST API can. A POST /v2/objects/{object}/records/merge takes two record IDs from the same object and returns a new merged record. In the UI, the only option is to copy values across and delete the duplicate, which loses its notes, tasks and history.

UI and API side by side

QuestionAttio interfaceAttio REST API
Custom object recordsNo People and companies onlyYes Any object slug or ID in the path
Records per mergeTwoTwo: a primary and a secondary
Whose values win a conflictThe record on the rightThe primary; the secondary fills empty attributes
Record ID afterwardsNew record, new ID and URLNew record, returned as new_record_id
UndoNoNo
Who can do itMembers with write access to the objectA token with record_permission:read-write and object_configuration:read
StatusGenerally availablePartial Beta; Attio says small changes may still land

Per Attio's merge and delete records help article and the Merge two records API reference, checked October 28, 2026.

What the interface allows

Attio's help centre is direct about it: you can merge any two company or person records from a record page, and "it's not yet possible to merge records for Deals, Workspaces, Users, or custom objects." Open a record on a custom object, click the ⋮ icon in the top right, and Merge Records is not there.

What the interface does offer on every record page is Delete record. So without the API, resolving a duplicate custom object record means moving what matters by hand and deleting the rest:

  1. Open both records side by side and decide which one stays. Prefer the one that other records reference and that holds the most activity.
  2. Copy every attribute value the keeper is missing from the duplicate onto the keeper.
  3. Re-point any record-reference attributes on other objects that link to the duplicate. A deal or company that referenced the duplicate will otherwise lose the link.
  4. Add the keeper to any list the duplicate was in, and copy across list entry values such as a stage or owner.
  5. Open the duplicate, click ⋮, then Delete record, and confirm with Delete.

The cost is in step 5. Notes, tasks, comments and files on the deleted record do not move anywhere; they are deleted with it. Attio states that "once a record is deleted, it cannot be recovered by you or your team." If the duplicate has activity worth keeping, the interface has no way to keep it attached. The same trade-off applies to deals, covered in duplicate deals in Attio.

A middle option that loses nothing: add a checkbox or select attribute such as "Duplicate of" to the object, flag the loser, and filter it out of your views. The data stays messy, but no history is destroyed while you decide.

What the API allows

The merge endpoint is POST /v2/objects/{object}/records/merge, where {object}is the object's slug or UUID. For a custom object called Projects, that is usually /v2/objects/projects/records/merge. The body takes exactly two fields, both required:

{ "data": { "primary_record_id": "<uuid>", "secondary_record_id": "<uuid>" } }

Both records have to belong to the same object. Attio's reference page lists no object exclusions, and Deduptio runs this endpoint against deals and custom objects in production. Here is what the reference says happens:

Groups of three or more

A group of N duplicates is a chain of N − 1 calls. Merge records A and B, take the new_record_id, and pass it as the primary when you merge in C. Each hop consumes both of its inputs, so a script that crashes mid-chain must store progress after every hop. Restarting from the top would send IDs that no longer exist. The chain and its failure modes are covered in bulk merging duplicates in Attio.

What moves and what does not

The API reference only describes attribute values. For the interface merge, Attio's help centre says list entries, notes, folders and files, tasks, comments, call recordings and meetings are combined. From Deduptio's production use of the API endpoint, these are the parts to plan around:

Before you merge: things specific to custom objects

There is no natural match key

People have email addresses and companies have domains. A custom object has whatever you gave it. Before merging anything, decide what makes two records the same: an external ID from the source system, a contract number, or a combination such as the same parent company plus the same name. Name alone is weak evidence. Two Projects called "Website rebuild" under two different companies are two projects.

Clean the parents first

Custom objects usually reference people or companies. If one company exists twice, its projects split across the two copies and never look like duplicates of each other. Merge duplicate companies first, then scan the custom object; the pairs collapse into obvious matches. Deduptio's cross-object matching page explains the order.

Snapshot both records

Nothing in Attio brings back a merged-away record. Before each merge, read both records with GET /v2/objects/{object}/records/{record_id} and store the response. That copy is the only way to re-create the originals if the match was wrong, and it restores attribute values only. Notes and tasks have already moved to the merged record. More on what is and is not recoverable in how to undo a merge in Attio.

Stop new duplicates on the object

Attio lets you create custom unique attributes on custom objects. A unique attribute stops two records from holding the same value, so a CSV import or an API write updates the existing record instead of adding a second one. Two limits are worth knowing. Unique attributes are case-sensitive: "PRJ-104" and "prj-104" count as different values, so normalise the casing upstream. And an integration only benefits if it asserts records with PUT /v2/objects/{object}/records and that attribute as the matching attribute, rather than calling create. The endpoints for that are in Attio duplicate detection with the API.

Merging custom objects with Deduptio

Deduptio is our product. It merges custom object records through the same Attio merge endpoint, with the parts above handled: you write a match rule per object, a read-only scan groups the duplicates, and you review each group with a field-by-field preview before anything is written. Groups of three or more are chained hop by hop, the extra list entry is removed after the merge, and every merge is snapshotted for 24 hours. A rollback restores field values and associations; it does not restore notes, tasks, list memberships or comments, which Attio has already moved. The exact list is on the rollback page.

Limits, from plans: the Free plan gives 25 live merges a month, exact matching, and scans the first 10,000 records of each object. Pro is $39 a month for unlimited merges, fuzzy matching and objects up to 100,000 records. A custom object only appears in Deduptio if the person who connects Attio can see it.

Scan a custom object for duplicates

Connect your Attio workspace, write one match rule, and run a scan. Scans are read-only — you see every group and the reason it matched before anything is merged.

Start a free Attio duplicate scan

Related