curl --request POST \
--url https://api.chatsailer.com/v1/success-events/{event_id}/reversal \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dedupe_key": "refund-1001",
"occurred_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
'import requests
url = "https://api.chatsailer.com/v1/success-events/{event_id}/reversal"
payload = {
"dedupe_key": "refund-1001",
"occurred_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
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: 'refund-1001',
occurred_at: '2023-11-07T05:31:56Z',
reason: '<string>'
})
};
fetch('https://api.chatsailer.com/v1/success-events/{event_id}/reversal', 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/{event_id}/reversal",
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' => 'refund-1001',
'occurred_at' => '2023-11-07T05:31:56Z',
'reason' => '<string>'
]),
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/{event_id}/reversal"
payload := strings.NewReader("{\n \"dedupe_key\": \"refund-1001\",\n \"occurred_at\": \"2023-11-07T05:31:56Z\",\n \"reason\": \"<string>\"\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/{event_id}/reversal")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"dedupe_key\": \"refund-1001\",\n \"occurred_at\": \"2023-11-07T05:31:56Z\",\n \"reason\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chatsailer.com/v1/success-events/{event_id}/reversal")
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\": \"refund-1001\",\n \"occurred_at\": \"2023-11-07T05:31:56Z\",\n \"reason\": \"<string>\"\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>"
}
]
}Reverse a success event
Undoes a recorded event — a refund, a cancelled sale. The original is never edited: this records a new reversal entry with the same event_code and value_cents, credited against the same agreement.
An event can be reversed once. Retrying with the same dedupe_key answers 200 with the reversal already on file; a different key answers 409 already_reversed. Reversing a reversal answers 409 not_a_record.
curl --request POST \
--url https://api.chatsailer.com/v1/success-events/{event_id}/reversal \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"dedupe_key": "refund-1001",
"occurred_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
'import requests
url = "https://api.chatsailer.com/v1/success-events/{event_id}/reversal"
payload = {
"dedupe_key": "refund-1001",
"occurred_at": "2023-11-07T05:31:56Z",
"reason": "<string>"
}
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: 'refund-1001',
occurred_at: '2023-11-07T05:31:56Z',
reason: '<string>'
})
};
fetch('https://api.chatsailer.com/v1/success-events/{event_id}/reversal', 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/{event_id}/reversal",
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' => 'refund-1001',
'occurred_at' => '2023-11-07T05:31:56Z',
'reason' => '<string>'
]),
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/{event_id}/reversal"
payload := strings.NewReader("{\n \"dedupe_key\": \"refund-1001\",\n \"occurred_at\": \"2023-11-07T05:31:56Z\",\n \"reason\": \"<string>\"\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/{event_id}/reversal")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"dedupe_key\": \"refund-1001\",\n \"occurred_at\": \"2023-11-07T05:31:56Z\",\n \"reason\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.chatsailer.com/v1/success-events/{event_id}/reversal")
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\": \"refund-1001\",\n \"occurred_at\": \"2023-11-07T05:31:56Z\",\n \"reason\": \"<string>\"\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_....
Path Parameters
Unique identifier for a success event.
^sev_[0-9a-f]{32}$"sev_9f2ac41d8b7e4a51b0d3e6f7a1c2d3e4"
Body
Body for POST /v1/success-events/{event_id}/reversal.
Your idempotency key for the reversal, e.g. your refund id. Retrying with the same key returns the reversal already on file (200).
1 - 255"refund-1001"
When the refund or cancellation happened. Defaults to now.
Free text kept for audit, e.g. why a sale was refunded.
2000Response
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"