Detach Contact Company
curl --request DELETE \
--url https://app.cometly.com/public-api/v1/contacts/{id}/company \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.cometly.com/public-api/v1/contacts/{id}/company"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.cometly.com/public-api/v1/contacts/{id}/company', 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://app.cometly.com/public-api/v1/contacts/{id}/company",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.cometly.com/public-api/v1/contacts/{id}/company"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://app.cometly.com/public-api/v1/contacts/{id}/company")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.cometly.com/public-api/v1/contacts/{id}/company")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": 123,
"company_id": null,
"message": "<string>"
}Contacts
Detach Contact Company
Detach a contact from its current company
DELETE
/
public-api
/
v1
/
contacts
/
{id}
/
company
Detach Contact Company
curl --request DELETE \
--url https://app.cometly.com/public-api/v1/contacts/{id}/company \
--header 'Authorization: Bearer <token>'import requests
url = "https://app.cometly.com/public-api/v1/contacts/{id}/company"
headers = {"Authorization": "Bearer <token>"}
response = requests.delete(url, headers=headers)
print(response.text)const options = {method: 'DELETE', headers: {Authorization: 'Bearer <token>'}};
fetch('https://app.cometly.com/public-api/v1/contacts/{id}/company', 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://app.cometly.com/public-api/v1/contacts/{id}/company",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://app.cometly.com/public-api/v1/contacts/{id}/company"
req, _ := http.NewRequest("DELETE", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.delete("https://app.cometly.com/public-api/v1/contacts/{id}/company")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.cometly.com/public-api/v1/contacts/{id}/company")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"id": 123,
"company_id": null,
"message": "<string>"
}Overview
This endpoint detaches a contact from its company, leaving it with no company. In the same transaction, the contact’s conversions, touchpoints, and visit metadata are re-stamped with anull company id, so company-level reports and the Companies dataset company_id columns in the data warehouse follow immediately.
There is no request body — the contact id in the path is the whole request.
This call is idempotent: calling it on a contact that already has no company returns a normal 200, not an error.
Path Parameters
integer
required
The unique identifier of the contact to detach. Merged profile aliases are automatically resolved to the current canonical contact — the response’s
id is the surviving contact.Response
Success Response
integer
The unique identifier of the contact (after resolving merged-profile aliases).
null
Always
null after a successful detach.Error Response
string
Error description explaining what went wrong.
Example Requests
curl -X DELETE "https://app.cometly.com/public-api/v1/contacts/12345/company" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json"
const contactId = 12345;
const response = await fetch(`https://app.cometly.com/public-api/v1/contacts/${contactId}/company`, {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json'
}
});
const data = await response.json();
console.log('Detached company:', data);
<?php
$contactId = 12345;
$url = 'https://app.cometly.com/public-api/v1/contacts/' . $contactId . '/company';
$headers = [
'Authorization: Bearer YOUR_API_KEY',
'Accept: application/json'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch);
?>
import requests
contact_id = 12345
url = f'https://app.cometly.com/public-api/v1/contacts/{contact_id}/company'
headers = {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json'
}
response = requests.delete(url, headers=headers)
result = response.json()
Status Codes
| Status Code | Description |
|---|---|
| 200 | Contact successfully detached (also returned as a no-op when the contact already had no company) |
| 401 | Missing or invalid API key |
| 403 | API key doesn’t have permission or subscription is inactive |
| 404 | Contact not found |
| 422 | Invalid contact ID provided |
| 429 | Too many requests - rate limit exceeded. See Rate Limiting |
Notes
- Rate Limit: This endpoint has a limit of 60 requests per minute per Space. See Rate Limiting for details, the same bucket as Update Contact.
- No request body: the contact id in the path is the whole request.
- Rows are re-stamped, not just the pivot: the contact’s conversions, touchpoints, and visit metadata are updated to a
nullcompany_idin the same transaction, so company-level reports and the data warehouse Companies dataset reflect the detach right away. - No-op on an already-detached contact: calling this on a contact with no company still returns
200withcompany_id: null— it is not an error. - Merged profiles: If you pass an ID that was merged into another profile, the detach is applied to the canonical (current) profile, and the response’s
idis that canonical id. - Behavior after a manual detach depends on company identity mode: in the default Auto mode, the tracker assigns a company to any contact that currently has none, so the contact’s next event carrying a business-email domain undoes the detach. In External ID mode, the next event carrying a
company_external_idre-points the contact the same way.