Skip to main content

Events API

A read-only feed of recent notable events in the platform — message sent, message delivered, agent run, flow step, contact updated, conversation created, webhook endpoint updated, etc. Two access patterns:
  • PolledGET /api/v1/events pages over a bounded recent-window replay buffer (see below).
  • LiveGET /api/v1/events/stream opens an SSE connection that delivers events in real time.
This is not durable history. The Events API is a bounded, in-memory replay buffer (a per-tenant Redis Stream), not a system of record. It retains only the most recent ~5000 events per tenant, and the buffer expires after ~15 minutes of tenant inactivity. Older events are evicted and are gone — they cannot be paged back to. GET /api/v1/events/{id} resolves only ids still inside the current window; an evicted id returns 404. If the real-time store is briefly unavailable the surface degrades open — the list returns an empty page and a single-event lookup returns 404 rather than erroring.For a durable, complete, retry-handled record of every event — anything you’d build a system of record, audit log, or reconciliation job off of — use Webhooks instead. Do not treat this endpoint as an event log.
Base path: /api/v1/events Authentication: API key (X-API-Key) or session JWT.

Live stream — SSE

Events arrive as data: lines (one JSON object per line). Reconnect on error with the Last-Event-ID header set so you don’t lose events. The ?token= query parameter is promoted to X-API-Key server-side so browsers (which can’t set arbitrary headers on EventSource) can authenticate. As with every Orbit endpoint, query strings are stripped from access logs platform-wide before they’re written, so the token value is never persisted to log storage.

Ingesting events — POST /api/v1/events/track

To record your own product events (rather than read the feed above), POST to the ingestion endpoint with an event name, an optional contact identifier (contact_email or contact_phone — omit both to store the event without linking it to a contact), and an optional properties object:
properties payload ceiling — 1 MiB. The serialized properties JSON for a single event must not exceed 1 MiB (1,048,576 bytes). An event over the ceiling is rejected with HTTP 413 and error.code = EVENT_PAYLOAD_TOO_LARGE — nothing is stored and the contact timeline is unchanged. Keep individual attributes small: store large blobs (raw documents, base64 media, full request dumps) in your own object storage and reference them from properties by URL or id rather than embedding them inline.

See also

  • Webhooks — for delivered, durable, retry-handled push of the same events