Merging custom object records in Attio
Last checked October 28, 2026 · Deduptio is our product. Every claim about another tool comes from its public site or documentation and is linked in place — tell us if something is out of date.
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
| Question | Attio interface | Attio REST API |
|---|---|---|
| Custom object records | No People and companies only | Yes Any object slug or ID in the path |
| Records per merge | Two | Two: a primary and a secondary |
| Whose values win a conflict | The record on the right | The primary; the secondary fills empty attributes |
| Record ID afterwards | New record, new ID and URL | New record, returned as new_record_id |
| Undo | No | No |
| Who can do it | Members with write access to the object | A token with record_permission:read-write and object_configuration:read |
| Status | Generally available | Partial 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:
- Open both records side by side and decide which one stays. Prefer the one that other records reference and that holds the most activity.
- Copy every attribute value the keeper is missing from the duplicate onto the keeper.
- 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.
- Add the keeper to any list the duplicate was in, and copy across list entry values such as a stage or owner.
- 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:
- Primary wins conflicts.Where both records hold a value for the same attribute, the primary's value is kept. The secondary's value fills in only where the primary has none. Pick the primary by which values you want, not by age.
- A new record is created. The response carries a
new_record_idthat usually matches neither input. Both originals are flagged as merged and can no longer be read or written. - 200 or 202. A 200 means the merged record is readable now. A 202 means the merge is committed but still being applied; reading the new record returns a 404 with
merge_in_progressuntil it finishes. Poll with a delay; do not retry the merge. - Not idempotent. Sending the same request twice returns a 404 the second time, because the originals are already merged.
- 5 requests per second. The endpoint has its own rate limit. A cleanup of 2,000 pairs takes at least 400 seconds of merge calls alone, before polling and reads.
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:
- Notes, tasks, list memberships and incoming references move onto the new record. A company that referenced either original now references the merged record.
- List entries can double. If both originals sat in the same list, the merged record sits in it twice. Remove the extra entry after the merge, keeping the one with the entry values you want — see duplicate list entries.
- Meetings lose their link. A meeting linked to an original is not deleted, but it is no longer linked to the merged record, and no Attio API can re-link it. Write down which meetings were linked before you merge.
- Stored IDs go stale.If a billing tool, warehouse or Zapier step stores the custom object's record IDs, both old IDs are dead after the merge. Update the external system with
new_record_id.
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 scanRelated
- How to merge records in Attio — the interface merge for people and companies, step by step.
- Duplicate deals in Attio — the other object the merge button does not cover.
- Reviewing & merging · The Attio deduplication guide