Event catalogue
Every change in a workspace is an event on the outbox. Webhooks, apps, bots, notifications and the realtime socket consume the same stream.
Last updated
Events are durable (published in the same transaction as the change) and retained 90 days by default. Delivery to consumers is at least once and not ordered: deduplicate on the event id and read the current state from the API when order matters. Names are object.verb. The payload carries the ids a consumer needs to decide whether to fetch more.
| Event | When | Payload highlights |
|---|---|---|
conversation.created | A conversation starts on any channel, by a customer, an agent, a bot or the API. | inbox_id, contact_id; web chats add visitor |
conversation.updated | Status, priority, assignee, team, tags, snooze or attributes change. | reason (e.g. resolved, snooze_ended), changed fields |
conversation.reopened | A resolved or closed conversation is open again (a customer reply, an agent, a rule or the API). Published next to conversation.updated; never for imports. | The same payload as conversation.updated |
conversation.handoff | A bot released the conversation to people. | inbox_id, bot_id, reason, kind (explicit, implicit, takeover), held_ms |
conversation.sla_breached | A conversation passed a target of its SLA policy while still waiting (no first response, or not resolved). Once per conversation and target. | kind (first_response, resolution), policy_id, policy_name, due_at |
message.created | Any message: inbound or outbound, reply, note or activity. | conversation_id, direction, kind, sender_type; web chats add visitor |
message.updated | A stored inbound message changed in place: the customer edited or deleted it on a channel that carries edits and deletions (Slack today). | conversation_id, inbox_id, direction, kind, change (edited, deleted) |
message.delivered, message.delivery_failed | The channel accepted or rejected an outbound reply. | conversation_id, provider_message_id, error |
csat.requested | A satisfaction survey was offered after a resolution (once per resolution, when an agent or bot replied). | conversation_id, survey_id, inbox_id, contact_id, assignee_id, team_id, channel, scale, expires_at, survey_url (a signed link, so an API inbox can show the survey itself) |
csat.submitted | The customer answered the survey, or changed their answer. | conversation_id, survey_id, response_id, rating (1 to 5), value, scale, comment, has_comment, low, updated, previous_rating, source |
contact.created, contact.updated, contact.merged, contact.erased, contact.identity_added, contact.identity_removed | Contact lifecycle. | contact_id, merged_into_id |
inbox.created, inbox.updated, inbox.deleted, inbox.members_changed | Channel connections and who works them. | |
team.created, team.updated, team.deleted, team.members_changed, tag.created, tag.updated, tag.deleted | Teams and tags. | |
member.updated, member.removed, invitation.created | Workspace members and invitations. | user_id |
role.created, role.updated, settings.changed, account.updated, account.closed | Access control, settings and the workspace itself. Publishing or restoring a branding version emits one settings.changed per changed key. | |
article.published, article.updated, article.unpublished, article.deleted | Help center articles. | article_id |
These are the types a webhook can subscribe to; GET /webhooks returns the current list as event_types. Other events on the stream, such as automation runs, notifications, an agent's availability changing and bot pauses, drive features inside Kommio and are not offered to webhooks. Bots receive their own bot events, and the send_webhook step of a rule or macro posts automation.send_webhook. Payloads carry ids, states and the names of changed fields, never custom attribute values; read those through the API with a key whose permissions allow it.
{
"id": 1204,
"event_id": 91822,
"type": "conversation.updated",
"account_id": 12,
"object_type": "conversation",
"object_id": 4821,
"occurred_at": "2026-09-22T09:12:00Z",
"data": { "reason": "resolved", "status_category": "resolved", "actor_kind": "user", "actor_id": 3 }
}id is the delivery (the same on a retry or a replay) and event_id the event; data is the event's payload.
Every claim on these pages is covered by a test in the repository, and the API reference is generated from the same contract every server serves at /api/openapi. Corrections to [email protected].