curl --request POST \
--url https://api.chatsailer.com/v1/success-events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dedupe_key": "order-1001",
"event_code": "sale_closed",
"occurred_at": "2026-09-01T12:00:00-03:00",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"reason": "<string>",
"value_cents": 150000
}
'import requests
url = "https://api.chatsailer.com/v1/success-events"
payload = {
"dedupe_key": "order-1001",
"event_code": "sale_closed",
"occurred_at": "2026-09-01T12:00:00-03:00",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"reason": "<string>",
"value_cents": 150000
}
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({
dedupe_key: 'order-1001',
event_code: 'sale_closed',
occurred_at: '2026-09-01T12:00:00-03:00',
contact_id: 'con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
conversation_id: 'conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
deal_id: 'deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
reason: '<string>',
value_cents: 150000
})
};
fetch('https://api.chatsailer.com/v1/success-events', 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.chatsailer.com/v1/success-events",
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([
'dedupe_key' => 'order-1001',
'event_code' => 'sale_closed',
'occurred_at' => '2026-09-01T12:00:00-03:00',
'contact_id' => 'con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
'conversation_id' => 'conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
'deal_id' => 'deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
'reason' => '<string>',
'value_cents' => 150000
]),
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://api.chatsailer.com/v1/success-events"
payload := strings.NewReader("{\n \"dedupe_key\": \"order-1001\",\n \"event_code\": \"sale_closed\",\n \"occurred_at\": \"2026-09-01T12:00:00-03:00\",\n \"contact_id\": \"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"conversation_id\": \"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"deal_id\": \"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"reason\": \"<string>\",\n \"value_cents\": 150000\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://api.chatsailer.com/v1/success-events")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"dedupe_key\": \"order-1001\",\n \"event_code\": \"sale_closed\",\n \"occurred_at\": \"2026-09-01T12:00:00-03:00\",\n \"contact_id\": \"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"conversation_id\": \"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"deal_id\": \"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"reason\": \"<string>\",\n \"value_cents\": 150000\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chatsailer.com/v1/success-events")
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 \"dedupe_key\": \"order-1001\",\n \"event_code\": \"sale_closed\",\n \"occurred_at\": \"2026-09-01T12:00:00-03:00\",\n \"contact_id\": \"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"conversation_id\": \"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"deal_id\": \"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"reason\": \"<string>\",\n \"value_cents\": 150000\n}"
response = http.request(request)
puts response.read_body{
"billable": true,
"created_at": "2023-11-07T05:31:56Z",
"currency": "BRL",
"dedupe_key": "<string>",
"entry_kind": "record",
"event_code": "<string>",
"id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"occurred_at": "2023-11-07T05:31:56Z",
"agreement_id": "agr_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"object": "success_event",
"reason": "<string>",
"reverses_event_id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"value_cents": 123
}{
"billable": true,
"created_at": "2023-11-07T05:31:56Z",
"currency": "BRL",
"dedupe_key": "<string>",
"entry_kind": "record",
"event_code": "<string>",
"id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"occurred_at": "2023-11-07T05:31:56Z",
"agreement_id": "agr_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"object": "success_event",
"reason": "<string>",
"reverses_event_id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"value_cents": 123
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"ctx": {},
"input": "<unknown>"
}
]
}Record a success event
Reports a business outcome — a sale closed, a meeting held — that this workspace’s agreement may charge a success fee on.
event_code must be one of this workspace’s event types (GET /v1/success-event-types). Send value_cents when the type’s value_basis is amount, and omit it when it is none.
Safe to retry. dedupe_key is your idempotency key, typically your own order id. Resending the same event_code + dedupe_key answers 200 with the event already on file instead of recording it twice.
billable in the response tells you whether a billing agreement was attached. An event recorded while none is in force is kept for reporting and is never invoiced.
curl --request POST \
--url https://api.chatsailer.com/v1/success-events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dedupe_key": "order-1001",
"event_code": "sale_closed",
"occurred_at": "2026-09-01T12:00:00-03:00",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"reason": "<string>",
"value_cents": 150000
}
'import requests
url = "https://api.chatsailer.com/v1/success-events"
payload = {
"dedupe_key": "order-1001",
"event_code": "sale_closed",
"occurred_at": "2026-09-01T12:00:00-03:00",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"reason": "<string>",
"value_cents": 150000
}
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({
dedupe_key: 'order-1001',
event_code: 'sale_closed',
occurred_at: '2026-09-01T12:00:00-03:00',
contact_id: 'con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
conversation_id: 'conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
deal_id: 'deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
reason: '<string>',
value_cents: 150000
})
};
fetch('https://api.chatsailer.com/v1/success-events', 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.chatsailer.com/v1/success-events",
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([
'dedupe_key' => 'order-1001',
'event_code' => 'sale_closed',
'occurred_at' => '2026-09-01T12:00:00-03:00',
'contact_id' => 'con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
'conversation_id' => 'conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
'deal_id' => 'deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4',
'reason' => '<string>',
'value_cents' => 150000
]),
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://api.chatsailer.com/v1/success-events"
payload := strings.NewReader("{\n \"dedupe_key\": \"order-1001\",\n \"event_code\": \"sale_closed\",\n \"occurred_at\": \"2026-09-01T12:00:00-03:00\",\n \"contact_id\": \"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"conversation_id\": \"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"deal_id\": \"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"reason\": \"<string>\",\n \"value_cents\": 150000\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://api.chatsailer.com/v1/success-events")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"dedupe_key\": \"order-1001\",\n \"event_code\": \"sale_closed\",\n \"occurred_at\": \"2026-09-01T12:00:00-03:00\",\n \"contact_id\": \"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"conversation_id\": \"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"deal_id\": \"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"reason\": \"<string>\",\n \"value_cents\": 150000\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chatsailer.com/v1/success-events")
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 \"dedupe_key\": \"order-1001\",\n \"event_code\": \"sale_closed\",\n \"occurred_at\": \"2026-09-01T12:00:00-03:00\",\n \"contact_id\": \"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"conversation_id\": \"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"deal_id\": \"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4\",\n \"reason\": \"<string>\",\n \"value_cents\": 150000\n}"
response = http.request(request)
puts response.read_body{
"billable": true,
"created_at": "2023-11-07T05:31:56Z",
"currency": "BRL",
"dedupe_key": "<string>",
"entry_kind": "record",
"event_code": "<string>",
"id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"occurred_at": "2023-11-07T05:31:56Z",
"agreement_id": "agr_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"object": "success_event",
"reason": "<string>",
"reverses_event_id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"value_cents": 123
}{
"billable": true,
"created_at": "2023-11-07T05:31:56Z",
"currency": "BRL",
"dedupe_key": "<string>",
"entry_kind": "record",
"event_code": "<string>",
"id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"occurred_at": "2023-11-07T05:31:56Z",
"agreement_id": "agr_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"contact_id": "con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"conversation_id": "conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"deal_id": "deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"object": "success_event",
"reason": "<string>",
"reverses_event_id": "sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4",
"value_cents": 123
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"ctx": {},
"input": "<unknown>"
}
]
}Authorizations
A workspace API token. Create one in Settings → API. Send it as Authorization: Bearer sk_live_....
Body
Body for POST /v1/success-events.
Your idempotency key for this fact, e.g. your order id. Unique per event_code within the workspace: sending the same key again returns the event already on file (200) instead of recording a second one — even if the rest of the body differs, so never reuse a key for a different fact.
1 - 255"order-1001"
Which kind of success this is — the code of one of this workspace's event types. List them with GET /v1/success-event-types.
1 - 100"sale_closed"
When the success actually happened, with a timezone offset. May be in the past: an event reported late is still dated when it happened.
"2026-09-01T12:00:00-03:00"
Unique identifier for a contact.
^con_[0-9a-f]{32}$"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Unique identifier for a conversation.
^conv_[0-9a-f]{32}$"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Unique identifier for a deal.
^deal_[0-9a-f]{32}$"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Free text kept for audit, e.g. why a sale was refunded.
2000The event's own value in cents (BRL), e.g. the sale amount. Required when the event type's value_basis is amount; must be omitted when it is none.
x >= 0150000
Response
Replayed: an event with this dedupe_key was already on file and is returned unchanged. Nothing new was recorded.
One entry in the success-event ledger.
Whether a billing agreement was attached when the event was recorded. false means the event is kept for reporting but will never be invoiced, even if an agreement starts later.
When Sailer recorded the event.
"BRL"
record for a success; reversal for the entry that undoes one. A reversal carries the same event_code and value_cents as the event it reverses.
record, reversal Unique identifier for a success event.
^sev_[0-9a-f]{32}$"sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Unique identifier for a billing agreement.
^agr_[0-9a-f]{32}$"agr_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Unique identifier for a contact.
^con_[0-9a-f]{32}$"con_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Unique identifier for a conversation.
^conv_[0-9a-f]{32}$"conv_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Unique identifier for a deal.
^deal_[0-9a-f]{32}$"deal_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
"success_event"Unique identifier for a success event.
^sev_[0-9a-f]{32}$"sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"