curl --request POST \
--url https://api.attio.com/v2/objects/{object}/records/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"data": {
"primary_record_id": "891dcbfc-9141-415d-9b2a-2238a6cc012d",
"secondary_record_id": "bf071e1f-6035-429d-b874-d83ea64ea13b"
}
}
'import requests
url = "https://api.attio.com/v2/objects/{object}/records/merge"
payload = { "data": {
"primary_record_id": "891dcbfc-9141-415d-9b2a-2238a6cc012d",
"secondary_record_id": "bf071e1f-6035-429d-b874-d83ea64ea13b"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: {
primary_record_id: '891dcbfc-9141-415d-9b2a-2238a6cc012d',
secondary_record_id: 'bf071e1f-6035-429d-b874-d83ea64ea13b'
}
})
};
fetch('https://api.attio.com/v2/objects/{object}/records/merge', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.attio.com/v2/objects/{object}/records/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'primary_record_id' => '891dcbfc-9141-415d-9b2a-2238a6cc012d',
'secondary_record_id' => 'bf071e1f-6035-429d-b874-d83ea64ea13b'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.attio.com/v2/objects/{object}/records/merge"
payload := strings.NewReader("{\n \"data\": {\n \"primary_record_id\": \"891dcbfc-9141-415d-9b2a-2238a6cc012d\",\n \"secondary_record_id\": \"bf071e1f-6035-429d-b874-d83ea64ea13b\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.attio.com/v2/objects/{object}/records/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"primary_record_id\": \"891dcbfc-9141-415d-9b2a-2238a6cc012d\",\n \"secondary_record_id\": \"bf071e1f-6035-429d-b874-d83ea64ea13b\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.attio.com/v2/objects/{object}/records/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"primary_record_id\": \"891dcbfc-9141-415d-9b2a-2238a6cc012d\",\n \"secondary_record_id\": \"bf071e1f-6035-429d-b874-d83ea64ea13b\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"new_record_id": "f528bd86-8142-4359-9a8c-b651d50a27b1"
}
}{
"data": {
"new_record_id": "f528bd86-8142-4359-9a8c-b651d50a27b1"
}
}{
"status_code": 400,
"type": "invalid_request_error",
"code": "self_merge",
"message": "A record cannot be merged into itself."
}{
"status_code": 403,
"type": "auth_error",
"code": "unauthorized",
"message": "You do not have the necessary permissions to merge these records."
}{
"status_code": 404,
"type": "invalid_request_error",
"code": "not_found",
"message": "Record with ID \"891dcbfc-9141-415d-9b2a-2238a6cc012d\" not found."
}Merge two records
Merges two records of the same object together. Where both records have a value for the same attribute, the primary record’s value takes precedence.
Merging produces a new record, so the new_record_id returned will match neither of the records supplied in the request. Both of the original records are marked as merged and can no longer be read or written.
Large merges are completed asynchronously. A 200 response means the merged record is readable immediately. A 202 response means the merge has been accepted but is still being applied, and reading the merged record will return a 404 with the merge_in_progress error code until it completes.
This endpoint is not idempotent. Because both original records are marked as merged, repeating the same request returns 404.
This endpoint is rate limited to 5 requests per second.
This endpoint is in beta. We will aim to avoid breaking changes, but small updates may be made as we roll out to more users.
Required scopes: record_permission:read-write, object_configuration:read.
curl --request POST \
--url https://api.attio.com/v2/objects/{object}/records/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"data": {
"primary_record_id": "891dcbfc-9141-415d-9b2a-2238a6cc012d",
"secondary_record_id": "bf071e1f-6035-429d-b874-d83ea64ea13b"
}
}
'import requests
url = "https://api.attio.com/v2/objects/{object}/records/merge"
payload = { "data": {
"primary_record_id": "891dcbfc-9141-415d-9b2a-2238a6cc012d",
"secondary_record_id": "bf071e1f-6035-429d-b874-d83ea64ea13b"
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: {
primary_record_id: '891dcbfc-9141-415d-9b2a-2238a6cc012d',
secondary_record_id: 'bf071e1f-6035-429d-b874-d83ea64ea13b'
}
})
};
fetch('https://api.attio.com/v2/objects/{object}/records/merge', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.attio.com/v2/objects/{object}/records/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'data' => [
'primary_record_id' => '891dcbfc-9141-415d-9b2a-2238a6cc012d',
'secondary_record_id' => 'bf071e1f-6035-429d-b874-d83ea64ea13b'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.attio.com/v2/objects/{object}/records/merge"
payload := strings.NewReader("{\n \"data\": {\n \"primary_record_id\": \"891dcbfc-9141-415d-9b2a-2238a6cc012d\",\n \"secondary_record_id\": \"bf071e1f-6035-429d-b874-d83ea64ea13b\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.attio.com/v2/objects/{object}/records/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"data\": {\n \"primary_record_id\": \"891dcbfc-9141-415d-9b2a-2238a6cc012d\",\n \"secondary_record_id\": \"bf071e1f-6035-429d-b874-d83ea64ea13b\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.attio.com/v2/objects/{object}/records/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": {\n \"primary_record_id\": \"891dcbfc-9141-415d-9b2a-2238a6cc012d\",\n \"secondary_record_id\": \"bf071e1f-6035-429d-b874-d83ea64ea13b\"\n }\n}"
response = http.request(request)
puts response.read_body{
"data": {
"new_record_id": "f528bd86-8142-4359-9a8c-b651d50a27b1"
}
}{
"data": {
"new_record_id": "f528bd86-8142-4359-9a8c-b651d50a27b1"
}
}{
"status_code": 400,
"type": "invalid_request_error",
"code": "self_merge",
"message": "A record cannot be merged into itself."
}{
"status_code": 403,
"type": "auth_error",
"code": "unauthorized",
"message": "You do not have the necessary permissions to merge these records."
}{
"status_code": 404,
"type": "invalid_request_error",
"code": "not_found",
"message": "Record with ID \"891dcbfc-9141-415d-9b2a-2238a6cc012d\" not found."
}Authorizations
This API uses OAuth 2.0 with the authorization code grant flow.
Path Parameters
A UUID or slug of the object both records belong to.
"people"
Body
Show child attributes
Show child attributes
Response
Success
Success
Show child attributes
Show child attributes
Was this page helpful?