Skip to content

Event types and schemas

An event type names something that happens on your platform, such as booking.created or invoice.paid, and its schema lists the fields every payload of that type can carry. Event types belong to your platform and every workspace shares them. A schema only grows: you can add to it, but not take away, so every template and payload already bound to a type keeps working.

Register an event type with a PUT to its name, sending its whole schema:

Terminal window
curl -X PUT https://api.sendtruss.com/v1/event-types/booking.created \
-H "Authorization: Bearer $SENDTRUSS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"fields": [
{"name": "guest_name", "type": "string", "required": true},
{"name": "arrival", "type": "date", "required": true},
{"name": "site_name", "type": "string", "required": false, "fallback": "your site"},
{"name": "total", "type": "money", "required": false},
{"name": "items", "type": "list", "required": false, "fields": [
{"name": "description", "type": "string", "required": true},
{"name": "price", "type": "money", "required": true}
]}
]
}'

The first PUT creates the type and answers 201. A later one changes its schema and answers 200. Sending the schema it already has changes nothing, so your deploy can register every type each time it runs.

A name is lowercase letters, digits and _, in dot-separated parts that each start with a letter, up to 100 characters. A type is never renamed or deleted.

Each field has a name, a type, and required as a JSON true or false. A type can have up to 100 fields; send [] for one with none.

Type A payload sends
string text, up to 5,000 characters
number a JSON number
boolean true or false
date "2026-10-12"
datetime "2026-10-12T15:00:00Z", with Z or an offset
money {"amount": "129.50", "currency": "EUR"}, the amount as a string so it stays exact
url an http or https URL, up to 2,048 characters
list up to 100 records, each with the fields its fields names

A field name is lowercase letters, digits and _, starting with a letter. A template reads it as {{ event.<name> }}, so guest_name becomes {{ event.guest_name }}.

A list is for line items. Its fields list the fields of each record, at most 20, and a record can’t hold another list. A template shows a list with its line-items block, one row per record.

fallback is the text a template shows when a payload leaves an optional field out. Without one, the field renders as nothing. Either way the email still goes out: a missing optional field never blocks a send.

Once a template or a payload depends on a field, taking it away would break them. So a change to a schema can only:

  • add an optional field;
  • make a required field optional;
  • change a field’s fallback.

Removing a field, changing its type, making it required, or adding a new required field is refused with schema_change_not_additive, and errors names each field at fault. If you really need one of those changes, register a new type under a new name, such as booking.created_v2.

Every emit’s payload is checked against its type’s schema before anything is recorded or sent. A missing required field, a value of the wrong type, or a field the schema doesn’t declare is refused with validation_failed, and errors names the field by its path: payload.guest_name, or payload.items.2.price for a field inside the third record. A payload can be up to 512 KB.

You can list your event types and get one to see its schema.

An event type has at most one template, which every workspace sends when you emit that type. A type with no template still accepts emits: we record the event and send nothing. See Templates and Emitting events.