Create Event
curl --request POST \
--url https://app.cometly.com/public-api/v1/events/track \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"event_name": "<string>",
"email": "<string>",
"comet_token": "<string>",
"fingerprint": "<string>",
"ip": "<string>",
"tracking_id": "<string>",
"company_external_id": "<string>",
"company_name": "<string>",
"full_name": "<string>",
"first_name": "<string>",
"last_name": "<string>",
"phone": "<string>",
"user_agent": "<string>",
"event_time": "<string>",
"url": "<string>",
"amount": 123,
"order_id": "<string>",
"order_name": "<string>",
"checkout_token": "<string>",
"is_upsell": true,
"upsell_common_id": "<string>",
"profile_field_1 ... profile_field_30": "<string>",
"idempotency_key": "<string>",
"do_not_capi": true
}
'import requests
url = "https://app.cometly.com/public-api/v1/events/track"
payload = {
"event_name": "<string>",
"email": "<string>",
"comet_token": "<string>",
"fingerprint": "<string>",
"ip": "<string>",
"tracking_id": "<string>",
"company_external_id": "<string>",
"company_name": "<string>",
"full_name": "<string>",
"first_name": "<string>",
"last_name": "<string>",
"phone": "<string>",
"user_agent": "<string>",
"event_time": "<string>",
"url": "<string>",
"amount": 123,
"order_id": "<string>",
"order_name": "<string>",
"checkout_token": "<string>",
"is_upsell": True,
"upsell_common_id": "<string>",
"profile_field_1 ... profile_field_30": "<string>",
"idempotency_key": "<string>",
"do_not_capi": True
}
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({
event_name: '<string>',
email: '<string>',
comet_token: '<string>',
fingerprint: '<string>',
ip: '<string>',
tracking_id: '<string>',
company_external_id: '<string>',
company_name: '<string>',
full_name: '<string>',
first_name: '<string>',
last_name: '<string>',
phone: '<string>',
user_agent: '<string>',
event_time: '<string>',
url: '<string>',
amount: 123,
order_id: '<string>',
order_name: '<string>',
checkout_token: '<string>',
is_upsell: true,
upsell_common_id: '<string>',
'profile_field_1 ... profile_field_30': '<string>',
idempotency_key: '<string>',
do_not_capi: true
})
};
fetch('https://app.cometly.com/public-api/v1/events/track', 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/events/track",
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([
'event_name' => '<string>',
'email' => '<string>',
'comet_token' => '<string>',
'fingerprint' => '<string>',
'ip' => '<string>',
'tracking_id' => '<string>',
'company_external_id' => '<string>',
'company_name' => '<string>',
'full_name' => '<string>',
'first_name' => '<string>',
'last_name' => '<string>',
'phone' => '<string>',
'user_agent' => '<string>',
'event_time' => '<string>',
'url' => '<string>',
'amount' => 123,
'order_id' => '<string>',
'order_name' => '<string>',
'checkout_token' => '<string>',
'is_upsell' => true,
'upsell_common_id' => '<string>',
'profile_field_1 ... profile_field_30' => '<string>',
'idempotency_key' => '<string>',
'do_not_capi' => true
]),
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/events/track"
payload := strings.NewReader("{\n \"event_name\": \"<string>\",\n \"email\": \"<string>\",\n \"comet_token\": \"<string>\",\n \"fingerprint\": \"<string>\",\n \"ip\": \"<string>\",\n \"tracking_id\": \"<string>\",\n \"company_external_id\": \"<string>\",\n \"company_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"phone\": \"<string>\",\n \"user_agent\": \"<string>\",\n \"event_time\": \"<string>\",\n \"url\": \"<string>\",\n \"amount\": 123,\n \"order_id\": \"<string>\",\n \"order_name\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"is_upsell\": true,\n \"upsell_common_id\": \"<string>\",\n \"profile_field_1 ... profile_field_30\": \"<string>\",\n \"idempotency_key\": \"<string>\",\n \"do_not_capi\": true\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://app.cometly.com/public-api/v1/events/track")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"event_name\": \"<string>\",\n \"email\": \"<string>\",\n \"comet_token\": \"<string>\",\n \"fingerprint\": \"<string>\",\n \"ip\": \"<string>\",\n \"tracking_id\": \"<string>\",\n \"company_external_id\": \"<string>\",\n \"company_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"phone\": \"<string>\",\n \"user_agent\": \"<string>\",\n \"event_time\": \"<string>\",\n \"url\": \"<string>\",\n \"amount\": 123,\n \"order_id\": \"<string>\",\n \"order_name\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"is_upsell\": true,\n \"upsell_common_id\": \"<string>\",\n \"profile_field_1 ... profile_field_30\": \"<string>\",\n \"idempotency_key\": \"<string>\",\n \"do_not_capi\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.cometly.com/public-api/v1/events/track")
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 \"event_name\": \"<string>\",\n \"email\": \"<string>\",\n \"comet_token\": \"<string>\",\n \"fingerprint\": \"<string>\",\n \"ip\": \"<string>\",\n \"tracking_id\": \"<string>\",\n \"company_external_id\": \"<string>\",\n \"company_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"phone\": \"<string>\",\n \"user_agent\": \"<string>\",\n \"event_time\": \"<string>\",\n \"url\": \"<string>\",\n \"amount\": 123,\n \"order_id\": \"<string>\",\n \"order_name\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"is_upsell\": true,\n \"upsell_common_id\": \"<string>\",\n \"profile_field_1 ... profile_field_30\": \"<string>\",\n \"idempotency_key\": \"<string>\",\n \"do_not_capi\": true\n}"
response = http.request(request)
puts response.read_body{
"status": 123,
"message": "<string>"
}Events
Create Event
Create a new event to track conversions and user interactions
POST
/
public-api
/
v1
/
events
/
track
Create Event
curl --request POST \
--url https://app.cometly.com/public-api/v1/events/track \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"event_name": "<string>",
"email": "<string>",
"comet_token": "<string>",
"fingerprint": "<string>",
"ip": "<string>",
"tracking_id": "<string>",
"company_external_id": "<string>",
"company_name": "<string>",
"full_name": "<string>",
"first_name": "<string>",
"last_name": "<string>",
"phone": "<string>",
"user_agent": "<string>",
"event_time": "<string>",
"url": "<string>",
"amount": 123,
"order_id": "<string>",
"order_name": "<string>",
"checkout_token": "<string>",
"is_upsell": true,
"upsell_common_id": "<string>",
"profile_field_1 ... profile_field_30": "<string>",
"idempotency_key": "<string>",
"do_not_capi": true
}
'import requests
url = "https://app.cometly.com/public-api/v1/events/track"
payload = {
"event_name": "<string>",
"email": "<string>",
"comet_token": "<string>",
"fingerprint": "<string>",
"ip": "<string>",
"tracking_id": "<string>",
"company_external_id": "<string>",
"company_name": "<string>",
"full_name": "<string>",
"first_name": "<string>",
"last_name": "<string>",
"phone": "<string>",
"user_agent": "<string>",
"event_time": "<string>",
"url": "<string>",
"amount": 123,
"order_id": "<string>",
"order_name": "<string>",
"checkout_token": "<string>",
"is_upsell": True,
"upsell_common_id": "<string>",
"profile_field_1 ... profile_field_30": "<string>",
"idempotency_key": "<string>",
"do_not_capi": True
}
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({
event_name: '<string>',
email: '<string>',
comet_token: '<string>',
fingerprint: '<string>',
ip: '<string>',
tracking_id: '<string>',
company_external_id: '<string>',
company_name: '<string>',
full_name: '<string>',
first_name: '<string>',
last_name: '<string>',
phone: '<string>',
user_agent: '<string>',
event_time: '<string>',
url: '<string>',
amount: 123,
order_id: '<string>',
order_name: '<string>',
checkout_token: '<string>',
is_upsell: true,
upsell_common_id: '<string>',
'profile_field_1 ... profile_field_30': '<string>',
idempotency_key: '<string>',
do_not_capi: true
})
};
fetch('https://app.cometly.com/public-api/v1/events/track', 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/events/track",
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([
'event_name' => '<string>',
'email' => '<string>',
'comet_token' => '<string>',
'fingerprint' => '<string>',
'ip' => '<string>',
'tracking_id' => '<string>',
'company_external_id' => '<string>',
'company_name' => '<string>',
'full_name' => '<string>',
'first_name' => '<string>',
'last_name' => '<string>',
'phone' => '<string>',
'user_agent' => '<string>',
'event_time' => '<string>',
'url' => '<string>',
'amount' => 123,
'order_id' => '<string>',
'order_name' => '<string>',
'checkout_token' => '<string>',
'is_upsell' => true,
'upsell_common_id' => '<string>',
'profile_field_1 ... profile_field_30' => '<string>',
'idempotency_key' => '<string>',
'do_not_capi' => true
]),
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/events/track"
payload := strings.NewReader("{\n \"event_name\": \"<string>\",\n \"email\": \"<string>\",\n \"comet_token\": \"<string>\",\n \"fingerprint\": \"<string>\",\n \"ip\": \"<string>\",\n \"tracking_id\": \"<string>\",\n \"company_external_id\": \"<string>\",\n \"company_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"phone\": \"<string>\",\n \"user_agent\": \"<string>\",\n \"event_time\": \"<string>\",\n \"url\": \"<string>\",\n \"amount\": 123,\n \"order_id\": \"<string>\",\n \"order_name\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"is_upsell\": true,\n \"upsell_common_id\": \"<string>\",\n \"profile_field_1 ... profile_field_30\": \"<string>\",\n \"idempotency_key\": \"<string>\",\n \"do_not_capi\": true\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://app.cometly.com/public-api/v1/events/track")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"event_name\": \"<string>\",\n \"email\": \"<string>\",\n \"comet_token\": \"<string>\",\n \"fingerprint\": \"<string>\",\n \"ip\": \"<string>\",\n \"tracking_id\": \"<string>\",\n \"company_external_id\": \"<string>\",\n \"company_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"phone\": \"<string>\",\n \"user_agent\": \"<string>\",\n \"event_time\": \"<string>\",\n \"url\": \"<string>\",\n \"amount\": 123,\n \"order_id\": \"<string>\",\n \"order_name\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"is_upsell\": true,\n \"upsell_common_id\": \"<string>\",\n \"profile_field_1 ... profile_field_30\": \"<string>\",\n \"idempotency_key\": \"<string>\",\n \"do_not_capi\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.cometly.com/public-api/v1/events/track")
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 \"event_name\": \"<string>\",\n \"email\": \"<string>\",\n \"comet_token\": \"<string>\",\n \"fingerprint\": \"<string>\",\n \"ip\": \"<string>\",\n \"tracking_id\": \"<string>\",\n \"company_external_id\": \"<string>\",\n \"company_name\": \"<string>\",\n \"full_name\": \"<string>\",\n \"first_name\": \"<string>\",\n \"last_name\": \"<string>\",\n \"phone\": \"<string>\",\n \"user_agent\": \"<string>\",\n \"event_time\": \"<string>\",\n \"url\": \"<string>\",\n \"amount\": 123,\n \"order_id\": \"<string>\",\n \"order_name\": \"<string>\",\n \"checkout_token\": \"<string>\",\n \"is_upsell\": true,\n \"upsell_common_id\": \"<string>\",\n \"profile_field_1 ... profile_field_30\": \"<string>\",\n \"idempotency_key\": \"<string>\",\n \"do_not_capi\": true\n}"
response = http.request(request)
puts response.read_body{
"status": 123,
"message": "<string>"
}Overview
This endpoint allows you to send event data to Cometly for tracking conversions, page views, and other user interactions. Events are processed asynchronously and will be queued for processing.Request Body
Identification Requirements
At least one of the following identification methods is required:- Email: User’s email address
- Comet Token: Cometly tracking token
- Fingerprint + IP: Both fingerprint and IP address must be provided together
The name of the event being tracked. Use one of the standard events or a configured custom event.Standard Events:
lead_generatedview_contentschedulepurchasesubscribeadd_to_cartcontactinitiate_checkoutadd_payment_infocomplete_registrationstart_trialsign_upsubmit_applicationwebinar_registration
custom_event_1 through custom_event_50. View our help article to learn how to configure custom events prior to sending to Cometly.Tracking Parameters
Custom tracking identifier. Events with the same tracking_id will be attributed to the same contact.
Groups this contact into a company using your own account or company identifier. Nullable; accepts a string or integer, trimmed, 1–190 characters after trimming. The value is case-preserved and stored byte-exact — it is never lowercased. A blank string is treated as absent (
null). Sending a float, array, or boolean returns a 422.This is unrelated to tracking_id: tracking_id merges events into a single contact and never groups companies, while company_external_id groups contacts into a company and never merges contacts or takes part in contact matching. Never send a shared account ID as tracking_id.Only honored when the Space’s company identity mode is set to External ID in Space Settings. In the default Auto mode (companies grouped by business-email domain), the value is still accepted and stored, but ignored for grouping.Display name for the company identified by
company_external_id. Nullable; accepts a string or integer, trimmed, 1–255 characters after trimming. A blank string is treated as absent (null). Sending a float, array, or boolean returns a 422.Last write wins, and the value is never used for matching — two companies with the same name stay separate. Ignored when company_external_id is not also provided, since company_name alone doesn’t identify a company to name.User Information
Session Information
Ecommerce Data
Unique order identifier. This field is used in our deduplication logic — if multiple events are sent with the same
order_id, they may be treated as duplicates. Ensure each distinct order uses a unique value.Custom Fields
Custom profile field values passed as root-level properties. Fields 1-15 accept text, 16-25 accept numbers, 26-30 accept dates.Example:
"profile_field_1": "Enterprise", "profile_field_16": "500"Advanced Options
Response
Success Response
Error Response
Example Requests
curl -X POST https://app.cometly.com/public-api/v1/events/track \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"event_name": "purchase",
"email": "customer@example.com",
"amount": 99.99,
"order_id": "ORD-12345",
"url": "https://example.com/checkout/success",
"event_time": "2024-01-15T10:30:00Z",
"company_external_id": "acct_8f3k2",
"company_name": "Acme Inc"
}'
const response = await fetch('https://app.cometly.com/public-api/v1/events/track', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
event_name: 'purchase',
email: 'customer@example.com',
amount: 99.99,
order_id: 'ORD-12345',
url: 'https://example.com/checkout/success',
event_time: '2024-01-15T10:30:00Z',
company_external_id: 'acct_8f3k2',
company_name: 'Acme Inc'
})
});
const data = await response.json();
<?php
$url = 'https://app.cometly.com/public-api/v1/events/track';
$headers = [
'Authorization: Bearer YOUR_API_KEY',
'Accept: application/json',
'Content-Type: application/json'
];
$data = [
'event_name' => 'purchase',
'email' => 'customer@example.com',
'amount' => 99.99,
'order_id' => 'ORD-12345',
'url' => 'https://example.com/checkout/success',
'event_time' => '2024-01-15T10:30:00Z',
'company_external_id' => 'acct_8f3k2',
'company_name' => 'Acme Inc'
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
?>
import requests
from datetime import datetime
url = 'https://app.cometly.com/public-api/v1/events/track'
headers = {
'Authorization': 'Bearer YOUR_API_KEY',
'Accept': 'application/json',
'Content-Type': 'application/json'
}
data = {
'event_name': 'purchase',
'email': 'customer@example.com',
'amount': 99.99,
'order_id': 'ORD-12345',
'url': 'https://example.com/checkout/success',
'event_time': '2024-01-15T10:30:00Z',
'company_external_id': 'acct_8f3k2',
'company_name': 'Acme Inc'
}
response = requests.post(url, headers=headers, json=data)
Status Codes
| Status Code | Description |
|---|---|
| 202 | Event accepted and queued for processing |
| 401 | Missing or invalid API key |
| 403 | API key doesn’t have permission or subscription is inactive |
| 422 | Validation failed or missing required parameters |
| 429 | Too many requests - rate limit exceeded. See Rate Limiting |
Notes
- Rate Limit: This endpoint has a limit of 1000 requests per minute per Space. See Rate Limiting for details.
Validation Rules
- At least one identification method must be provided:
email, ORcomet_token, OR- Both
fingerprintANDiptogether
event_nameis required- If
fingerprintis provided,ipmust also be provided (and vice versa) event_timeaccepts ISO 8601 format or Unix timestamp in secondsamountmust be a number if providedcompany_external_id, if provided, must be a string or integer, 1–190 characters after trimming; floats, arrays, and booleans return422company_name, if provided, must be a string or integer, 1–255 characters after trimming; floats, arrays, and booleans return422- Blank strings for
company_external_idorcompany_nameare treated as absent (null);company_nameis ignored whencompany_external_idisn’t also provided
Meta Deduplication
Theidempotency_key in our API is a unique identifier that ensures data consistency and prevents duplication of events. You can extract the event_id from the Meta browser pixel and use it as the idempotency_key when interacting with our API. Upon an attributed Meta ad conversion event, we will send this value as event_id to prevent duplication, enabling Meta to recognize the event_id and deduplicate browser events.
Use the
idempotency_key parameter to safely retry requests without creating duplicate events. The same idempotency key will prevent the event from being processed multiple times.