Skip to main content
Events are defined in a .repost schema file. It describes the shape of each payload, the name of each event, and which SDKs to generate. The generated client, the payloads on the wire, and the event docs your customers read all come from this file, so they stay in sync without any effort on your part. The syntax follows Prisma’s schema language. A complete schema looks like this:
repost/schema.repost
There are four kinds of block. A model describes a payload, a type lists your event names, an event ties a name to a payload, and a generator selects an SDK to emit.

Where a schema line ends up

Consider the line price Float. After generation it appears in three places. In your code, it becomes a typed field. This is the actual generated TypeScript:
generated index.d.ts
Each catalog member became a method, so Book.created is called as webhooks.book.created(...), and the /// comment above the member became the method’s documentation. Passing a string as price is a compile error. On the wire, it becomes a payload field:
Fields serialize in declaration order in every language. The wire name of the event is the lowercased catalog name, a dot, and the member: book.created. In your customers’ hands, it becomes documentation. Deploying the schema publishes book.created to your environment with a JSON Schema of the payload and the doc comment as its description. The portal’s event catalog and your public event docs render that registry directly.

Models

A model is a list of typed fields:

Field types

Modifiers compose. String? is optional, Line[] is a list, and String[]? is an optional list.

Absent is not null

Optional fields have three states, and the SDKs keep them separate. A field that is set serializes its value. A field that is absent is omitted from the payload, unless it declares a @default, in which case the default is filled in. An explicit null serializes as null. Consumers can rely on the difference between a missing field and a null one.

Defaults

@default fills a field in when you don’t provide a value. It accepts literals (@default("fallback"), @default(1), @default(false), @default(USD)), the send time (@default(now())), and generated ids (@default(uuid()), @default(cuid())).

Wire names

Schema names are for your code. @map sets the name used in the payload:
Your code reads order.reference; the payload contains order_reference. Enum members can be renamed the same way: RED @map("scarlet").

Enums

An enum generates a value object and a type (Currency.USD in TypeScript) and serializes as the member name, or the @map value if the member was renamed.

Event types

The type block names your events. Each event block gives one of them a payload:
Events in the same catalog can carry different payloads. A deletion usually only needs an id, so it gets a smaller model. The /// comment on a member is worth writing. It becomes the generated method’s documentation, the event’s description in your environment, and the description shown in the portal catalog and your public event docs. A schema can hold any number of catalogs. type Order, type Invoice, and type ApiKey each become their own branch of the method tree, such as apiKey.rotated.

Generators

A generator block emits one SDK. A schema can carry several, so a monorepo can generate every service’s client from the same file:
Supported languages are typescript, go, python, java, and kotlin. TypeScript writes into node_modules by default. The other languages commit their generated package to the repo and require an output path. Java and Kotlin take a few extra settings for their build plugins, covered in the Java and Kotlin guides.

Validating and formatting

repost schema validate checks the schema without writing anything. repost schema fmt formats it in place. Both exit non-zero on problems, so they work as CI checks. The schema lives in repost/schema.repost, or in a repost/schema/ directory of .repost files once it outgrows a single file; use one layout or the other, not both. Changing the schema is a versioned operation. The next page covers how changes are recorded and deployed.

Continue

Migrations & deploys

Record schema changes as migrations and put them live.

SDKs

What these definitions become in each language.

Event docs

The customer-facing pages generated from your doc comments.