중복 고객 병합
인증된 조직의 중복 고객을 기준 고객으로 병합합니다. 중복 고객의 식별자, 통화, 채팅을 기준 고객으로 옮긴 뒤 중복 고객을 영구 삭제합니다. 기준 고객의 프로필은 유지합니다. 두 고객 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
성공 응답
목록 항목 형상에 메타데이터와 인터랙션 요약을 추가한 고객 응답입니다.
식별자 검색, 생성, 수정, 병합에서 반환합니다. CustomerListItemResponse에는 인터랙션 요약이 없으므로 목록 조회의 집계 비용을 줄입니다. 인터랙션 요약은 이 응답을 사용하는 경로에서만 제공합니다.
메모리는 이 응답에 없으며 CustomerDetailResponse에만 있습니다. 식별자 검색, 생성, 수정, 병합에서는 메모리를 불러오지 않습니다. 메모리 필드를 포함하면 실제 메모리가 없는 것처럼 보이는 빈 그룹을 반환하므로 고객 단건 조회에서만 제공합니다.
고객 UUID입니다.
자동 추출한 고객 속성 값입니다. 이름에 해당하는 정의가 없어도 저장된 값을 유지합니다.
리소스 생성 시각입니다. 밀리초 단위 unix timestamp입니다.
리소스 수정 시각입니다. 밀리초 단위 unix timestamp입니다.
고객 신원 식별자 목록입니다.
Show child attributes
Show child attributes
고객 메타데이터입니다.
통화와 채팅 인터랙션의 집계 요약입니다.
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": {}
}
}