curl --request POST \
--url https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split \
--header 'Content-Type: application/json' \
--data '
{
"identifier_type": "anonymous_id",
"identifier_value": "anon_9f2c1e4b",
"reassign_events": true,
"reason": "Two visitors were merged by a shared-device alias."
}
'import requests
url = "https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split"
payload = {
"identifier_type": "anonymous_id",
"identifier_value": "anon_9f2c1e4b",
"reassign_events": True,
"reason": "Two visitors were merged by a shared-device alias."
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
identifier_type: 'anonymous_id',
identifier_value: 'anon_9f2c1e4b',
reassign_events: true,
reason: 'Two visitors were merged by a shared-device alias.'
})
};
fetch('https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split', 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.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split",
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([
'identifier_type' => 'anonymous_id',
'identifier_value' => 'anon_9f2c1e4b',
'reassign_events' => true,
'reason' => 'Two visitors were merged by a shared-device alias.'
]),
CURLOPT_HTTPHEADER => [
"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.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split"
payload := strings.NewReader("{\n \"identifier_type\": \"anonymous_id\",\n \"identifier_value\": \"anon_9f2c1e4b\",\n \"reassign_events\": true,\n \"reason\": \"Two visitors were merged by a shared-device alias.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split")
.header("Content-Type", "application/json")
.body("{\n \"identifier_type\": \"anonymous_id\",\n \"identifier_value\": \"anon_9f2c1e4b\",\n \"reassign_events\": true,\n \"reason\": \"Two visitors were merged by a shared-device alias.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"identifier_type\": \"anonymous_id\",\n \"identifier_value\": \"anon_9f2c1e4b\",\n \"reassign_events\": true,\n \"reason\": \"Two visitors were merged by a shared-device alias.\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"user_id": "ext_44882",
"new_contact_id": "cnt_01J8ZA1B2C3D4E5F6G7H8J9K",
"survivor_id": "cnt_01J8XF3T4W5Q6N7V8R9M0K1P",
"detached": {
"type": "anonymous_id",
"value": "anon_9f2c1e4b"
},
"reassigned_events": 132,
"remaining_identifiers": 2,
"audit_id": "caa_01J8ZD5F6G7H8J9K0L1M2N3P"
},
"meta": {
"request_id": "req_01J8Z9K3P4Q5R6S7T8U9V0W1X2",
"timestamp": "2026-08-19T12:00:00.000Z"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "<string>",
"status": 429,
"retry_after": 2
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}Split a mis-stitched identifier off a profile
Detaches one identifier (external_id or anonymous_id) that was wrongly stitched onto the canonical profile and re-materialises it as its own contact, optionally carrying the detached identity’s events across. Use to undo a bad identify/alias merge without a full unmerge. Requires owner/admin/developer + contacts:write; a 409 means the identifier is not on this profile.
curl --request POST \
--url https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split \
--header 'Content-Type: application/json' \
--data '
{
"identifier_type": "anonymous_id",
"identifier_value": "anon_9f2c1e4b",
"reassign_events": true,
"reason": "Two visitors were merged by a shared-device alias."
}
'import requests
url = "https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split"
payload = {
"identifier_type": "anonymous_id",
"identifier_value": "anon_9f2c1e4b",
"reassign_events": True,
"reason": "Two visitors were merged by a shared-device alias."
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
identifier_type: 'anonymous_id',
identifier_value: 'anon_9f2c1e4b',
reassign_events: true,
reason: 'Two visitors were merged by a shared-device alias.'
})
};
fetch('https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split', 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.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split",
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([
'identifier_type' => 'anonymous_id',
'identifier_value' => 'anon_9f2c1e4b',
'reassign_events' => true,
'reason' => 'Two visitors were merged by a shared-device alias.'
]),
CURLOPT_HTTPHEADER => [
"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.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split"
payload := strings.NewReader("{\n \"identifier_type\": \"anonymous_id\",\n \"identifier_value\": \"anon_9f2c1e4b\",\n \"reassign_events\": true,\n \"reason\": \"Two visitors were merged by a shared-device alias.\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split")
.header("Content-Type", "application/json")
.body("{\n \"identifier_type\": \"anonymous_id\",\n \"identifier_value\": \"anon_9f2c1e4b\",\n \"reassign_events\": true,\n \"reason\": \"Two visitors were merged by a shared-device alias.\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orbit.devotel.io/api/v1/cdp/profiles/by-user-id/{user_id}/identity-graph/split")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"identifier_type\": \"anonymous_id\",\n \"identifier_value\": \"anon_9f2c1e4b\",\n \"reassign_events\": true,\n \"reason\": \"Two visitors were merged by a shared-device alias.\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"user_id": "ext_44882",
"new_contact_id": "cnt_01J8ZA1B2C3D4E5F6G7H8J9K",
"survivor_id": "cnt_01J8XF3T4W5Q6N7V8R9M0K1P",
"detached": {
"type": "anonymous_id",
"value": "anon_9f2c1e4b"
},
"reassigned_events": 132,
"remaining_identifiers": 2,
"audit_id": "caa_01J8ZD5F6G7H8J9K0L1M2N3P"
},
"meta": {
"request_id": "req_01J8Z9K3P4Q5R6S7T8U9V0W1X2",
"timestamp": "2026-08-19T12:00:00.000Z"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "RATE_LIMITED",
"message": "<string>",
"status": 429,
"retry_after": 2
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"status": 123,
"details": {}
},
"meta": {
"request_id": "<string>",
"timestamp": "2023-11-07T05:31:56Z",
"docs_url": "<string>"
}
}Path Parameters
Body
Which stitched alias to peel off the profile.
external_id, anonymous_id The exact identifier value currently stitched to the profile.
Move the detached identity's events onto the new contact (default true).
Optional operator note recorded on the audit row.
Response
The split outcome — the new contact id, what was detached, and how many events moved.
The split outcome — the new contact id, what was detached, and how many events moved.