Queued with the change itself
An event is written in the same transaction as the change that caused it. If the change rolls back there is no event; if it commits the event cannot be dropped.
Signed events another system can subscribe to. Three exist today.
Growth-OS can post a signed event to an endpoint when something changes. Three event types are built: an organization profile change, a subscription change, and a completed data export. No growth record emits one, so nothing in our daily work depends on this. When we do want another internal tool to hear about something, the delivery, retry and replay machinery is already here.
Product example
This is the same visual component used by the authenticated app, rendered with deterministic sample data.
A signed delivery that succeeded next to a dead one that can still be replayed.
Inert sample data · no network access
Preview ready
Highlights
An event is written in the same transaction as the change that caused it. If the change rolls back there is no event; if it commits the event cannot be dropped.
A receiver that is down gets up to 8 attempts with growing delays, then the delivery stops cleanly instead of looping.
Every attempt records its status and a short response snippet, and an admin can replay a failed delivery for 30 days.
Without a shared foundation, every team rebuilds these edge cases, differently.
A receiver was down for a deploy and the event was sent inline with the request, so it simply died. No record, no retry, nothing to resend. Queueing the delivery with the change removes that whole category.
Without a signature and a timestamp, a receiver cannot tell a real event from a forged one. Every delivery here is signed with the endpoint secret and carries the timestamp it was signed at.
Someone asks whether an event went out and the only answer is a log search and a guess. With attempt history you see the failed status on attempt three and press replay.
The mechanism end to end, as implemented in the repository.
Events queue with the write
enqueueWebhookEvent runs inside the owning transaction, validates the payload against that event type and version, and inserts a delivery row per matching enabled endpoint.
A worker signs and sends
A background worker decrypts the endpoint secret, signs the body with the timestamp, and posts under a strict timeout.
Every attempt is recorded
Each try is claimed under a row lock before any network call, so it gets a durable attempt number. Only timeouts, conflicts, rate limits and server errors retry.
Dead deliveries wait for a person
After 8 attempts or 30 days a delivery is marked dead with its last error kept, and an admin can replay it through the same worker.
Engineering guarantees
Only event types that are actually built are advertised; draft definitions stay hidden. Delivery history shows status codes and short response snippets, never a signing secret. Today the three built events are all platform events, not growth records.
The boundary above is code, not a claim. These files carry the contract:
src/registries/webhook-events.tssrc/features/developer-platform/delivery.tssrc/features/developer-platform/jobs.tssrc/features/developer-platform/crypto.server.tsThese capabilities share contracts and boundaries with this one.
The docs describe the same contracts this page demonstrates.