Mark a contact dedup review as merged
curl --request PATCH \
--url https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"resolution": {
"keepContactId": "5f7b1c2e8a1d4e0012c3b4a5",
"mergedFields": [
"email",
"phoneNumber"
]
}
}
'import requests
url = "https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge"
payload = { "resolution": {
"keepContactId": "5f7b1c2e8a1d4e0012c3b4a5",
"mergedFields": ["email", "phoneNumber"]
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
resolution: {
keepContactId: '5f7b1c2e8a1d4e0012c3b4a5',
mergedFields: ['email', 'phoneNumber']
}
})
};
fetch('https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/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://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'resolution' => [
'keepContactId' => '5f7b1c2e8a1d4e0012c3b4a5',
'mergedFields' => [
'email',
'phoneNumber'
]
]
]),
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://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge"
payload := strings.NewReader("{\n \"resolution\": {\n \"keepContactId\": \"5f7b1c2e8a1d4e0012c3b4a5\",\n \"mergedFields\": [\n \"email\",\n \"phoneNumber\"\n ]\n }\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"resolution\": {\n \"keepContactId\": \"5f7b1c2e8a1d4e0012c3b4a5\",\n \"mergedFields\": [\n \"email\",\n \"phoneNumber\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"resolution\": {\n \"keepContactId\": \"5f7b1c2e8a1d4e0012c3b4a5\",\n \"mergedFields\": [\n \"email\",\n \"phoneNumber\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Contact dedup review marked as merged",
"data": {
"_id": "5f7b1c2e8a1d4e0012c3b4b0",
"organizationId": "5f7b1c2e8a1d4e0012c3b400",
"reviewSource": "fuzzy_match",
"status": "merged",
"resolvedAt": "2026-05-18T14:35:00.000Z"
}
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}Organizations
Mark a contact dedup review as merged
Marks the review as merged, merging the source contact into the candidate per the optional resolution payload, recording the resolving user, and writing an audit log entry. Emits socket updates so other clients refresh their dedup queues.
PATCH
/
api
/
organizations
/
{organizationId}
/
contact-dedup-reviews
/
{reviewId}
/
merge
Mark a contact dedup review as merged
curl --request PATCH \
--url https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"resolution": {
"keepContactId": "5f7b1c2e8a1d4e0012c3b4a5",
"mergedFields": [
"email",
"phoneNumber"
]
}
}
'import requests
url = "https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge"
payload = { "resolution": {
"keepContactId": "5f7b1c2e8a1d4e0012c3b4a5",
"mergedFields": ["email", "phoneNumber"]
} }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
resolution: {
keepContactId: '5f7b1c2e8a1d4e0012c3b4a5',
mergedFields: ['email', 'phoneNumber']
}
})
};
fetch('https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/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://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'resolution' => [
'keepContactId' => '5f7b1c2e8a1d4e0012c3b4a5',
'mergedFields' => [
'email',
'phoneNumber'
]
]
]),
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://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge"
payload := strings.NewReader("{\n \"resolution\": {\n \"keepContactId\": \"5f7b1c2e8a1d4e0012c3b4a5\",\n \"mergedFields\": [\n \"email\",\n \"phoneNumber\"\n ]\n }\n}")
req, _ := http.NewRequest("PATCH", 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.patch("https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"resolution\": {\n \"keepContactId\": \"5f7b1c2e8a1d4e0012c3b4a5\",\n \"mergedFields\": [\n \"email\",\n \"phoneNumber\"\n ]\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-instance.example.com/api/organizations/{organizationId}/contact-dedup-reviews/{reviewId}/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"resolution\": {\n \"keepContactId\": \"5f7b1c2e8a1d4e0012c3b4a5\",\n \"mergedFields\": [\n \"email\",\n \"phoneNumber\"\n ]\n }\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"message": "Contact dedup review marked as merged",
"data": {
"_id": "5f7b1c2e8a1d4e0012c3b4b0",
"organizationId": "5f7b1c2e8a1d4e0012c3b400",
"reviewSource": "fuzzy_match",
"status": "merged",
"resolvedAt": "2026-05-18T14:35:00.000Z"
}
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}{
"error": "Organization not found",
"details": "No organization exists with the provided id"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
application/json
Freeform resolution payload recorded on the review; for merges, may include fieldChoices (source/candidate per field) and other reviewer-chosen metadata persisted with the merge audit entry.
Response
Contact dedup review marked as merged
Available options:
true Show child attributes
Show child attributes
Example:
{
"_id": "5f7b1c2e8a1d4e0012c3b4b0",
"organizationId": "5f7b1c2e8a1d4e0012c3b400",
"sourceContactId": "5f7b1c2e8a1d4e0012c3b4a5",
"candidateContactId": "5f7b1c2e8a1d4e0012c3b4a7",
"reviewSource": "fuzzy_match",
"status": "needs_review",
"score": 86,
"thresholdSnapshot": {
"thresholdPercent": 90,
"reviewThresholdPercent": 70
},
"fieldBreakdown": {
"firstName": 100,
"lastName": 80,
"email": 75
},
"createdAt": "2026-05-18T14:30:00.000Z",
"updatedAt": "2026-05-18T14:30:00.000Z"
}
⌘I