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:- Polled —
GET /api/v1/eventspages over a bounded recent-window replay buffer (see below). - Live —
GET /api/v1/events/streamopens an SSE connection that delivers events in real time.
/api/v1/events
Authentication: API key (X-API-Key) or session JWT.
Using the SDKs
ApiResponse envelope. See the SDK index at SDK quickstart.
GET /api/v1/events response
The list endpoint returns pages of recent events inside the standard paginated envelope. Each data[] entry is one event envelope: the canonical stream id (pass it back as cursor to page forward, or as Last-Event-ID on the SSE stream to resume), the event type, the publish time ts (epoch milliseconds), and the type-specific data object.
meta.pagination.cursor is the id of the last event on the page. When has_more is true, pass it back as ?cursor= to fetch the next page; when it is null, you are at the head of the retained window.
GET /api/v1/events/{id} response
A single-event lookup returns the same event envelope under data, un-wrapped from data[]:
Live stream — SSE
data: lines (one JSON object per line). Reconnect on error with the Last-Event-ID header set so you don’t lose events.
A consumer that just opens the stream and dies with it will miss every event emitted between the last delivered event and the reconnect. Track the last id you received and send it back as the Last-Event-ID header (or the ?lastEventId= query parameter, for clients like browser EventSource that can’t set headers) — the server replays the buffered window from that id before switching to the live tail.
?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.
Schema registry — GET /api/v1/events/schema-registry
Before you build a pipeline off the event stream or webhooks, you need to know the shape of each event — and when that shape changes. The schema registry returns the versioned catalog of every event type Orbit emits.
data.schemas carries:
event_type— the wire-level type, e.g.message.delivered.json_schema— the Draft-07 JSON Schema for the event envelope, with thetypeliteral pinned. Use it to validate incoming events or to generate types.example_payload— a realistic example envelope that validates againstjson_schema.fingerprint— asha256:<hex>content fingerprint ofjson_schema, so you can pin one event’s schema and detect drift.
catalog_version (a single sha256:<hex> over every (event_type, fingerprint) pair), an event_count, and the JSON Schema dialect.
catalog_version you last processed. Poll this endpoint on a schedule: while catalog_version is unchanged, nothing in the contract moved and you can skip the work. When it changes, compare each entry’s fingerprint against the one you stored to find exactly which event schemas changed, and regenerate only those types or validators.
A Node generation step that does exactly that:
Event type samples
Every event shares the same envelope —id, type, ts, and a data object whose shape is specific to the event type. The tabs below show the data shape for three common types. For the full catalog of every event type and its JSON Schema, see Webhook events, or fetch the machine-readable schema registry above.
- message.sent / message.delivered
- agent.response
- flow.execution.started
delivered_at with carrier detail in error_code / error_message.Handling 404 on evicted ids
A single-event lookup (GET /api/v1/events/{id}) that returns 404 is not an error
for a consumer pipeline — it means the id aged out of the bounded window described
above. The body looks like this:
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:
See also
- Webhooks — for delivered, durable, retry-handled push of the same events