Send events
Events are signals from your system. The billable condition is evaluated after each one.
Events apply to an outcome you already opened. Each event names the outcome by outcome_key. Create the outcome first; events for an outcome that does not exist are discarded.
What is an event?
An event is a signal from your system that something happened. You send events as things occur: a ticket is resolved, a document is signed, a score is submitted, a file is uploaded.
After each event, witn evaluates the outcome's billable condition and resets the settlement timer. If the condition is satisfied, the outcome moves toward confirmation when the timer expires.
Event structure
{
"outcome_key": "support:ticket:1001",
"action": "agent_replied"
}{
"outcome_key": "support:ticket:1001",
"action": "csat",
"properties": {
"value": 4.8,
"settles_at": "2024-01-18T10:00:00Z"
}
}| Field | Required | Description |
|---|---|---|
outcome_key | Yes | The key of the outcome this event applies to. |
action | Yes | What happened. Matched against the billable condition. |
properties.value | No | A string, number, or boolean used for match and numeric comparisons. |
properties.settles_at | No | ISO datetime that pins when this outcome resolves. Overrides the settlement timer for this event. |
properties.value and properties.settles_at are reserved by witn
Sending an event
curl -X POST https://api.thewitn.com/v1/events \
-H "Authorization: Bearer $WITN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "outcome_key": "support:ticket:1001", "action": "agent_replied" }'curl -X POST https://api.thewitn.com/v1/events \
-H "Authorization: Bearer $WITN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "outcome_key": "support:ticket:1001", "action": "csat", "properties": { "value": 4.8 } }'Both return 202 Accepted. The request is validated immediately. Condition evaluation and settlement happen asynchronously.
In TypeScript:
await fetch('https://api.thewitn.com/v1/events', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.WITN_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
outcome_key: 'support:ticket:1001',
action: 'csat',
properties: { value: 4.8 },
}),
})Multiple events with the same action
When you submit more than one event with the same action, the latest properties.value for that action is used for condition evaluation. This lets you send corrections: if you submitted a CSAT score of 2 and the customer later updates it to 5, send the new event. witn uses 5 and re-evaluates the condition.
# First submission: score of 2 (condition not met if gte 4)
curl -X POST https://api.thewitn.com/v1/events \
-H "Authorization: Bearer $WITN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "outcome_key": "support:ticket:1001", "action": "csat", "properties": { "value": 2 } }'
# Correction: score of 5 (condition now met)
curl -X POST https://api.thewitn.com/v1/events \
-H "Authorization: Bearer $WITN_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "outcome_key": "support:ticket:1001", "action": "csat", "properties": { "value": 5 } }'Value and billing
Numeric comparators (gt, gte, lt, lte, eq) compare against properties.value. When the outcome confirms, the billed amount is the rate card entry's price_per_unit.
Pinning the settlement time
By default, every event resets the settlement timer to the event timestamp plus the task's settlement period.
If an event knows the next business deadline, set properties.settles_at:
{
"outcome_key": "appointment:123",
"action": "appointment_booked",
"properties": {
"settles_at": "2024-02-01T17:00:00Z"
}
}The outcome resolves at that time instead of the default settlement window.
Errors
| Code | Status | When |
|---|---|---|
VALIDATION_ERROR | 400 | outcome_key or action is missing or invalid. |
TOKEN_INVALID | 401 | Token missing or not recognised. |