Send events

Events are signals from your system. The billable condition is evaluated after each one.

Outcomes are created by the first event for a new key. agent_key is optional: if you only run one agent, or your action maps to a single agent, leave it out. Once an outcome exists, later events for the same key route to it automatically.

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

{
  "key": "support:ticket:1001",
  "action": "agent_replied",
  "agent_key": "support",
  "customer_key": "acme"
}
{
  "key": "support:ticket:1001",
  "action": "csat",
  "agent_key": "support",
  "customer_key": "acme",
  "properties": {
    "value": 4.8,
    "attribution": 0.8,
    "settles_at": "2024-01-18T10:00:00Z"
  }
}
FieldRequiredDescription
keyYesThe outcome key.
actionYesWhat happened. Matched against the billable condition.
agent_keyNoThe agent key. Omit to let witn infer the agent; send it to be explicit.
customer_keyYesThe customer's key.
properties.valueNoA string, number, or boolean used for match and numeric comparisons.
properties.attributionNoA numeric value used for billing quantity.
properties.settles_atNoISO datetime that pins when this outcome resolves. Overrides the settlement timer for this event.

properties.value, properties.attribution, 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 '{ "key": "support:ticket:1001", "action": "agent_replied", "agent_key": "support", "customer_key": "acme" }'
curl -X POST https://api.thewitn.com/v1/events \
  -H "Authorization: Bearer $WITN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "key": "support:ticket:1001", "action": "csat", "agent_key": "support", "customer_key": "acme", "properties": { "value": 4.8, "attribution": 0.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({
    key: 'support:ticket:1001',
    action: 'csat',
    agent_key: 'support',
    customer_key: 'acme',
    properties: { value: 4.8, attribution: 0.8 },
  }),
})

Multiple events with the same action

When you submit more than one event with the same action, properties.value and properties.attribution are handled differently.

For condition evaluation, the latest properties.value for that action is used. 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 '{ "key": "support:ticket:1001", "action": "csat", "agent_key": "support", "customer_key": "acme", "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 '{ "key": "support:ticket:1001", "action": "csat", "agent_key": "support", "customer_key": "acme", "properties": { "value": 5 } }'

Earlier events are still stored. Their properties.attribution values can still affect billing depending on the agent's attribution_method.

Value, attribution, and billing

Event payloads separate condition evaluation from billing quantity:

  1. Condition evaluation. Numeric comparators (gt, gte, lt, lte, eq) compare against properties.value.
  2. Billing quantity. When the outcome confirms, the billed amount is price_per_unit × unit (using properties.attribution from submitted events).

The attribution_method on the agent controls which properties.attribution value is used when multiple events include billing quantities.

Pinning the settlement time

By default, every event resets the settlement timer to the event timestamp plus the agent's settlement period.

If an event knows the next business deadline, set properties.settles_at:

{
  "key": "appointment:123",
  "action": "appointment_booked",
  "agent_key": "phone-ai",
  "customer_key": "acme",
  "properties": {
    "settles_at": "2024-02-01T17:00:00Z"
  }
}

The outcome resolves at that time instead of the default settlement window.

Errors

CodeStatusWhen
VALIDATION_ERROR400key, action, or customer_key is missing or invalid, or agent_key is present but empty.
TOKEN_INVALID401Token missing or not recognised.

On this page