curl --request POST \
--url https://app.thinnest.ai/api/v1/events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "+91 98765 43210",
"event": "order.delivered",
"name": "Priya Nair",
"data": {
"order": "10432",
"courier": "Delhivery"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '+91 98765 43210',
event: 'order.delivered',
name: 'Priya Nair',
data: {order: '10432', courier: 'Delhivery'}
})
};
fetch('https://app.thinnest.ai/api/v1/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.thinnest.ai/api/v1/events"
payload = {
"to": "+91 98765 43210",
"event": "order.delivered",
"name": "Priya Nair",
"data": {
"order": "10432",
"courier": "Delhivery"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"event": "order.delivered",
"contact": "cust_4e7b1c9d-2a6f-4385-b0d2-9f6a3e8c1b74",
"started": 1,
"stopped": 1,
"tagged": 0,
"matched": true
}{
"error": "\"items\" must be text, a number or true/false — not an object or a list."
}{
"error": "Send a valid API key as `Authorization: Bearer <key>`."
}{
"error": "This API key is read-only: it can read everything but change nothing."
}{
"error": "Over 240 requests a minute. Slow down and retry."
}{
"error": "Could not record that event."
}Report Event
Tells us something happened to a customer. Every sequence or tag rule subscribed to that event name runs: sequences that stop on it end first, then tags are added or removed, then sequences that start on it enrol the contact (unless they opted out, and only into an active sequence). The contact is created if the number is new. Nothing subscribed is still a 200, with matched: false — you can send events before anyone has set up what they do. Only send events for people who agreed to hear from you: an event that starts a sequence is taken as their opt-in. Needs a full key.
curl --request POST \
--url https://app.thinnest.ai/api/v1/events \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"to": "+91 98765 43210",
"event": "order.delivered",
"name": "Priya Nair",
"data": {
"order": "10432",
"courier": "Delhivery"
}
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
to: '+91 98765 43210',
event: 'order.delivered',
name: 'Priya Nair',
data: {order: '10432', courier: 'Delhivery'}
})
};
fetch('https://app.thinnest.ai/api/v1/events', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.thinnest.ai/api/v1/events"
payload = {
"to": "+91 98765 43210",
"event": "order.delivered",
"name": "Priya Nair",
"data": {
"order": "10432",
"courier": "Delhivery"
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"ok": true,
"event": "order.delivered",
"contact": "cust_4e7b1c9d-2a6f-4385-b0d2-9f6a3e8c1b74",
"started": 1,
"stopped": 1,
"tagged": 0,
"matched": true
}{
"error": "\"items\" must be text, a number or true/false — not an object or a list."
}{
"error": "Send a valid API key as `Authorization: Bearer <key>`."
}{
"error": "This API key is read-only: it can read everything but change nothing."
}{
"error": "Over 240 requests a minute. Slow down and retry."
}{
"error": "Could not record that event."
}Authorizations
Your API key (ta_live_…) from Settings → API keys, sent as Authorization: Bearer <key>. Keep it on a server: it can message every customer you have. A key is full, build or read-only; a request its level does not allow is refused with 403.
Headers
Developers only: the customer workspace this request acts in — its org_… id from POST /customers. Leave it out to act in your own workspace.
"org_3fKq9TzQ1mN8vB2xR7cLpA"
Body
The customer's number, with or without the +; spaces are fine. Matched to a contact by its digits; a new number creates a contact.
"+91 98765 43210"
What happened, as a name. Normalised and echoed back — lower case, anything but letters, digits, ., - and _ becomes a dot, 60 characters at most — so "Order Delivered" is stored as order.delivered. Subscribe to the name that comes back.
"order.delivered"
Values to carry into the sequences this starts, for their templates to use — an order number, a courier. At most 20; each name 1–60 characters (a longer one is refused); values are text, numbers or true/false, stored as text and cut at 300 characters. An object or list as a value is refused.
Show child attributes
Show child attributes
{ "order": "10432", "courier": "Delhivery" }
The customer's name, if you have it. Used for a contact this call creates, or one with no name yet. Cut at 120 characters.
120"Priya Nair"
Response
Recorded, and what it did.
The event was recorded.
The normalised name. Set your subscriptions up against this, not what you sent.
The contact the event was recorded against (cust_…), the id Get Contact takes.
Sequences this event enrolled the contact into.
Sequences it took them out of.
Tags added to or removed from the contact.
Whether anything was subscribed and acted.
Only when nothing acted: says nothing is subscribed to this event yet.