Events no Verb emits
Events the payment rail, the clock, the runtime or a state change raises, how each names its Noun, and how a Startup records its own.
Most Events are a Verb completing. A few happen with no caller: money settles, a date passes, work finishes, and each is recorded the same way.
Four sources
| Raised by | When | Example |
|---|---|---|
| The payment rail | What Stripe reports after a call returns | Transaction.settled, Dispute.opened |
| The clock | A date passing with nothing done | Invoice.overdue, Domain.renewalDue |
| The runtime | Work finishing or failing with no one calling | Action.done, Action.failed |
| A state change | A record entering a state worth its own name | Subscription.pastDue |
Each one names the Noun it is about, so data carries that record as the Event left it. Where it marks a state, the record is in that state when the Event arrives. Extra fields, such as the retry attempt on an overdue Invoice, sit beside the record.
Every one of them moves a lifecycle, wakes a Workflow or feeds a computed property. Dispute.opened puts the Customer at risk, and Transaction.failed reopens the Bill it was paying.
One, delivered
Subscription.pastDue fires when a renewal Invoice goes overdue and the Subscription moves to pastDue. It carries the overdue Invoice beside the Subscription:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | required | Subscription.pastDue. |
at | datetime | required | When it happened. |
seq | integer | Its position in the namespace, one more than the Event before; any seq is a cursor into the history. | |
data | json | required | The Thing as the Action left it. |
data.subscription | Subscription | required | The Subscription as the change left it. |
data.subscription.status | string | required | One of active, trialing, pastDue, paused, incomplete, or canceled. |
data.subscription.renewsAt | datetime | When it next renews. | |
data.subscription.quantity | integer | How many units of the Offer’s Price it holds, such as 12 members; 1 by default. | |
data.subscription.trialEndsAt | datetime | When a trial ends and the first paid period starts. | |
data.subscription.termEndsAt | datetime | When a committed term ends; the Renewal and the renewal notice read it. | |
data.invoice | Invoice | required | The overdue renewal Invoice. |
data.previous.status | string | required | The status before this Event: active. |
{
"$id": "https: //api.sb/ routewise.dev/ events/ event_1",
"$type": "Event",
"name": "Subscription.pastDue",
"at": "2026-10-22T12: 00: 00Z",
"data": {
"subscription": {
"$id": "https: //api.sb/ routewise.dev/ subscriptions/ subscription_1",
"$type": "Subscription",
"status": "pastDue",
"renewsAt": "2026-10-22T12: 00: 00Z",
"quantity": 1,
"trialEndsAt": "2026-10-22T12: 00: 00Z",
"termEndsAt": "2026-10-22T12: 00: 00Z"
},
"invoice": {
"$id": "https: //api.sb/ routewise.dev/ invoices/ invoice_1",
"$type": "Invoice",
"total": {
"amount": 25,
"currency": "USD"
},
"due": "2026-10-22"
},
"previous": {
"status": "active"
}
},
"seq": 1
}Your own Events
A Verb a Startup adds emits its own Event, named for it, with no extra work. For what no Verb does, such as a page view or a click, Event.capture records one. It takes calls from a Site, an App or the API:
await $.Event.capture({ name: 'Report.viewed', data: { report: 'renewals-due' } })A captured Event is a record like any other. A Metric counts it, a Trigger wakes a Workflow on it, and webhooks deliver it.