Events
Every change in Kabu is an event: a message sent, delivered, answered or expired, a session started or ended. A service that needs to react, such as a dashboard, an audit log or a bot in your chat, reads them in one of three ways, and all three carry the same objects:
| Way | Call | Good for |
|---|---|---|
| Page | GET /v2/events?after=<checkpoint>&wait=25 |
Batch jobs, catching up |
| Stream | GET /v2/events/stream (server-sent events, or NDJSON with Accept: application/x-ndjson) |
A process that stays connected |
| Webhook | Kabu calls your endpoint | Servers that should not hold a connection: see Webhooks |
An event
{
"object": "event",
"id": "evt_01J9Z…",
"type": "message.resolved",
"project": "payments-api",
"resource": "msg_01J9Y…",
"resource_version": 3,
"session": "ses_01J9X…",
"created_at": "2026-10-30T09:41:00Z",
"data": { "object": { "object": "message", "id": "msg_01J9Y…", "status": "answered" }, "previous": { "status": "pending" } }
}data.object is the resource as it is when the event reaches you, and data.previous the fields that changed. Types:
message.created, message.delivered, message.resolved, message.expired, message.cancelled, session.created,
session.updated, session.ended, agent.paused and ping. New types appear over time: ignore the ones you do not
know.
Order and duplicates
Events are delivered at least once and in order for each resource, not across all of them. Each carries the
resource_version it describes: keep the highest version you have applied for each resource, and skip an event whose
version is not newer. That makes repeats and replays harmless.
Checkpoints
Every page of events returns a checkpoint, even an empty one, and every streamed event carries its own (the
server-sent event’s id). Pass it as after to continue exactly where you stopped; a stream that reconnects resumes
from Last-Event-ID. A checkpoint works only with the filters it was issued with.
Events are kept for 30 days. An older checkpoint is 410
checkpoint_expired. To start again, or to start at all:
- take a checkpoint first,
GET /v2/events/checkpoint, with the filters you will use; - list the current state, such as
GET /v2/messages; - page or stream from that checkpoint, applying only newer versions.
Nothing is missed and nothing is applied twice.