Skip to content

events

Events is the operational feed flowing out: an append-only log of what Boomin did, ordered by a monotonically increasing seq.

It is the same spine webhooks deliver from, through the same public vocabulary — which makes it the durable recovery path for any delivery you missed.

const page = await boomin.events.list({ type: "distribution.live", limit: 50 });
for await (const event of boomin.events.list({ startingAfter: lastSeenSeq })) {
await handle(event);
}
MethodRouteScope
list(params, options)GET /eventsevents:read
{
"id": "evt_...",
"object": "event",
"type": "distribution.live",
"seq": 48213,
"subject": { "type": "distribution", "id": "" },
"data": { },
"operation": "op_...",
"livemode": true,
"createdAt": "2026-08-02T12:00:00.000Z"
}

The same shape a webhook delivers through constructEvent, so one handler serves both paths. (Raw wire deliveries spell it created_at; both events.list and constructEvent camelCase it for you.)

operation is the operation that caused the event, or null. subject.id is the raw subject id.

ParamValues
typeOne public event type (below). Unlisted types are invalid_event_type (400)
limit1–100, default 20
startingAfterA seq number or an evt_... id

Events page forward by ascending seq — unlike every other list in the API, which pages backward by creation time. That is deliberate: a feed you replay should replay in the order it happened.

// resume exactly where you left off
let cursor = await store.get("boomin_seq");
for await (const event of boomin.events.list({ startingAfter: cursor })) {
await handle(event);
await store.set("boomin_seq", event.seq);
}

The registry is the exposure boundary — types not on this list never leave your organization, and they are not addressable as a type filter or as a webhook enabledEvents entry.

distribution.launching · distribution.live · distribution.paused · distribution.resumed · distribution.completed · distribution.failed · distribution.canceled

deployment.created · deployment.activated · deployment.rejected · deployment.paused · deployment.completed · deployment.drifted · deployment.cancel_requested · deployment.canceled · deployment.cleanup_failed

relationship.created · relationship.activated · relationship.paused · relationship.resumed · relationship.ended

The canonical family (RELATIONSHIP_CORE naming). The legacy relationship.* spellings remain valid subscription entries forever — an endpoint subscribed to relationship.paused receives the canonical relationship.paused event — but new emissions and new subscriptions should use relationship.*.

enrollment.created · enrollment.approved · enrollment.rejected · enrollment.activated · enrollment.qualified · enrollment.disqualified

enrollment.qualified / enrollment.disqualified are standing transitions, emitted exactly once per committed old→new change (entering the grace window emits nothing; falling from grace to not_qualified emits disqualified). The payload carries previous_status and the evaluation trigger. These fire from any cause — metric events, an assertion changing, a capacity or override change — so they are the one subscription that means “this member’s earned access changed”.

assertion.created · assertion.revoked

Tenant-truth claims changing (an expiry-refresh is a new assertion.created). The payload carries the entity and the claim key.

payout.created · payout.settled · payout.failed

operation.succeeded · operation.failed · operation.cancel_requested · operation.canceled · operation.superseded

budget.reserved · budget.released · budget.reserve_failed

Use both, for different jobs:

events.listWebhooks
LatencyYou pollPush, seconds
HistoryEverything since the org existedOnly events appended at or after the endpoint was created
OrderingGuaranteed by seqNot guaranteed — retries reorder
Best forReconciliation, backfill, gap recoveryReacting in real time

The usual production shape is webhooks for reaction plus a periodic events.list sweep from the last seq you durably stored, which closes any delivery that exhausted its retries.