Events
The complete catalog, and the payload each event carries.
This is every event type Rovela fires. Registering an endpoint with a name that is not on this list is rejected rather than accepted and quietly never fired, so a typo surfaces at registration instead of at three in the morning.
Envelope
Every event, whatever its type, is delivered in the same envelope:
{
"id": "evt_<uuid>",
"type": "email.delivered",
"created_at": "2026-09-25T09:14:02.481+00:00",
"data": { ... }
}Only data varies by event type. Deduplicate on id: a retry carries the same event id and the same created_at.
The catalog
Email delivery
What happened to a message after it was accepted.
email.sent— Accepted by the SMTP relay. Not yet delivered.email.delivered— The receiving server accepted it for the recipient.email.delivery_delayed— Still being retried. Not an outcome — it may yet deliver or bounce.email.bounced— Permanent failure. The address does not exist or refuses mail.email.failed— Delivery failed for a reason that is not a recipient bounce.email.suppressed— Blocked before sending by the suppression list.email.scheduled— Queued for a future `scheduled_at`.email.received— An inbound message was accepted for a hosted mailbox.
Engagement
What the recipient did. Only fires when tracking is enabled for the sending domain.
email.opened— The tracking pixel was fetched.email.clicked— A rewritten link was followed.email.complained— The recipient marked the message as spam.
Broadcasts
Campaign fan-out.
broadcast.sent— The fan-out finished and every recipient was queued.
Contacts
Changes to your audience.
contact.created— A contact was added.contact.updated— A contact's details changed.contact.deleted— A contact was removed.contact.unsubscribed— A contact opted out. Worth acting on — see the note below.
Suppressions
The list of addresses mail is withheld from.
suppression.added— An address was suppressed, by a bounce or by hand.suppression.removed— An address was un-suppressed.
Domains
Sending-domain lifecycle.
domain.created— A domain was added.domain.updated— Its settings changed.domain.deleted— It was removed. Sending from it is refused afterwards.
Automations
Multi-step flows.
automation.started— A run began for a contact.automation.completed— The run reached the end.automation.failed— The run stopped on an error.
Mailboxes
Hosted mailboxes filling up.
mailbox.quota_alert— Nearly full, full, or cleared again. The distinction is in `severity` (warning|critical) and `status` (opened|escalated|resolved) rather than in separate event names.
Example payloads
Delivery events identify the message and its participants:
{
"id": "evt_2f9c1a...",
"type": "email.delivered",
"created_at": "2026-09-25T09:14:02.481+00:00",
"data": {
"email_id": "9f1c2e40-...",
"from": "hello@mail.example.com",
"to": ["user@example.com"]
}
}Contact events carry the contact rather than a message:
{
"id": "evt_7b3d84...",
"type": "contact.unsubscribed",
"created_at": "2026-09-25T09:20:11.004+00:00",
"data": {
"contact_id": "<uuid>",
"email": "user@example.com"
}
}data as additive. New fields can appear as the product grows, and a handler that rejects an event because it contained something unexpected will lose that event permanently — see the retry rules in Overview. Parse the fields you need and ignore the rest.Which events you actually want
email.bounced,email.complainedandcontact.unsubscribedare the three that should change something on your side. A bounce means stop mailing that address; a complaint means the same, more urgently. Ignoring them is how a domain loses its sending reputation.email.deliveredis the one people subscribe to first, and it is the least actionable — it confirms what usually happens anyway.email.openedandemail.clickedonly fire where tracking is enabled for the sending domain. A domain with tracking switched off produces no engagement events at all, which looks identical to a domain nobody engages with.