Skip to content

Events

How every Action writes immutable Events to one ordered log, and how Triggers, Watches and webhooks react to them.

An Event is the immutable record that something happened, named Noun.pastTense, such as Order.paid. Every Action writes Events, and Events start every Workflow, Metric and outbound delivery.

One log per namespace

Each Startup has one ordered Event log in db.sb. An Action appends an Event on every status change, from pending to done, failed, canceled or refused. Model calls, inbound webhooks and Visits land in the same log, in the same order.

The log keeps everything forever. No Event expires and none is deleted; a correction is a new Event that supersedes the old one. Current state is therefore always explainable: every field of every Thing traces to the Events that set it.

Names

An Event's name comes from its Verb. The Verb pay on an Order emits Order.paid; staff on a Role emits Role.staffed. Inherited writes emit created, updated and deleted.

VerbEventPayload
publishOffer.publishedThe Offer
payOrder.paidThe Order
answerConversation.answeredThe Conversation
registerDomain.registeredThe Domain

The registry derives every name, so an Event never drifts from the Verb that emits it. The Event reference lists all of them.

Selectors

One grammar matches Events everywhere: a name, an optional where clause, and bindings. Triggers, Meters, Watches and Tasks that close on an Event all use it.

TypeScript
const bigOrders = {
  event: 'Order.paid',
  where: { 'order.total.amount': { gte: 1000 } },
}

A selector reads the Event payload, so order.total.amount is the paid Order's total.

Triggers

A Trigger starts a Workflow on an Event, a schedule, or a Thing entering a state. Triggers are records, so a Startup's whole reactive behavior is a query away.

TypeScript
import { $ } from 'startup-builder'

// The deliver-outcome Workflow starts on this Trigger.
await $.Trigger.create({ event: 'Order.paid' })

Every Trigger firing is itself an Action, with its own Events. A Workflow that fails leaves a failed Action and the Event that caused it, side by side.

Watches and webhooks

A Watch delivers matching Events to an outside URL. Each delivery is signed, retried with backoff, and replayable from any point with replay.

Watch.createMode do
You, to your agent

Add a watch to ShiftNote.

curl -X POST https://api.sb/shiftnote.app/watches \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selector":"Example selector","url":"https://shiftnote.app"}'
import { $ } from 'startup-builder'

const { watch, secret } = await $.Watch.create({ selector: 'Example selector', url: 'https://shiftnote.app' })
npx startup-builder do Watch.create --json '{"selector":"Example selector","url":"https://shiftnote.app"}'
{
  "name": "do",
  "arguments": {
    "code": "return await $.Watch.create({ selector: 'Example selector', url: 'https://shiftnote.app' })"
  }
}

Inbound webhooks enter through one ingress per Startup. The ingress verifies the sender's signature, writes an Event, and hands it to Triggers. A signal from an Integration is therefore handled like an internal one.

TermKindDefinition
ActionNounAn Action is one Verb performed by a Worker on a Thing, recorded with its status and every Event it emits.
EventNounAn Event is the immutable record of something that happened to a Thing, named by its Noun and past-tense Verb.
TriggerNounA Trigger is what starts a Workflow: an Event, a schedule, or a Thing entering a state.
WatchNounA Watch is an outbound subscription that delivers the Events a selector matches to a URL, signed, retried, and replayable.
Watch.pauseVerbPause stops a Watch delivering while its Events keep queuing; the platform pauses a Watch whose deliveries fail for three days.
Watch.replayVerbReplay redelivers a Watch’s Events from a chosen point, signed as they were the first time.
Watch.resumeVerbResume restarts a paused Watch and delivers the Events it held, oldest first.
Watch.rotateVerbRotate issues a new signing secret for a Watch and signs with both secrets until the old one expires.

Next