중복 고객 병합
인증된 조직의 중복 고객을 기준 고객으로 병합합니다. 중복 고객의 식별자, 통화, 채팅을 기준 고객으로 옮긴 뒤 중복 고객을 영구 삭제합니다. 필드 충돌 시 기준 고객의 프로필을 유지합니다. 다만 기준 고객의 이름이나 메모가 비어 있거나 속성값이 없으면 중복 고객의 값을 채웁니다. 병합 후 메모리 저장 한도를 다시 적용합니다. 두 고객 ID는 달라야 하며, 같으면 400 INVALID_MERGE를 반환합니다. 두 고객 모두 조직에 있어야 합니다. 하나라도 없으면 404 CUSTOMER_NOT_FOUND를 반환합니다. 작업 중 오류가 발생하면 전체 변경을 되돌립니다.
curl --request POST \
--url https://client-api.tryvox.co/v3/customers/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"main_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"duplicate_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://client-api.tryvox.co/v3/customers/merge"
payload = {
"main_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"duplicate_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
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({
main_customer_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
duplicate_customer_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://client-api.tryvox.co/v3/customers/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://client-api.tryvox.co/v3/customers/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([
'main_customer_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'duplicate_customer_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
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://client-api.tryvox.co/v3/customers/merge"
payload := strings.NewReader("{\n \"main_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"duplicate_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\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://client-api.tryvox.co/v3/customers/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"main_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"duplicate_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.tryvox.co/v3/customers/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 \"main_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"duplicate_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"attributes": {},
"created_at": 123,
"updated_at": 123,
"identifiers": [
{
"id": "<string>",
"identifier_type": "<string>",
"identifier_value": "<string>",
"created_at": 123
}
],
"metadata": {},
"interaction_summary": {
"interaction_count": 123,
"first_interaction_at": 123,
"last_interaction_at": 123,
"last_interaction_id": "<string>",
"last_interaction_type": "<string>"
},
"name": "<string>",
"note": "<string>"
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": {
"field": "name",
"reason": "must not be blank"
}
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication is required.",
"details": {}
}
}{
"error": {
"code": "FORBIDDEN",
"message": "Permission denied.",
"details": {}
}
}{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found.",
"details": {
"resource": "agent"
}
}
}{
"error": {
"code": "CONFLICT",
"message": "The requested operation conflicts with current state.",
"details": {
"current_status": "draft"
}
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests.",
"details": {
"limit": 5,
"window_seconds": 1
}
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error.",
"details": {}
}
}{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "Service temporarily unavailable.",
"details": {}
}
}Authorizations
조직 API 키를 Authorization: Bearer <token> 형식으로 보냅니다.
Body
병합할 기준 고객과 중복 고객의 UUID입니다.
Response
성공 응답
식별자 검색, 생성, 수정, 병합 경로에서 반환하는 고객 응답입니다.
메모리는 고객 단건 조회가 반환하는 CustomerDetailResponse에만 있습니다.
고객 UUID입니다.
자동 추출한 고객 속성 값입니다. 이름에 해당하는 정의가 없어도 저장된 값을 유지합니다.
리소스 생성 시각입니다. 밀리초 단위 unix timestamp입니다.
리소스 수정 시각입니다. 밀리초 단위 unix timestamp입니다.
고객 신원 식별자 목록입니다.
Show child attributes
Show child attributes
고객 메타데이터입니다.
통화, 채팅, SMS 인터랙션의 집계 요약입니다.
Show child attributes
Show child attributes
고객 이름입니다.
고객 메모입니다.
Was this page helpful?
curl --request POST \
--url https://client-api.tryvox.co/v3/customers/merge \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"main_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"duplicate_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://client-api.tryvox.co/v3/customers/merge"
payload = {
"main_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"duplicate_customer_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
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({
main_customer_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
duplicate_customer_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'
})
};
fetch('https://client-api.tryvox.co/v3/customers/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://client-api.tryvox.co/v3/customers/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([
'main_customer_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'duplicate_customer_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
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://client-api.tryvox.co/v3/customers/merge"
payload := strings.NewReader("{\n \"main_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"duplicate_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\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://client-api.tryvox.co/v3/customers/merge")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"main_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"duplicate_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://client-api.tryvox.co/v3/customers/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 \"main_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"duplicate_customer_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"id": "<string>",
"attributes": {},
"created_at": 123,
"updated_at": 123,
"identifiers": [
{
"id": "<string>",
"identifier_type": "<string>",
"identifier_value": "<string>",
"created_at": 123
}
],
"metadata": {},
"interaction_summary": {
"interaction_count": 123,
"first_interaction_at": 123,
"last_interaction_at": 123,
"last_interaction_id": "<string>",
"last_interaction_type": "<string>"
},
"name": "<string>",
"note": "<string>"
}{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed.",
"details": {
"field": "name",
"reason": "must not be blank"
}
}
}{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication is required.",
"details": {}
}
}{
"error": {
"code": "FORBIDDEN",
"message": "Permission denied.",
"details": {}
}
}{
"error": {
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found.",
"details": {
"resource": "agent"
}
}
}{
"error": {
"code": "CONFLICT",
"message": "The requested operation conflicts with current state.",
"details": {
"current_status": "draft"
}
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests.",
"details": {
"limit": 5,
"window_seconds": 1
}
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "Internal server error.",
"details": {}
}
}{
"error": {
"code": "SERVICE_UNAVAILABLE",
"message": "Service temporarily unavailable.",
"details": {}
}
}