Attach Contact Company
curl --request PUT \
--url https://app.cometly.com/public-api/v1/contacts/{id}/company \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"company_id": 123
}
'import requests
url = "https://app.cometly.com/public-api/v1/contacts/{id}/company"
payload = { "company_id": 123 }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({company_id: 123})
};
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 => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'company_id' => 123
]),
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://app.cometly.com/public-api/v1/contacts/{id}/company"
payload := strings.NewReader("{\n \"company_id\": 123\n}")
req, _ := http.NewRequest("PUT", 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.put("https://app.cometly.com/public-api/v1/contacts/{id}/company")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"company_id\": 123\n}")
.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::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"company_id\": 123\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"company_id": 123,
"message": "<string>"
}Contacts
Attach Contact Company
Attach a contact to a company, moving it off any company it currently belongs to
PUT
/
public-api
/
v1
/
contacts
/
{id}
/
company
Attach Contact Company
curl --request PUT \
--url https://app.cometly.com/public-api/v1/contacts/{id}/company \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"company_id": 123
}
'import requests
url = "https://app.cometly.com/public-api/v1/contacts/{id}/company"
payload = { "company_id": 123 }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({company_id: 123})
};
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 => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'company_id' => 123
]),
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://app.cometly.com/public-api/v1/contacts/{id}/company"
payload := strings.NewReader("{\n \"company_id\": 123\n}")
req, _ := http.NewRequest("PUT", 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.put("https://app.cometly.com/public-api/v1/contacts/{id}/company")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"company_id\": 123\n}")
.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::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"company_id\": 123\n}"
response = http.request(request)
puts response.read_body{
"id": 123,
"company_id": 123,
"message": "<string>"
}Overview
This endpoint attaches a contact to a company. A contact belongs to at most one company per Space, so attaching it to a new company moves it off any company it currently belongs to. In the same transaction, the contact’s conversions, touchpoints, and visit metadata are re-stamped with the new company id, so company-level reports and the Companies datasetcompany_id columns in the data warehouse follow immediately — nothing is left pointing at the old company.
This call is idempotent: repeating it with the contact’s current company id re-stamps the same rows again, which is useful for repairing rows that drifted out of sync rather than a no-op.
Path Parameters
integer
required
The unique identifier of the contact to attach. Merged profile aliases are automatically resolved to the current canonical contact — the response’s
id is the surviving contact.Request Body
integer
required
The unique identifier of the company to attach the contact to. Must belong to a company in the same Space as the contact.
Response
Success Response
integer
The unique identifier of the contact (after resolving merged-profile aliases).
integer
The id of the company the contact is now attached to — echoes the
company_id sent in the request.Error Response
string
Error description explaining what went wrong.
Example Requests
curl -X PUT "https://app.cometly.com/public-api/v1/contacts/12345/company" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"company_id": 54321
}'
const contactId = 12345;
const response = await fetch(`https://app.cometly.com/public-api/v1/contacts/${contactId}/company`, {
method: 'PUT',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
company_id: 54321
})
});
const data = await response.json();
console.log('Attached 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',
'Content-Type: application/json'
];
$data = [
'company_id' => 54321,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
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',
'Content-Type': 'application/json'
}
data = {
'company_id': 54321,
}
response = requests.put(url, headers=headers, json=data)
result = response.json()
Status Codes
| Status Code | Description |
|---|---|
| 200 | Contact successfully attached to the company |
| 401 | Missing or invalid API key |
| 403 | API key doesn’t have permission or subscription is inactive |
| 404 | Contact not found, or company_id does not match a company in this Space |
| 422 | Invalid parameters provided (check error message for details) |
| 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.
- One company per contact: attaching a contact to a new company removes it from any company it previously belonged to — a contact is never attached to more than one company at a time.
- Rows are re-stamped, not just the pivot: the contact’s conversions, touchpoints, and visit metadata are updated to the new
company_idin the same transaction, so company-level reports and the data warehouse Companies dataset join correctly right away. - Idempotent repair: calling this again with the contact’s current company id is not a no-op — it re-stamps the contact’s rows, which repairs any that had drifted out of sync.
- Merged profiles: If you pass an ID that was merged into another profile, the attach is applied to the canonical (current) profile, and the response’s
idis that canonical id. company_idmust be in the same Space: attaching to a company from a different Space returns404.- Behavior after a manual attach depends on company identity mode: in the default Auto mode, the tracker only assigns a company to a contact that currently has none, so a manual attach sticks until the contact is manually detached — it is not undone by a later event. In External ID mode, the next event carrying a different
company_external_idre-points the contact again.