View Markdown

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:

  1. take a checkpoint first, GET /v2/events/checkpoint, with the filters you will use;
  2. list the current state, such as GET /v2/messages;
  3. page or stream from that checkpoint, applying only newer versions.

Nothing is missed and nothing is applied twice.