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"
  }
}
FieldRequiredDescription
outcome_keyYesThe key of the outcome this event applies to.
actionYesWhat happened. Matched against the billable condition.
properties.valueNoA string, number, or boolean used for match and numeric comparisons.
properties.settles_atNoISO 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

CodeStatusWhen
VALIDATION_ERROR400outcome_key or action is missing or invalid.
TOKEN_INVALID401Token missing or not recognised.

On this page