Docs · The event schema

The event schema.

The schema on this page runs in the first body today. It is copied from the running code, not from a design document, and every type below appears in real events in the first body’s log.

Every meaningful fact about the business is one row in an append-only log. A lead captured, a board generated, a message approved, a payment made: each is one typed event, and every table the business uses is a view computed from the log. If a fact matters and is not an event, that is treated as a bug in the code that should have emitted it. Events are constructed through a single function that validates the payload against the schema for its type before the event is written, so a malformed event cannot enter the log.

01Reference

The envelope.

Every event is wrapped in the same envelope, and the envelope is venture-agnostic: the next body imports it unchanged and contributes its own payload types.

Fig. 1 · The envelope
venture

The slug of the body that emitted the event. The first body emits video.

string

ts

When the event happened.

ISO 8601 datetime

type

The event type. The shape of the payload depends on it, and every type is listed below.

string

actor

Who caused the event.

client | agent | human | system

jobId

Present when the event is attached to a job.

string · optional

payload

The typed payload, validated against the schema for the event’s type.

object

Every event in the log carries these six fields. Only the payload's shape varies, and it varies by type.

02Reference

The event types.

Event types are named arm.noun.verb-past, where the arm is the part of the business that produced the event, so site.lead.captured reads as: the site captured a lead. The groups below are listed in funnel order, from a visitor’s first contact down to operations.

Fig. 2 · Site and funnel events
site.lead.captured

A visitor submitted the intake form. source records how they arrived: organic, outbound, oss-video, referral, or direct.

email · productUrl · audience · goal · lengthTier? · source · name? · briefChars? · uploadCount?

site.lead.confirmed

The lead clicked the confirmation link that was mailed to them.

email

board.generated

The body produced a board of candidate videos, and the event records the size, the cost, and the wall-clock time of the batch.

candidateCount · generationCostUsd · wallClockMin

board.viewed

A lead opened their board. The token identifies which recipient’s board it was.

token · watchedCandidates

candidate.watched

A lead watched one candidate, and the event records how much of it they watched.

candidateId · watchPct

candidate.picked

A lead picked a candidate from the board.

candidateId · notes?

candidate.reaction

A lead gave explicit feedback on one candidate, with an optional stated reason.

candidateId · reaction (up | down) · reason?

board.feedback

Feedback on the board as a whole, including from leads who never picked. The verdict is one of picked, none-fit, wrong-style, wrong-message, price, timing, or other.

verdict · note?

order.paid

A customer paid for an order at one of three tiers.

tier (launch | pro | flagship) · amountUsd

video.first_cut.ready

The first cut of a paid order is ready, with the render cost and the human minutes it took.

renderCostUsd · humanMinutes

revision.requested

The customer asked for a revision. The class records whether the round is included in the tier or is a change order.

round · class (included | change-order)

video.delivered

The finished video was delivered, with the total cost and the total human minutes across the job.

tier · totalCostUsd · totalHumanMinutes

Each row is one event type, its payload fields, and what the event records. A field ending in ? is optional.

The eyes arm is the part of the body that publishes content and watches how it performs.

Fig. 3 · Eyes events
oss.video.published

The body published a video about an open-source library.

library · platform (x | youtube) · url

oss.video.stats

A later reading of that video’s performance, including whether the library’s maintainer engaged.

library · views · likes · maintainerEngaged

content.article.published

The body published an article, filed under a topic cluster.

slug · cluster

content.search.stats

A later reading of an article’s search performance.

slug · impressions · clicks

Published and stats are separate types because publishing happens once and readings recur.

The outbound arm is the part of the body that finds prospects and writes to them. Every outbound artifact carries a unique signed token, so a view can be attributed to the exact recipient who viewed it.

Fig. 4 · Outbound events
outbound.teaser.generated

The body produced a personalized teaser for a prospect, and the event records what it cost.

company · token · costUsd

outbound.send.queued

A draft message was staged in the approval queue.

company · contact

outbound.send.approved

The owner approved the exact text of a staged message. The actor of this event is always human.

company

outbound.sent

The approved message was sent.

company · token

outbound.viewed

The recipient viewed the teaser, and the token attributes the view to them.

company · token · watchPct

outbound.replied

The recipient replied, with the sentiment recorded.

company · sentiment (positive | neutral | negative)

The five types after teaser.generated decompose one message's funnel, so a silence can be located at the exact stage where it happened.
Fig. 5 · Ops events
job.state.changed

A job moved between states.

from · to · reason?

note.recorded

The body wrote a note to itself and logged that it did.

file · summary

alert.raised

Something needs attention, at one of three severities.

severity (info | warn | page) · message

Ops events are about the body itself rather than the funnel. They make the machine's own behavior part of the record.